CTRLTEST, exemple : implémente les contrôles personnalisés
Mise à jour : novembre 2007
L'exemple CTRLTEST illustre plusieurs techniques d'implémentation et d'utilisation des contrôles personnalisés :
Implémentation de CParsedEdit, un contrôle d'édition spécialisé qui dérive sa fonctionnalité de sa classe du contrôle de bibliothèque, et de trois méthodes d'utilisation des contrôles personnalisés.
Utilisation du contrôle Spin. Le contrôle Spin possède un petit bouton en forme de flèche vers le haut et un autre en forme de flèche vers le bas pour incrémenter ou décrémenter une valeur.
Implémentation sous forme de bouton bitmap des commandes du menu Custom à l'aide de CBitmapButton.
Menus et zones de liste owner-drawn (fenêtre parente). Les classes correspondantes du contrôle, qui sont dérivées de la classe CMenu et de CListBox offrent cette fonctionnalité selon une approche orientée objet.
Utilisation de fichiers de ressources non gérables par les Éditeurs de ressources Microsoft Visual C++. Cela illustre les avantages et les inconvénients de l'utilisation d'un fichier .rc2 dans une boîte de dialogue possédant un contrôle personnalisé dont les styles sont définis par des constantes dans un fichier d'en-tête.
Les exemples d'utilisation de CTRLTEST sont tous exécutés via les commandes de menu.
Note de sécurité : |
---|
Cet exemple de code est fourni pour illustrer un concept et ne doit pas être utilisé dans des applications ou des sites Web, car il peut ne pas illustrer les pratiques de programmation les plus sûres. Microsoft n'assume aucune responsabilité pour tout dommage indirect ou consécutif en cas d'utilisation de l'exemple de code à des fins autres que celles prévues. |
Pour obtenir des exemples et des instructions d'installation :
Dans le menu ? (Aide) de Visual Studio, cliquez sur Exemples.
Pour plus d'informations, consultez Recherche des fichiers d'exemple.
La liste la plus récente et la plus complète d'exemples est disponible en ligne à partir de la page Visual Studio 2008 Samples.
Des exemples sont également disponibles sur le disque dur de votre ordinateur. Des exemples et un fichier Readme sont stockés par défaut dans un dossier sous \Program Files\Visual Studio 9.0\Samples\. Pour les éditions Express de Visual Studio, tous les exemples sont disponibles en ligne.
Génération et exécution de l'exemple
Pour générer et exécuter l'exemple CTRLTEST
Ouvrez la solution Ctrltest.sln.
Dans le menu Générer, cliquez sur Générer.
Dans le menu Déboguer, cliquez sur Exécuter sans débogage.
Exemple : implémentation et utilisation des contrôles personnalisés
Vous pouvez implémenter un contrôle personnalisé en le faisant dériver de CWnd, mais il est beaucoup plus simple d'exploiter la fonctionnalité d'un contrôle Windows standard en le faisant dériver à partir de sa classe de contrôle dans la bibliothèque. Pour ce faire, CTRLTEST implémente un contrôle d'édition spécialisé, CParsedEdit. Celui-ci n'accepte les entrées d'utilisateur que sous forme de jeux de caractères spécifiques : numériques, alphabétiques ou hors contrôle. CParsedEdit est dérivé de CEdit. Il possède un gestionnaire de messages OnChar pour filtrer les caractères.
L'implémentation des commandes dans le menu Simple illustre trois méthodes d'utilisation d'un contrôle personnalisé. Ces méthodes se distinguent selon la manière dont l'application associe les instances du contrôle de la boîte de dialogue à la classe CParsedEdit. Chaque commande du menu Simple affiche une boîte de dialogue comportant quatre instances du contrôle CParsedEdit. Les données entrées dans la boîte de dialogue sont envoyées au port de débogage sous la forme d'une sortie TRACE. Les trois commandes du menu Simple sont les suivantes :
Test C++ Derived Class
Les contrôles CParsedEdit sont des données membres de la classe de boîte de dialogue. Ces contrôles sont créés explicitement dans la fonction OnInitDialog de la boîte de dialogue grâce à l'appel de CParsedEdit::CreateSet. Consultez Dertest.cpp.
Test WNDCLASS Registered
Les contrôles CParsedEdit sont affichés dans une ressource de modèle de boîte de dialogue (IDD_WNDCLASS_EDIT) sous forme de contrôles personnalisés accompagnés de WNDCLASS identifié en tant que "paredit". Il est intéressant d'examiner les propriétés de ces contrôles personnalisés à l'aide de l'Éditeur de boîtes de dialogue Visual C++.
Pas de légende. Il s'agit de la valeur initiale affichée dans le contrôle CParsedEdit.
Class:paredit. Il s'agit du nom WNDCLASS inscrit par CParsedEdit::RegisterControlClass dans PAREDIT2.CPP, avant que la boîte de dialogue ne soit appelée.
Visible:checked. Le contrôle est visible.
Tabstop:checked. L'utilisateur peut utiliser les touches de tabulation pour accéder au contrôle.
Style:0x5081002, 0x5081001, 0x5081003, 0x5081ffff pour les quatre contrôles d'édition analysés. Le style 0x500000 est destiné à WS_CHILD et WS_VISIBLE, tandis que 0x1000 est réservé à WS_TABSTOP. Tous les contrôles personnalisés possèdent le style WS_CHILD. Les styles WS_VISIBLE et WS_TABSTOP sont automatiquement définis par l'Éditeur de boîtes de dialogue lorsque vous activez les styles Visible et Tabstop. 0x80000 est réservé à WS_BORDER. La page de propriétés de l'Éditeur de boîtes de dialogue d'un contrôle personnalisé offre tous les styles de fenêtres tels que WS_BORDER ; par conséquent, vous devez rechercher la constante dans \Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Include\WINUSER.H. Les styles 0x0001, 0x0002, 0x0004 et 0x0ffff sont définis dans PAREDIT.H comme, respectivement, PES_NUMBERS, PES_LETTERS, PER_OTHERCHARS et PES_ALL.
Les styles hexadécimaux de la page de propriétés du contrôle personnalisé ne sont pas explicites. Si vous accordez de l'importance à l'utilisation des styles symboliques, tels que PES_NUMBERS et PES_LETTERS, vous avez également la possibilité d'éditer manuellement un fichier de ressources distinct, par exemple RES\Ctrltest.rc2, qui est inclus par le compilateur de ressources au moment de la compilation, mais n'est pas lu par Visual C++ au moment de l'édition. Pour connaître les avantages et les inconvénients de l'édition manuelle d'une boîte de dialogue possédant un contrôle personnalisé dans un fichier .rc2, consultez Exemple : utilisation de fichiers de ressources non gérables par les Éditeurs de ressources Visual C++.
Test Dynamic Subclassed
Les contrôles sont affichés dans une ressource de modèle de boîte de dialogue (IDD_SUB_EDIT in Ctrltest.rc) en tant que contrôles d'édition standard. Ils sont déclarés en tant que données membres CParsedEdit dans la classe de boîte de dialogue. La fonction OnInitDialog de la boîte de dialogue appelle CParsedEdit::SubClassEdit, qui à son tour appelle CWnd::SubclassDlgItem, pour associer chaque instance spécifique du contrôle d'édition à la classe CParsedEdit. Consultez Paredit.cpp.
Exemple : contrôle Spin
L'exemple CTRLTEST inclut une implémentation d'un contrôle Spin. Le contrôle Spin possède un petit bouton en forme de flèche vers le haut et un autre en forme de flèche vers le bas pour incrémenter ou décrémenter une valeur.
La commande Spin Control appelle une boîte de dialogue qui possède quatre contrôles CParsedEdit, chacun étant associé à un contrôle Spin. Les données entrées dans les contrôles CParsedEdit de cette boîte de dialogue sont filtrées pour accepter uniquement les entiers non négatifs. L'utilisateur peut entrer des données numériques en tapant la valeur dans le contrôle CParsedEdit ou en utilisant le contrôle Spin associé.
Exemple : bouton Bitmap
L'implémentation des commandes du menu Custom illustre les méthodes d'utilisation de CBitmapButton:
Bitmap Button 1 - Le constructeur de boîte de dialogue charge explicitement les ressources bitmap correspondant aux trois états (levé, enfoncé et avec focus) du bouton en appelant CBitmapButton::LoadBitmaps.
Bitmap Button 2 - La fonction OnInitDialog de la boîte de dialogue appelle CBitmapButton::Autoload pour charger les ressources bitmap d'après la convention d'affectation de noms suivante. Le texte de la fenêtre du contrôle sert de nom de ressource de base, alors que les lettres U, D et F sont ajoutées pour créer les noms des ressources de chacune des trois images bitmap associées respectivement aux états levé, enfoncé et avec focus. Par exemple, les trois ressources bitmap associées au bouton OK se nomment OKU, OKD et OKF.
Bitmap Button 3 - La boîte de dialogue est une extension de la seconde boîte de dialogue ci-dessus, qui utilise un quatrième état de bouton possible, désactivé. Pour pouvoir utiliser cette boîte de dialogue, cliquez sur le bouton bitmap représentant une flèche vers la gauche ou sur celui qui représente une flèche vers la droite, jusqu'à ce que le nombre affiché atteigne 1, le nombre le plus petit ou 10, le nombre le plus élevé. Une fois la limite atteinte, le bouton est désactivé et une quatrième image bitmap s'affiche. La convention d'affectation de noms applicable à la ressource bitmap de l'état désactivé préconise l'utilisation du suffixe X, comme l'illustrent les noms de ressources PREVX et NEXTX.
Exemple : dessin owner-drawn (menu et zone de liste)
Plusieurs contrôles et menus Windows possèdent une fonctionnalité owner-draw qui permet à la fenêtre parente (ou propriétaire) de dessiner sans limite dans la zone cliente du contrôle au lieu d'utiliser son comportement standard. Les classes correspondantes du contrôle et la classe CMenu fournissent cette fonctionnalité selon une approche plus simple, orientée objet : la classe du contrôle ou du menu gère le dessin. Cela s'appelle le « dessin automatique ».
CTRLTEST illustre la technique générale du dessin owner-drawn par l'implémentation des commandes suivantes dans le menu **Custom **:
Custom Menu -Cet élément de menu appelle un menu contextuel CColorMenu, dérivé de CMenu. Chaque élément du sous-menu affiche l'une des huit couleurs disponibles à l'aide de la fonctionnalité de dessin automatique. Un message confirme la couleur que vous avez sélectionnée dans le sous-menu.
Custom ListBox - Cet élément de menu appelle une boîte de dialogue qui affiche CColorListBox, dérivé de CListBox. La zone de liste possède huit entrées, chacune étant dessinée dans l'une des huit couleurs disponibles à l'aide de la fonctionnalité de dessin automatique. La sortie TRACE confirme votre sélection dans la zone de liste.
Exemple : utilisation de fichiers de ressources non gérables par les Éditeurs de ressources Visual C++
Le fichier de ressources CTRLTEST\RES\Ctrltest.rc2 est un exemple de fichier de ressources non gérable par les Éditeurs de ressources Visual C++ sous une forme explicite. Si vous étiez amené à ouvrir Ctrltest.rc2 dans Visual C++ et à l'enregistrer, vous perdriez des informations explicites utiles, même si le compilateur de ressources est toujours capable de compiler le fichier .rc2 pour produire un fichier .res binaire équivalent. Par conséquent, RES\Ctrltest.rc2 a été ajouté en tant que #include dans Ctrltest.rc avec une directive de compilation spécifiée à l'aide de la commande Resource File Set Includes.
Les éléments suivants représentent trois catégories d'informations explicites qui ne sont pas gérables par les Éditeurs de ressources Visual C++. Deux de ces catégories sont illustrées dans Ctrltest.rc2 :
Symboles de styles de contrôles personnalisés - Par exemple, "msctls_updown32" est un style défini pour le contrôle Spin. Bien que Visual C++ puisse interpréter ce symbole lorsqu'il lit le contenu du fichier .rc2, Visual C++ le réécrirait dans le fichier .rc2 sous forme hexadécimale.
Symboles Windows WS_ standard ou symboles de styles de contrôles utilisés dans un contrôle à partir d'une classe dérivée d'un contrôle Windows standard - Par exemple, ES_AUTOHSCROLL est défini pour le contrôle Spin dans la boîte de dialogue IDD_SPIN_EDIT. Bien que Visual C++ puisse interpréter ces symboles lorsqu'il lit le contenu du fichier .rc2, Visual C++ le réécrirait dans les fichiers .rc2 sous forme hexadécimale.
Arithmétique dans le fichier .rc - Les expressions telles que "IDC_EDIT1+2", qui permettent d'identifier les contrôles de la boîte de dialogue IDD_SPIN_EDIT, seraient également réécrites dans le fichier .rc2 sous forme de valeur hexadécimale unique par Visual C++.
L'exemple CTRLTEST illustre les avantages et les inconvénients de l'utilisation d'un fichier .rc2 dans une boîte de dialogue possédant un contrôle personnalisé dont les styles sont définis par des constantes dans un fichier d'en-tête. Les deux boîtes de dialogue IDD_WNDCLASS_EDIT et IDD_SPIN_EDIT possèdent des contrôles personnalisés avec des styles définis symboliquement ; cependant, IDD_WNDCLASS est spécifié dans un fichier .rc pouvant être modifié à l'aide de l'Éditeur de boîtes de dialogue Visual C++, alors que IDD_SPIN_EDIT est spécifié dans un fichier .rc2 qui ne peut être modifié que manuellement.
Les différences d'utilisation entre le fichier .rc et le fichier .rc2 peuvent se résumer de la façon suivante.
Pour la boîte de dialogue IDD_WNDCLASS_EDIT, le script de ressources est défini dans Ctrltest.rc. Pour la boîte de dialogue IDD_SPIN_EDIT, le script de ressources est défini dans RES\Ctrltest.rc2. Dans le cas de la boîte de dialogue IDD_WNDCLASS_EDIT, le contrôle personnalisé WNDCLASS est "paredit", les constantes de styles sont définies dans PAREDIT.H, et PES_NUMBER est un exemple de constante de style. IDD_WNDCLASS_EDIT est modifiable par Visual C++ mais ne peut pas utiliser de styles #define. IDD_SPIN_EDIT n'est pas modifiable par Visual C++ mais peut utiliser des styles #define.
Le compromis est le suivant : si vous utilisez le fichier .rc2, vous pouvez exploiter les styles symboliques explicites définis dans le fichier d'en-tête du contrôle personnalisé, mais vous ne pouvez pas modifier le fichier .rc2 à l'aide de l'Éditeur de boîtes de dialogue Visual C++. Il est plus facile de créer la boîte de dialogue à l'aide de Visual C++ que d'écrire manuellement le script de ressources ; en outre, l'écriture de scripts de ressources est davantage susceptible d'entraîner des erreurs. D'un autre côté, les styles ne sont pas explicites lorsqu'ils sont affichés au format hexadécimal dans la page de propriétés du contrôle personnalisé par l'Éditeur de boîtes de dialogue Visual C++.
Mots clés
Cet exemple illustre l'utilisation des mots clés suivants :
AfxGetInstanceHandle ; AfxMessageBox ; AfxThrowResourceException ; CBitmapButton::AutoLoad ; CDC::FillRect ; CDC::FrameRect ; CDialog::DoModal ; CDialog::EndDialog ; CDialog::OnInitDialog ; CDialog::OnOK ; CDialog::OnSetFont ; CEdit::Create ; CEdit::SetSel ; CFrameWnd::Create ; CListBox::AddString ; CListBox::CompareItem ; CListBox::DrawItem ; CListBox::GetItemData ; CListBox::MeasureItem ; CMenu::AppendMenu ; CMenu::CreateMenu ; CMenu::Detach ; CMenu::DrawItem ; CMenu::EnableMenuItem ; CMenu::FromHandle ; CMenu::GetMenuString ; CMenu::MeasureItem ; CRect::Width ; CStatic::Create ; CString::Format ; CString::LoadString ; CWinApp::InitInstance ; CWnd::Attach ; CWnd::EnableWindow ; CWnd::FromHandle ; CWnd::GetDlgCtrlID ; CWnd::GetDlgItem ; CWnd::GetDlgItemInt ; CWnd::GetMenu ; CWnd::GetParent ; CWnd::GetWindowRect ; CWnd::GetWindowText ; CWnd::IsWindowEnabled ; CWnd::MessageBox ; CWnd::OnChar ; CWnd::OnCommand ; CWnd::OnVScroll ; CWnd::PostNcDestroy ; CWnd::SendMessage ; CWnd::SetDlgItemInt ; CWnd::SetFocus ; CWnd::SetFont ; CWnd::SetWindowPos ; CWnd::ShowWindow ; CWnd::SubclassDlgItem ; CallWindowProc ; GetBValue ; GetClassInfo ; GetGValue ; GetRValue ; GetSystemMetrics ; HIWORD ; IsCharAlpha ; IsCharAlphaNumeric ; LOWORD ; MAKEINTRESOURCE ; MAKELONG ; MessageBeep ; ModifyMenu ; RGB ; RegisterClass ; SetWindowLong
Remarque : |
---|
Certains exemples, tels que celui-ci, n'ont pas été modifiés pour refléter les changements apportés aux Assistants, aux bibliothèques et au compilateur Visual C++, mais ils illustrent bien l'exécution de la tâche souhaitée. |