Partager via


TN014 : contrôles personnalisés

Cette remarque décrit la prise en charge MFC des contrôles personnalisés et de dessin automatique.Elle décrit également le sous-classement dynamique, et décrit la relation entre les objets et l' HWNDS. de CWnd .

L'exemple d'application CTRLTEST MFC illustre comment utiliser de nombreux contrôles personnalisés.Consultez le code source de l'exemple général CTRLTEST MFC et l'aide en ligne.

Contrôles/menus owner-draw

Les fenêtres fournit la prise en charge des contrôles et des menus owner-draw en utilisant des messages windows.La fenêtre parente de tout contrôle ou menu reçoit ces messages et les appels s'exécute dans la réponse.Vous pouvez substituer ces fonctions pour personnaliser l'apparence visuelle et le comportement de votre contrôle ou menu owner-draw.

MFC prend en charge directement draw avec les fonctions suivantes :

Vous pouvez substituer ces fonctions dans votre classe dérivée d' CWnd pour implémenter un comportement personnalisé de dessin.

Cette approche ne mène pas au code réutilisable.Si vous avez deux contrôles semblables dans deux classes différentes d' CWnd , vous devez implémenter le comportement de contrôle personnalisé dans deux emplacements.L'architecture MFC-prise en charge de contrôle de dessin automatique résout le problème.

Contrôles et menus de dessin automatique

MFC fournit une implémentation par défaut (en CWnd et les classes de CMenu ) pour les messages standard owner-draw.Cette implémentation par défaut décodera les paramètres owner-draw et délèguera les messages owner-draw des contrôles ou du menu.Il s'agit de dessin automatique car le code de dessin est dans la classe du contrôle ou dans le menu, pas dans la fenêtre propriétaire.

En utilisant des contrôles de dessin automatique vous pouvez générer les classes de contrôle réutilisables qui utilisent la sémantique de draw pour afficher le contrôle.Le code pour dessiner le contrôle est dans la classe de contrôle, non son parent.Il s'agit d'une approche orientée objet à la programmation de contrôle personnalisé.Ajoutez la liste suivante des fonctions à vos classes de dessin automatique :

  • Pour les boutons de dessin automatique :

    CButton:DrawItem(LPDRAWITEMSTRUCT);
            // insert code to draw this button
    
  • Pour les menus de dessin automatique :

    CMenu:MeasureItem(LPMEASUREITEMSTRUCT);
            // insert code to measure the size of an item in this menu
    CMenu:DrawItem(LPDRAWITEMSTRUCT);
            // insert code to draw an item in this menu
    
  • Pour les zones de liste de dessin automatique :

    CListBox:MeasureItem(LPMEASUREITEMSTRUCT);
            // insert code to measure the size of an item in this list box
    CListBox:DrawItem(LPDRAWITEMSTRUCT);
            // insert code to draw an item in this list box
    
    CListBox:CompareItem(LPCOMPAREITEMSTRUCT);
            // insert code to compare two items in this list box if LBS_SORT
    CListBox:DeleteItem(LPDELETEITEMSTRUCT);
            // insert code to delete an item from this list box
    
  • Pour les zones de liste déroulante de dessin automatique :

    CComboBox:MeasureItem(LPMEASUREITEMSTRUCT);
            // insert code to measure the size of an item in this combo box
    CComboBox:DrawItem(LPDRAWITEMSTRUCT);
            // insert code to draw an item in this combo box
    
    CComboBox:CompareItem(LPCOMPAREITEMSTRUCT);
            // insert code to compare two items in this combo box if CBS_SORT
    CComboBox:DeleteItem(LPDELETEITEMSTRUCT);
            // insert code to delete an item from this combo box
    

Pour plus d'informations sur draw les structures (DRAWITEMSTRUCT, MEASUREITEMSTRUCT, COMPAREITEMSTRUCT, et DELETEITEMSTRUCT) consultez la documentation MFC pour CWnd::OnDrawItem, CWnd::OnMeasureItem, CWnd::OnCompareItem, et CWnd::OnDeleteItem respectivement.

Utilisation de contrôles et des menus de dessin automatique

Pour les menus de dessin automatique, vous devez substituer les méthodes d' OnMeasureItem et d' OnDrawItem .

Pour les zones de liste et zones de liste déroulante de dessin automatique, vous devez substituer OnMeasureItem et OnDrawItem.Vous devez spécifier le style d' LBS_OWNERDRAWVARIABLE pour les zones de liste ou le style d' CBS_OWNERDRAWVARIABLE pour les zones de liste déroulante dans le modèle de boîte de dialogue.Le style d' OWNERDRAWFIXED ne fonctionnera pas avec des éléments de dessin automatique car la hauteur fixe d'élément est déterminée avant que les contrôles de dessin automatique à joindre à la zone de liste.(Vous pouvez utiliser les méthodes CListBox::SetItemHeight et CComboBox::SetItemHeight pour contourner cette limitation.)

Basculer vers un style d' OWNERDRAWVARIABLE oblige le système pour appliquer le style d' NOINTEGRALHEIGHT au contrôle.Étant donné que le contrôle ne peut pas calculer une hauteur intégrale avec les éléments de taille variables, le style par défaut d' INTEGRALHEIGHT est ignoré et le contrôle est toujours NOINTEGRALHEIGHT.Si vos éléments sont à altitude fixe, vous pouvez empêcher les éléments partiels doit être dessiné en spécifiant la taille du contrôle soit un multiplicateur entier de la taille d'élément.

Pour les zones de liste et zones de liste déroulante de dessin automatique avec le style d' LBS_SORT ou d' CBS_SORT , vous devez substituer la méthode d' OnCompareItem .

Pour les zones de liste et zones de liste déroulante de dessin automatique, OnDeleteItem n'est généralement pas substituée.Vous pouvez substituer OnDeleteItem si vous souhaitez exécuter un traitement spécial.Un cas où ce s'appliquerait est lorsque la mémoire ou d'autres ressources sont stockées avec chaque élément de zone de liste ou de zone de liste déroulante.

Exemples de contrôles et des menus de dessin automatique

L'exemple général CTRLTEST MFC fournit des exemples d'un menu de dessin automatique et une zone de liste de dessin automatique.

L'exemple le plus courant d'un bouton de dessin automatique est un bouton bitmap.Un bouton bitmap est un bouton qui présente une, deux, ou trois images bitmap pour les différents états.Un exemple de ce est fourni dans la classe MFC CBitmapButton.

Sous-classement dynamique

Parfois souhaiter modifier les fonctionnalités d'un objet existant.Les exemples précédents vous requis pour personnaliser les contrôles avant qu'ils ont été créés.Le sous-classement dynamique vous permet de personnaliser un contrôle qui a été créé.

Le sous-classement est le terme windows pour remplacer WndProc d'une fenêtre avec WndProc personnalisé et appeler WndProc ancien pour la fonctionnalité par défaut.

Cela ne doit pas être confondue avec la dérivation de classe C++.Pour la ajout, la classe de base des termes C++ et la classe dérivée sont analogues à la surclassement et à la sous-classe dans le modèle objet de windows.La dérivation C++ avec MFC et le sous-classement de fenêtres sont fonctionnellement semblables, à moins que C++ ne prend pas en charge le sous-classement dynamique.

La classe d' CWnd fournit la connexion entre un objet C++ (dérivé d' CWnd) et un objet window windows (appelé HWND).

Il existe trois façons courantes que ceux-ci sont liés :

  • CWnd crée HWND.Vous pouvez modifier le comportement d'une classe dérivée en créant une classe dérivée d' CWnd.HWND est créé lorsque votre application appelle CWnd::Create.

  • L'application attache CWnd à HWNDexistant.Le comportement de la fenêtre existante n'est pas modifié.Il s'agit d'un cas de délégation et est rendu possible en appelant CWnd::Attach à l'alias HWND existant à un objet d' CWnd .

  • CWnd est attaché à HWND existant et vous pouvez modifier le comportement dans une classe dérivée.Cela est appelé sous-classement dynamique car nous modifions le comportement, et par conséquent la classe, d'un objet de fenêtres au moment de l'exécution.

Vous pouvez obtenir le sous-classement dynamique à l'aide de les méthodes CWnd::SubclassWindow etCWnd::SubclassDlgItem.

Les deux routines attachent un objet d' CWnd à HWNDexistant.SubclassWindow prend HWND directement.SubclassDlgItem est une fonction d'assistance qui prend un ID du contrôle et la fenêtre parente.SubclassDlgItem est conçu pour joindre des objets C++ aux contrôles de boîte de dialogue créé à partir d'un modèle de boîte de dialogue.

Consultez l'exemple de CTRLTEST pour plusieurs exemples de le moment où utiliser SubclassWindow et SubclassDlgItem.

Voir aussi

Autres ressources

Notes techniques de nombres

Notes techniques de catégorie