2009-02-22 9 views
3

J'utilise une combinaison de l'ATL et WTL pour un projet et ont dérivé ma propre classe de CWindowImpl, qui ressemble à ceci:pré-enregistrement d'une classe de fenêtre ATL

class CMyControl : public CWindowImpl<CMyControl> 
{ 
public: 
    DECLARE_WND_CLASS(_T("MyClassName")) 
    ... 
    BEGIN_MSG_MAP(CMyControl) 
     ... 
    END_MSG_MAP() 
}; 

C'est tout bon, et si j'utilise CMyControl::Create pour créer une instance du contrôle, alors cela fonctionne très bien car sous le capot, la fonction CWindowImpl::Create va enregistrer la classe Win32 (dans ce cas appelé MyClassName).

Cependant, c'est ce comportement - la classe Win32 étant enregistrée lors de la création d'une instance - qui me cause un mal de tête. Je veux être en mesure d'enregistrer la classe à l'avance afin que je puisse utiliser le nom de classe avec une autre bibliothèque tierce qui créera la fenêtre en utilisant l'appel Win32 CreateWindowEx, mais je ne trouve pas un moyen simple de le faire. Actuellement, je contourne ce problème en utilisant static comme nom de classe CreateWindowEx, puis j'utilise CMyWindow::SubclassWindow pour y attacher ma classe, mais ceci est un kludge.

Est-ce que quelqu'un sait comment enregistrer une classe dérivée CWindowImpl sans réellement créer une fenêtre, donc je peux passer le nom de classe à CreateWindowEx avec succès? Je pensais qu'il y avait un moyen standard de faire cela avec les fenêtres ATL car je ne peux pas être le premier à rencontrer ce problème.

Répondre

2

Ce que vous essayez de faire ne fonctionnera pas. Cela est dû au fait que la création de la fenêtre ATL/WTL doit passer par la classe ATL. La classe enregistre ses ce ptr avec une fenêtre thunk. Ce thunk devient le WNDPROC et remplace le paramètre HWND du WNDPROC par le ce ptr de l'instance d'objet. Bref, si vous saviez comment fonctionne le fenêtrage ATL sous le capot, vous ne vous efforcerez pas d'essayer cela. Si vous étiez en mesure d'enregistrer la classe de fenêtre, l'appel CreateWindowEx réussirait à créer la fenêtre. Toutefois, le thun WNDPROC ne serait pas créé et il n'y aurait pas d'instance d'objet avec laquelle associer votre fenêtre et aucun de vos gestionnaires de messages ne serait appelé. Au lieu de cela, voyez si vous pouvez créer votre fenêtre en utilisant CWindowImpl :: Create et passez votre bibliothèque tierce partie au hwnd d'un contrôle ATL une fois créé.

0

Vous pouvez utiliser:

WNDPROC pUnusedWndSuperProc; 
pUnusedWndSuperProc = NULL; 
CMyControl::GetWndClassInfo().Register(&pUnusedWndSuperProc); 

Bien ... Je ne sais pas pourquoi vous ne créez pas seulement une instance de la fenêtre et le garder caché. C'est un peu de frais généraux mais cela évite de bousculer avec les tripes de la logique de fenêtrage (ce qui est assez compliqué ... la dernière chose que vous voulez est un problème inattendu ou inhabituel avec "thunking").

Questions connexes