TN003: mapowanie uchwytów okien na obiekty

W tej notatce opisano procedury MFC, które obsługują mapowanie dojść obiektów systemu Windows do obiektów C++.

The Problem

Obiekty systemu Windows są zwykle reprezentowane przez różne obiekty HANDLE Klasy MFC opakowują uchwyty obiektów systemu Windows za pomocą obiektów C++. Funkcje zawijania obsługi biblioteki klas MFC umożliwiają znalezienie obiektu C++ opakowującego obiekt systemu Windows, który ma określony uchwyt. Jednak czasami obiekt nie ma obiektu otoki C++, a w tym czasie system tworzy tymczasowy obiekt, który będzie działać jako otoka języka C++.

Obiekty systemu Windows korzystające z map są następujące:

  • HWND (CWnd i CWnd-pochodne klasy)

  • HDC (klasy CDC i CDC-pochodne)

  • HMENU (CMenu)

  • HPEN (CGdiObject)

  • HBRUSH (CGdiObject)

  • HFONT (CGdiObject)

  • HBITMAP (CGdiObject)

  • HPALETTE (CGdiObject)

  • HRGN (CGdiObject)

  • HIMAGELIST (CImageList)

  • SOCKET (CSocket)

Biorąc pod uwagę uchwyt do dowolnego z tych obiektów, można znaleźć obiekt MFC, który opakowuje uchwyt, wywołując metodę FromHandlestatyczną . Na przykład, biorąc pod uwagę HWND o nazwie hWnd, następujący wiersz zwróci wskaźnik do CWnd tego zawijania hWnd:

CWnd::FromHandle(hWnd)

Jeśli hWnd nie ma określonego obiektu otoki, zostanie utworzony tymczasowy CWnd obiekt zawijania hWnd. Dzięki temu można uzyskać prawidłowy obiekt C++ z dowolnego uchwytu.

Po utworzeniu obiektu otoki można pobrać jego uchwyt z publicznej zmiennej składowej klasy otoki. W przypadku obiektu CWndm_hWnd zawiera HWND dla tego obiektu.

Dołączanie dojść do obiektów MFC

Biorąc pod uwagę nowo utworzony obiekt handle-wrapper i uchwyt do obiektu systemu Windows, można skojarzyć te dwa, wywołując Attach funkcję, jak w tym przykładzie:

CWnd myWnd;
myWnd.Attach(hWnd);

Powoduje to, że wpis w stałej mapie kojarzący ciąg myWnd i hWnd. Wywołanie CWnd::FromHandle(hWnd) spowoduje teraz zwrócenie wskaźnika do myWnd. Po usunięciu obiektu myWnd destruktor automatycznie zniszczy funkcję hWnd przez wywołanie funkcji DestroyWindow systemu Windows. Jeśli nie jest to pożądane, hWnd musi być odłączony od myWnd przed zniszczeniem myWnd (zwykle w przypadku opuszczania zakresu, w którym zdefiniowano myWnd ). Metoda Detach to robi.

myWnd.Detach();

Więcej informacji o obiektach tymczasowych

Obiekty tymczasowe są tworzone za każdym razem, gdy FromHandle otrzymuje uchwyt, który nie ma jeszcze obiektu otoki. Te obiekty tymczasowe są odłączane od ich uchwytu DeleteTempMap i usuwane przez funkcje. Domyślnie CWinThread::OnIdle automatycznie wywołuje DeleteTempMap każdą klasę, która obsługuje tymczasowe mapy obsługi. Oznacza to, że nie można założyć, że wskaźnik do obiektu tymczasowego będzie prawidłowy obok punktu wyjścia z funkcji, w której wskaźnik został uzyskany.

Obiekty otoki i wiele wątków

Zarówno obiekty tymczasowe, jak i trwałe są utrzymywane na podstawie poszczególnych wątków. Oznacza to, że jeden wątek nie może uzyskać dostępu do obiektów otoki C++ innego wątku, niezależnie od tego, czy jest tymczasowy, czy stały.

Aby przekazać te obiekty z jednego wątku do innego, zawsze wysyłaj je jako typ macierzysty HANDLE . Przekazanie obiektu otoki języka C++ z jednego wątku do drugiego często spowoduje nieoczekiwane wyniki.

Zobacz też

Uwagi techniczne według numerów
Uwagi techniczne według kategorii