Contrôles ActiveX MFC : sous-classement un contrôle Windows
Cet article explique le processus pour le sous-classement d'un contrôle Windows commun pour créer un contrôle ActiveX.Le sous-classement d'un contrôle Windows existant est un moyen rapide de développer un contrôle ActiveX.Le nouveau contrôle a les capacités du contrôle Windows sous-classé, telles que la peinture et la réponse aux clics de souris.L'exemple de BUTTON ActiveX MFC est un exemple de sous-classement d'un contrôle Windows.
Sous-classer un contrôle Windows, exécutez les tâches suivantes :
Substituer les fonctions membres d'IsSubclassedControl et de PreCreateWindow de COleControl
Modifiez la fonction membre d'OnDraw
Considérer tous les messages de contrôle ActiveX (OCM) répercutées dans le contrôle
[!REMARQUE]
De nombreuses cette opération est exécutée pour vous par l'Assistant Contrôle ActiveX si vous sélectionnez le contrôle pour être sous-classé à l'aide de la liste déroulante de Select Parent Window Class dans la page de Control Settings .
Consultez l'article de la Base de connaissances Q243454 pour plus d'informations sur le sous-classement le contrôle.
Substituer IsSubclassedControl et PreCreateWindow
Pour substituer PreCreateWindow et IsSubclassedControl, ajoutez les lignes suivantes à la section d' protected de la déclaration de classe de contrôle :
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
BOOL IsSubclassedControl();
Dans le fichier d'implémentation du 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 bouton windows est spécifié dans PreCreateWindow.Toutefois, tous les contrôles Windows standard peuvent être sous-classé.Pour plus d'informations sur les contrôles Windows standard, consultez contrôles.
Lorsque le sous-classement d'un contrôle Windows, vous pouvez éventuellement spécifier le style de fenêtre particulier (WS_) ou le style de fenêtre étendu (WS_EX_) diminue pour être utilisé en créant la fenêtre du contrôle.Vous pouvez définir des valeurs pour ces paramètres dans la fonction membre d' PreCreateWindow en modifiant cs.style et les champs de structure de cs.dwExStyle .Les modifications apportées à ces champs doivent être apportées à l'aide d'une opération d' OR , pour conserver les indicateurs de valeur par défaut définies par la classe COleControl.Par exemple, si le contrôle est sous-classement le contrôle bouton et vous souhaitez que le contrôle apparaisse comme case à cocher, insérez la ligne suivante de code dans l'implémentation d' CSampleCtrl::PreCreateWindow, avant l'instruction return :
cs.style |= BS_CHECKBOX;
Cette opération ajoute la balise de style de BS_CHECKBOX , tout en laissant la balise par défaut de style (WS_CHILD) de la classe COleControl intacte.
Modifier la fonction membre d'OnDraw
Si vous souhaitez que votre contrôle sous-classé de conserver la même apparence que le contrôle Windows correspondant, la fonction membre d' OnDraw pour le contrôle doit contenir un appel à la fonction membre d' DoSuperclassPaint , 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 d' 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 spécifié de périphérique, dans le rectangle englobant.Ceci rend le visible de contrôle même s'il n'est pas actif.
[!REMARQUE]
La fonction membre d' DoSuperclassPaint fonctionne uniquement avec les types de contrôles qui permettent un contexte de périphérique à passer en tant wParam d'un message d' WM_PAINT .Cela inclut certains contrôles Windows standard, tels que SCROLLBAR et BUTTON, et tous les contrôles communs.Pour les contrôles qui ne prennent pas en charge ce comportement, vous devrez fournir votre propre code pour afficher correctement un contrôle inactif.
Gérer les messages réfléchis de fenêtre
Les contrôles Windows envoient généralement certains messages de fenêtre vers leur fenêtre parente.Certains de ces messages, tels que WM_COMMAND, offrent notification d'une action par l'utilisateur.d'autres, tel qu' WM_CTLCOLOR, sont utilisés pour obtenir les informations 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 en déclenchant des événements (notifications d'événements d'émission), des informations sur le conteneur de contrôle sont obtenues par accès aux propriétés ambiantes du conteneur.Étant donné que ces techniques de communication existent, il n'est pas censé que les conteneurs de contrôle ActiveX ne traitent les messages de fenêtre envoyé par le contrôle.
Pour empêcher le conteneur de recevoir des 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é un « 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 position comme fenêtre de contrôle.Messages de fenêtre d'intercepte de fenêtre de réflecteur certains et les envoyer vers le contrôle.Le contrôle, dans sa procédure de fenêtre, peut ensuite gérer ces messages réfléchis en prenant des actions appropriées pour un contrôle ActiveX (par exemple, ce qui déclenche un événement).Consultez l' Identificateurs répercutées de message de fenêtre pour obtenir une liste de messages commande windows et de leurs messages réfléchis correspondants.
Un conteneur de contrôles ActiveX peuvent être conçus pour exécuter le renvoi de message lui-même, éliminant le besoin d' COleControl de créer la fenêtre de réflecteur et de réduire la charge mémoire à l'exécution d'un contrôle Windows sous-classé.COleControl détecte si le conteneur prend en charge cette fonction en recherchant une propriété ambiante de MessageReflect avec une valeur de TRUE.
Pour traiter un message réfléchi de fenêtre, ajoutez une entrée au mappage de message de contrôle et implémentez une fonction gestionnaire.Étant donné que les messages réfléchis ne font pas partie du jeu standard des messages définis par windows, l'Affichage de classes ne prend pas en charge l'ajout de ces gestionnaires de messages.Toutefois, il n'est pas besoin d'ajouter un gestionnaire manuellement.
Pour ajouter un gestionnaire de messages pour un message réfléchi de fenêtre exécutées manuellement les éléments suivants :
Dans la classe de contrôle. Le fichier de H, déclarez une fonction gestionnaire.La fonction doit avoir un type de retour de LRESULT et de deux paramètres, avec des types WPARAM et LPARAM, respectivement.Par exemple :
class CMyAxSubCtrl : public COleControl { ... protected: LRESULT OnOcmCommand(WPARAM wParam, LPARAM lParam); };
Dans le fichier.cpp de contrôle de classe, ajoutez une entrée d' ON_MESSAGE à la table des messages.Les paramètres de cette entrée doit contenir l'identificateur de message et le nom de la fonction gestionnaire.Par exemple :
BEGIN_MESSAGE_MAP(CMyAxSubCtrl, COleControl) ON_MESSAGE(OCM_COMMAND, &CMyAxSubCtrl::OnOcmCommand) END_MESSAGE_MAP()
Également dans le fichier .cpp, implémentez la fonction membre d' OnOcmCommand pour traiter le message réfléchi.Les paramètres de wParam et de lParam sont identiques à celles du message d'origine de fenêtre.
Pour obtenir un exemple de la façon dont les messages réfléchis sont traités, reportez -vous à l'exemple de BUTTONActiveX MFC.Il affiche un gestionnaire d' OnOcmCommand qui détecte le code de notification de BN_CLICKED et répondre en déclenchant (source) un événement clic.