TN003: Zuordnen von Fensterhandles zu Objekten
In diesem Hinweis werden die MFC-Routinen beschrieben, die das Zuordnen von Windows-Objekthandles zu C++-Objekten unterstützen.
Problemstellung
Windows-Objekte werden in der Regel durch verschiedene HANDLE-Objekte dargestellt. Die MFC-Klassen umschließen Windows-Objekthandles mit C++-Objekten. Mit den Handleumbruchfunktionen der MFC-Klassenbibliothek können Sie das C++-Objekt finden, das das Windows-Objekt umschlossen, das ein bestimmtes Handle aufweist. Manchmal verfügt ein Objekt jedoch nicht über ein C++-Wrapperobjekt, und zu diesem Zeitpunkt erstellt das System ein temporäres Objekt, das als C++-Wrapper fungiert.
Die Windows-Objekte, die Handlezuordnungen verwenden, sind wie folgt:
HWND (CWnd - und
CWnd
-abgeleitete Klassen)HDC (CDC - und
CDC
abgeleitete Klassen)HMENU (CMenu)
HPEN (CGdiObject)
HBRUSH (
CGdiObject
)HFONT (
CGdiObject
)HBITMAP (
CGdiObject
)HPALETTE (
CGdiObject
)HRGN (
CGdiObject
)HIMAGELIST (CImageList)
SOCKET (CSocket)
Bei einem Handle für eines dieser Objekte finden Sie das MFC-Objekt, das das Handle umschließt, indem Sie die statische Methode FromHandle
aufrufen. Wenn z. B. ein HWND mit dem Namen hWnd angegeben wird, gibt die folgende Zeile einen Zeiger auf den hWnd um, der CWnd
hWnd umschließt:
CWnd::FromHandle(hWnd)
Wenn hWnd nicht über ein bestimmtes Wrapperobjekt verfügt, wird ein temporäres CWnd
Objekt zum Umbrechen von hWnd erstellt. Dadurch kann ein gültiges C++-Objekt von jedem Handle abgerufen werden.
Nachdem Sie über ein Wrapperobjekt verfügen, können Sie dessen Handle aus einer öffentlichen Membervariable der Wrapperklasse abrufen. Im Fall eines CWnd
, m_hWnd enthält den HWND für dieses Objekt.
Anfügen von Handles an MFC-Objekte
Angesichts eines neu erstellten Handle-Wrapper-Objekts und eines Handles zu einem Windows-Objekt können Sie die beiden zuordnen, indem Sie die Attach
Funktion wie in diesem Beispiel aufrufen:
CWnd myWnd;
myWnd.Attach(hWnd);
Dadurch wird ein Eintrag in der permanenten Karte, die myWnd und hWnd zugeordnet. Das Aufrufen CWnd::FromHandle(hWnd)
gibt jetzt einen Zeiger auf myWnd zurück. Wenn myWnd gelöscht wird, zerstört der Destruktor automatisch hWnd durch Aufrufen der Windows DestroyWindow-Funktion . Wenn dies nicht gewünscht ist, muss hWnd von myWnd getrennt werden, bevor myWnd zerstört wird (normalerweise beim Verlassen des Bereichs, in dem myWnd definiert wurde). Die Detach
Methode führt dies aus.
myWnd.Detach();
Weitere Informationen zu temporären Objekten
Temporäre Objekte werden immer dann erstellt, wenn FromHandle
ein Handle vorhanden ist, das noch nicht über ein Wrapperobjekt verfügt. Diese temporären Objekte werden von ihrem Handle getrennt und von den DeleteTempMap
Funktionen gelöscht. Standardmäßig ruft CWinThread::OnIdle automatisch für jede Klasse auf DeleteTempMap
, die temporäre Handle-Karten unterstützt. Dies bedeutet, dass Sie nicht davon ausgehen können, dass ein Zeiger auf ein temporäres Objekt über den Ausgangspunkt der Funktion, an der der Zeiger abgerufen wurde, gültig ist.
Wrapperobjekte und mehrere Threads
Temporäre und permanente Objekte werden pro Thread Standard beibehalten. Das heißt, ein Thread kann nicht auf die C++-Wrapperobjekte eines anderen Threads zugreifen, unabhängig davon, ob er temporär oder dauerhaft ist.
Um diese Objekte von einem Thread an einen anderen zu übergeben, senden Sie sie immer als nativen HANDLE
Typ. Das Übergeben eines C++-Wrapperobjekts von einem Thread an einen anderen führt häufig zu unerwarteten Ergebnissen.
Siehe auch
Technische Hinweise – nach Nummern geordnet
Technische Hinweise – nach Kategorien geordnet