Partager via


Contrôles ActiveX MFC : sous-classe d’un contrôle Windows

Cet article décrit le processus de sous-classe d’un contrôle Windows commun pour créer un contrôle ActiveX. La sous-classe d’un contrôle Windows existant est un moyen rapide de développer un contrôle ActiveX. Le nouveau contrôle aura les capacités du contrôle Windows sous-classé, comme la peinture et la réponse aux clics de souris. L’exemple DE BOUTON des contrôles ActiveX MFC est un exemple de sous-classe d’un contrôle Windows.

Importante

ActiveX est une technologie héritée qui ne doit pas être utilisée pour le nouveau développement. Pour plus d’informations sur les technologies modernes qui remplacent ActiveX, consultez Contrôles ActiveX.

Pour sous-classer un contrôle Windows, effectuez les tâches suivantes :

Remplacement de IsSubclassedControl et PreCreateWindow

Pour remplacer PreCreateWindow et IsSubclassedControlajouter les lignes de code suivantes à la protected section de la déclaration de classe de contrôle :

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
BOOL IsSubclassedControl();

Dans le fichier d’implémentation de contrôle (. CPP), ajoutez les lignes de code suivantes pour implémenter les deux fonctions substituées :

// CMyAxSubCtrl::PreCreateWindow - Modify parameters for CreateWindowEx

BOOL CMyAxSubCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
   cs.lpszClass = _T("BUTTON");
   return COleControl::PreCreateWindow(cs);
}

// CMyAxSubCtrl::IsSubclassedControl - This is a subclassed control

BOOL CMyAxSubCtrl::IsSubclassedControl()
{
   return TRUE;
}

Notez que, dans cet exemple, le contrôle de bouton Windows est spécifié dans PreCreateWindow. Toutefois, tous les contrôles Windows standard peuvent être sous-classés. Pour plus d’informations sur les contrôles Windows standard, consultez Contrôles.

Lors de la sous-classe d’un contrôle Windows, vous pouvez spécifier des indicateurs de style de fenêtre (WS_) ou de style de fenêtre étendu (WS_EX_) à utiliser pour créer la fenêtre du contrôle. Vous pouvez définir des valeurs pour ces paramètres dans la fonction membre PreCreateWindow en modifiant les champs de structure cs.style et cs.dwExStyle. Les modifications apportées à ces champs doivent être effectuées à l’aide d’une opération OR pour conserver les indicateurs par défaut définis par classe COleControl. Par exemple, si le contrôle est sous-classe du contrôle BUTTON et que vous souhaitez que le contrôle apparaisse sous forme de case à cocher, insérez la ligne de code suivante dans l’implémentation de CSampleCtrl::PreCreateWindow, avant l’instruction return :

cs.style |= BS_CHECKBOX;

Cette opération ajoute l’indicateur de style BS_CHECKBOX, tout en laissant intact l’indicateur de style par défaut (WS_CHILD) de la classe COleControl .

Modification de la fonction membre OnDraw

Si vous souhaitez que votre contrôle sous-classé conserve la même apparence que le contrôle Windows correspondant, la OnDraw fonction membre du contrôle doit contenir uniquement un appel à la DoSuperclassPaint fonction membre, comme dans l’exemple suivant :

void CMyAxSubCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
   if (!pdc)
      return;

   DoSuperclassPaint(pdc, rcBounds);
}

La fonction membre DoSuperclassPaint, implémentée par COleControl, utilise la procédure de fenêtre du contrôle Windows pour dessiner le contrôle dans le contexte matériel spécifié, au sein du rectangle englobant. Cela rend le contrôle visible même s’il n’est pas actif.

Remarque

La fonction membre DoSuperclassPaint ne fonctionne qu'avec les types de contrôle qui permettent de passer un contexte de périphérique en tant que paramètre wParam d'un message WM_PAINT. Cela inclut certains des contrôles Windows standard, tels que SCROLLBAR et BUTTON, et tous les contrôles courants. Pour les contrôles qui ne prennent pas en charge ce comportement, vous devez fournir votre propre code pour afficher correctement un contrôle inactif.

Gestion des messages de fenêtre répercutés

Les contrôles Windows envoient généralement certains messages de fenêtre à leur fenêtre parente. Certains de ces messages, tels que WM_COMMAND, fournissent une notification d’une action par l’utilisateur. D’autres, comme WM_CTLCOLOR, sont utilisées pour obtenir des informations à partir de la fenêtre parente. Un contrôle ActiveX communique généralement avec la fenêtre parente par d’autres moyens. Les notifications sont communiquées par déclenchement d’événements (envoi de notifications d’événements) et des informations sur le conteneur de contrôle sont obtenues en accédant aux propriétés ambiantes du conteneur. Étant donné que ces techniques de communication existent, les conteneurs de contrôle ActiveX ne sont pas censés traiter les messages de fenêtre envoyés par le contrôle.

Pour empêcher le conteneur de recevoir les messages de fenêtre envoyés par un contrôle Windows sous-classé, COleControl crée une fenêtre supplémentaire pour servir de parent du contrôle. Cette fenêtre supplémentaire, appelée « réflecteur », est créée uniquement pour un contrôle ActiveX qui sous-classe un contrôle Windows et a la même taille et la même position que la fenêtre de contrôle. La fenêtre de réflecteur intercepte certains messages de fenêtre et les renvoie au contrôle. Le contrôle, dans sa procédure de fenêtre, peut ensuite traiter ces messages reflétés en effectuant des actions appropriées pour un contrôle ActiveX (par exemple, déclencher un événement). Consultez les ID de messages de fenêtres répercutés pour obtenir la liste des messages de fenêtres interceptés et leurs messages répercutés correspondants.

Un conteneur de contrôle ActiveX peut être conçu pour effectuer une réflexion de message lui-même, éliminant la nécessité pour COleControl de créer la fenêtre de réflecteur et réduisant la surcharge d'exécution pour un contrôle Windows subclassé. COleControl détecte si le conteneur prend en charge cette fonctionnalité en recherchant une propriété ambiante MessageReflect avec la valeur TRUE.

Pour gérer un message de fenêtre réfléchi, ajoutez une entrée à la carte des messages de contrôle et implémentez une fonction de gestionnaire. Étant donné que les messages reflétés ne font pas partie de l’ensemble standard de messages définis par Windows, l’affichage de classes ne prend pas en charge l’ajout de tels gestionnaires de messages. Toutefois, il n’est pas difficile d’ajouter un gestionnaire manuellement.

Pour ajouter manuellement un gestionnaire de messages pour un message de fenêtre réfléchie, procédez comme suit :

  • Dans la classe de contrôle . Fichier H, déclarez une fonction de gestionnaire. La fonction doit avoir un type de retour LRESULT et deux paramètres, avec les types WPARAM et LPARAM, respectivement. Par exemple:

    class CMyAxSubCtrl : public COleControl
    {
    
    protected:
       LRESULT OnOcmCommand(WPARAM wParam, LPARAM lParam);
    };
    
  • Dans le fichier de la classe de contrôle .CPP, ajoutez une entrée ON_MESSAGE à la carte des messages. Les paramètres de cette entrée doivent être l’identificateur de message et le nom de la fonction de gestionnaire. Par exemple:

    BEGIN_MESSAGE_MAP(CMyAxSubCtrl, COleControl)
       ON_MESSAGE(OCM_COMMAND, &CMyAxSubCtrl::OnOcmCommand)
    END_MESSAGE_MAP()
    
  • Dans le fichier .CPP, implémentez également la fonction membre OnOcmCommand pour traiter le message renvoyé. Les paramètres wParam et lParam sont identiques à ceux du message de fenêtre d’origine.

Pour obtenir un exemple de la façon dont les messages réfléchis sont traités, reportez-vous à l’exemple BUTTON des contrôles MFC ActiveX. Il illustre un OnOcmCommand gestionnaire qui détecte le code de notification BN_CLICKED et répond en déclenchant (envoyant) un Click événement.

Voir aussi

Contrôles ActiveX MFC