TN003 : mappage des handles Windows à des objets
Cette note décrit les routines MFC qui prennent en charge le mappage des handles d’objets Windows aux objets C++.
Le problème
Les objets Windows sont généralement représentés par différents objets HANDLE Les classes MFC encapsulent les handles d’objets Windows avec des objets C++. Les fonctions de wrapping handle de la bibliothèque de classes MFC vous permettent de trouver l’objet C++ qui encapsule l’objet Windows qui a un handle particulier. Toutefois, parfois, un objet n’a pas d’objet wrapper C++ et, à ces moments, le système crée un objet temporaire pour agir en tant que wrapper C++.
Les objets Windows qui utilisent des cartes de handle sont les suivants :
HWND (classes CWnd et
CWnd
-dérivées)HMENU (CMenu)
HPEN (CGdiObject)
HBRUSH (
CGdiObject
)HFONT (
CGdiObject
)HBITMAP (
CGdiObject
)HPALETTE (
CGdiObject
)HRGN (
CGdiObject
)HIMAGELIST (CImageList)
SOCKET (CSocket)
Étant donné un handle à l’un de ces objets, vous pouvez trouver l’objet MFC qui encapsule le handle en appelant la méthode FromHandle
statique. Par exemple, étant donné un HWND appelé hWnd, la ligne suivante retourne un pointeur vers le CWnd
hWnd encapsulé :
CWnd::FromHandle(hWnd)
Si hWnd n’a pas d’objet wrapper spécifique, un wrapper temporaire CWnd
est créé pour encapsuler hWnd. Cela permet d’obtenir un objet C++ valide à partir de n’importe quel handle.
Une fois que vous avez un objet wrapper, vous pouvez récupérer son handle à partir d’une variable membre publique de la classe wrapper. Dans le cas d’un CWnd
m_hWnd contient le HWND pour cet objet.
Attachement de handles à des objets MFC
Étant donné un objet handle-wrapper nouvellement créé et un handle à un objet Windows, vous pouvez associer les deux en appelant la Attach
fonction comme dans cet exemple :
CWnd myWnd;
myWnd.Attach(hWnd);
Cela fait une entrée dans la carte permanente associant myWnd et hWnd. L’appel CWnd::FromHandle(hWnd)
retourne maintenant un pointeur vers myWnd. Lorsque myWnd est supprimé, le destructeur détruit automatiquement hWnd en appelant la fonction Windows DestroyWindow . Si ce n’est pas souhaité, hWnd doit être détaché de myWnd avant que myWnd ne soit détruit (normalement en laissant l’étendue à laquelle myWnd a été défini). La Detach
méthode effectue cette opération.
myWnd.Detach();
En savoir plus sur les objets temporaires
Les objets temporaires sont créés chaque fois FromHandle
qu’un handle n’a pas encore d’objet wrapper. Ces objets temporaires sont détachés de leur handle et supprimés par les DeleteTempMap
fonctions. Par défaut , CWinThread ::OnIdle appelle DeleteTempMap
automatiquement chaque classe qui prend en charge les cartes de handle temporaire. Cela signifie que vous ne pouvez pas supposer qu’un pointeur vers un objet temporaire sera valide au-delà du point de sortie de la fonction où le pointeur a été obtenu.
Objets wrapper et threads multiples
Les objets temporaires et permanents sont conservés par thread. Autrement dit, un thread ne peut pas accéder aux objets wrapper C++ d’un autre thread, qu’il s’agisse d’un wrapper temporaire ou permanent.
Pour passer ces objets d’un thread à un autre, envoyez-les toujours en tant que type natif HANDLE
. Le passage d’un objet wrapper C++ d’un thread à un autre entraîne souvent des résultats inattendus.