Contrôles personnalisés

Cette section contient des informations sur les contrôles personnalisés ou définis par l’application.

Les rubriques suivantes sont présentées.

Création de contrôles Owner-Drawn

Les boutons, les menus, les contrôles de texte statiques, les zones de liste et les zones de liste modifiable peuvent être créés avec un indicateur de style owner-drawn. Lorsqu’un contrôle a le style owner-drawn, le système gère l’interaction de l’utilisateur avec le contrôle comme d’habitude, en effectuant des tâches telles que la détection lorsqu’un utilisateur a choisi un bouton et avertit le propriétaire de l’événement du bouton. Toutefois, étant donné que le contrôle est owner-drawn, la fenêtre parente du contrôle est responsable de l’apparence visuelle du contrôle. La fenêtre parente reçoit un message chaque fois que le contrôle doit être dessiné.

Pour les boutons et les contrôles de texte statique, le style owner-drawn affecte la façon dont le système dessine l’ensemble du contrôle. Pour les zones de liste et les zones de liste modifiable, la fenêtre parente dessine les éléments dans le contrôle et le contrôle dessine son propre plan. Par exemple, une application peut personnaliser une zone de liste pour qu’elle affiche une petite bitmap en regard de chaque élément de la liste.

L’exemple de code suivant montre comment créer un contrôle de texte statique owner-drawn. Supposons que Unicode est défini.

// g_myStatic is a global HWND variable.
g_myStatic = CreateWindowEx(0, L"STATIC", L"Some static text", 
            WS_CHILD | WS_VISIBLE | SS_OWNERDRAW, 
            25, 125, 150, 20, hDlg, 0, 0, 0);

Dans l’exemple suivant, dans la procédure de fenêtre pour la boîte de dialogue qui contient le contrôle créé dans l’exemple précédent, le message WM _ DRAWITEM est géré en affichant le texte dans une couleur personnalisée, à l’aide de la police par défaut. Notez que vous n’avez pas besoin d’appeler BeginPaint et EndPaint lors du traitement de WM _ DRAWITEM.

case WM_DRAWITEM:
{
    LPDRAWITEMSTRUCT pDIS = (LPDRAWITEMSTRUCT)lParam;
    if (pDIS->hwndItem == g_myStatic)
    {
        SetTextColor(pDIS->hDC, RGB(100, 0, 100));
        WCHAR staticText[99];
        int len = SendMessage(myStatic, WM_GETTEXT, 
            ARRAYSIZE(staticText), (LPARAM)staticText);
        TextOut(pDIS->hDC, pDIS->rcItem.left, pDIS->rcItem.top, staticText, len);
    }
    return TRUE;
}

Pour plus d’informations sur les contrôles owner-drawn, consultez création d’une zone de liste owner-drawn et de zones de liste déroulante owner drawn.

Sous-classement de la classe de fenêtre d’un contrôle existant

Le sous-classement d’un contrôle existant est une autre façon de créer un contrôle personnalisé. La procédure de sous-classe peut modifier les comportements sélectionnés du contrôle en traitant les messages qui affectent les comportements sélectionnés. Tous les autres messages passent à la procédure de fenêtre d’origine pour le contrôle. Par exemple, une application peut afficher une petite bitmap en regard du texte d’un contrôle d’édition en lecture seule sur une seule ligne en sous-classant le contrôle et en traitant le message de _ peinture WM . Pour plus d’informations, consultez à propos des procédures de fenêtre et des contrôles de sous- classe.

Implémentation d’une classe de fenêtre Application-Defined

Pour créer un contrôle qui n’est pas explicitement basé sur un contrôle existant, l’application doit créer et inscrire une classe de fenêtre. Le processus d’inscription d’une classe de fenêtre définie par l’application pour un contrôle personnalisé est identique à l’inscription d’une classe pour une fenêtre ordinaire. Pour créer un contrôle personnalisé, spécifiez le nom de la classe de fenêtre dans la fonction CreateWindowEx ou dans un modèle de boîte de dialogue. Chaque classe doit avoir un nom unique, une procédure de fenêtre correspondante et d’autres informations.

Au minimum, la procédure de fenêtre dessine le contrôle. Si une application utilise le contrôle pour permettre à l’utilisateur de taper des informations, la procédure de fenêtre traite également les messages d’entrée à partir du clavier et de la souris et envoie des messages de notification à la fenêtre parente. En outre, si le contrôle prend en charge les messages de contrôle, la procédure de fenêtre traite les messages qui lui sont envoyés par la fenêtre parente ou d’autres fenêtres. Par exemple, les contrôles traitent souvent le message WM _ GETDLGCODE envoyé par les boîtes de dialogue pour indiquer à une boîte de dialogue de traiter l’entrée au clavier d’une manière donnée.

La procédure de fenêtre pour un contrôle défini par l’application doit traiter n’importe quel message de contrôle prédéfini dans le tableau suivant si le message affecte le fonctionnement du contrôle.

Message Recommandation
_GETDLGCODE WM Processus si le contrôle utilise les touches entrée, ÉCHAP, TAB ou flèche. La fonction IsDialogMessage envoie ce message aux contrôles dans une boîte de dialogue pour déterminer s’il faut traiter les clés ou les passer au contrôle.
WM _ GETFONT Processus si le message WM _ SetFont est également traité.
WM _ GETTEXT Processus si le texte du contrôle n’est pas le même que le titre spécifié par la fonction CreateWindowEx .
_GETTEXTLENGTH WM Processus si le texte du contrôle n’est pas le même que le titre spécifié par la fonction CreateWindowEx .
_KILLFOCUS WM Processus si le contrôle affiche un signe insertion, un rectangle de focus ou un autre élément pour indiquer qu’il a le focus d’entrée.
WM _ SetFocus Processus si le contrôle affiche un signe insertion, un rectangle de focus ou un autre élément pour indiquer qu’il a le focus d’entrée.
WM, _ SETTEXT Processus si le texte du contrôle n’est pas le même que le titre spécifié par la fonction CreateWindowEx .
_SetFont WM Processus si le contrôle affiche du texte. Le système envoie ce message lors de la création d’une boîte de dialogue avec le _ style DS setfont.

Les messages de contrôle définis par l’application sont spécifiques au contrôle donné et doivent être envoyés explicitement au contrôle à l’aide d’une fonction SendMessage ou SendDlgItemMessage . La valeur numérique de chaque message doit être unique et ne doit pas être en conflit avec les valeurs d’autres messages de fenêtre. Pour s’assurer que les valeurs des messages définis par l’application ne sont pas en conflit, une application doit créer chaque valeur en ajoutant un numéro unique à la valeur de l' _ utilisateur WM .

Envoi de notifications à partir d’un contrôle

Des contrôles personnalisés peuvent être nécessaires pour envoyer des notifications d’événements à la fenêtre parente afin que l’application hôte puisse répondre à ces événements. Par exemple, un affichage de liste personnalisé peut envoyer une notification lorsque l’utilisateur sélectionne un élément et une autre notification lors d’un double-clic sur un élément.

Les notifications sont envoyées en tant que _ commandes WM ou messages de _ notification WM . WM _ Les messages de notification contiennent plus d’informations que les messages de _ commande WM .

L’identificateur de contrôle est un nombre unique que l’application utilise pour identifier le contrôle qui envoie le message. L’application définit l’identificateur d’un contrôle lorsqu’il crée le contrôle. L’application spécifie l’identificateur dans le paramètre HMENU de la fonction CreateWindowEx ou dans le membre ID de la structure DLGITEMTEMPLATEEX .

Étant donné que le contrôle lui-même ne définit pas l’identificateur de contrôle, le contrôle doit récupérer l’identificateur avant de pouvoir envoyer des messages de notification. Un contrôle doit utiliser la fonction GetDlgCtrlID pour récupérer son propre identificateur de contrôle. Bien que l’identificateur de contrôle soit spécifié comme handle de menu lorsque le contrôle est créé, la fonction GetMenu ne peut pas être utilisée pour récupérer l’identificateur. Un contrôle peut également récupérer l’identificateur du membre HMENU dans la structure CREATESTRUCT lors du traitement du message WM _ Create .

Les exemples suivants, où hwndControl est le descripteur de la fenêtre de contrôle et que la définition de la _ notification CN est une définition de notification personnalisée, illustrent les deux façons d’envoyer une notification spécifique au contrôle.

 // Send as WM_COMMAND.
SendMessage(GetParent(hwndControl), 
    WM_COMMAND,
    MAKEWPARAM(GetDlgCtrlID(hwndControl), CN_VALUECHANGED),
    (LPARAM)hwndControl);

// Send as WM_NOTIFY.           
NMHDR nmh;
nmh.code = CN_VALUECHANGED;
nmh.idFrom = GetDlgCtrlID(hwndControl);
nmh.hwndFrom = hwndControl;
SendMessage(GetParent(hwndControl), 
    WM_NOTIFY, 
    (WPARAM)hwndControl, 
    (LPARAM)&nmh);

Notez que la structure NMHDR peut faire partie d’une plus grande structure définie par le contrôle qui contient des informations supplémentaires. Dans l’exemple, les valeurs anciennes et nouvelles du contrôle peuvent être contenues dans cette structure. (Ces structures étendues sont utilisées avec de nombreuses notifications standard ; par exemple, consultez LVN _ INSERTITEM, qui utilise la structure NMLISTVIEW .)

Accessibilité

Tous les contrôles communs prennent en charge Microsoft Active Accessibility (MSAA), qui permet l’accès par programme aux applications de technologie accessibles telles que les lecteurs d’écran. MSAA permet également l’automatisation d’interface utilisateur, une technologie plus récente, pour interagir avec les contrôles.

Les contrôles personnalisés doivent implémenter l’interface IAccessible (pour prendre en charge MSAA) ou les interfaces UI Automation, ou les deux. Dans le cas contraire, les produits de technologie accessible ne pourront obtenir que des informations très limitées sur la fenêtre de contrôle, n’auront pas accès aux propriétés du contrôle et ne pourront pas déclencher d’événements dans le contrôle.

pour plus d’informations sur la mise à disposition de votre contrôle, consultez Windows API Automation.

Conceptuel

Référence de contrôle générale

Personnalisation de l’apparence d’un contrôle à l’aide d’un dessin personnalisé

Messages de contrôle

Utilisation de styles visuels avec des contrôles Owner-Drawn