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 CDCabgeleitete 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 FromHandleaufrufen. 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