共用方式為


TN003:將 Windows 句柄對應至物件

此附注描述支援將 Windows 物件句柄對應至C++物件的 MFC 例程。

問題

Windows 物件通常以各種 HANDLE 物件表示。MFC 類別會將 Windows 物件的句柄包裝成 C++ 物件。 MFC 類別庫的句柄包裝函式可讓您找到包裝具有特定句柄之 Windows 物件的C++物件。 不過,有時候對象沒有C++包裝函式物件,而此時系統會建立暫存物件來做為C++包裝函式。

使用句柄對應的 Windows 物件如下所示:

  • HWND (CWndCWnd衍生類別)

  • HDC (CDCCDC衍生類別)

  • HMENU (CMenu

  • HPEN (CGdiObject

  • HBRUSH (CGdiObject

  • HFONT (CGdiObject

  • HBITMAP (CGdiObject

  • HPALETTE (CGdiObject

  • HRGN (CGdiObject

  • HIMAGELIST (CImageList

  • SOCKET (CSocket

為任一物件指定句柄,您可以藉由呼叫靜態方法 FromHandle來尋找包裝句柄的 MFC 物件。 例如,假設 HWND 名為 hWnd,下列這一行會傳回包裝 CWnd指標:

CWnd::FromHandle(hWnd)

如果 hWnd 沒有特定的包裝函式物件,則會建立暫存 CWnd 專案來包裝 hWnd。 這可讓您從任何句柄取得有效的C++物件。

擁有包裝函式對象之後,您可以從包裝函式類別的公用成員變數擷取其句柄。 在 CWnd 的情況下,m_hWnd 包含該物件的 HWND。

將句柄附加至 MFC 物件

給定一個新建立的 handle-wrapper 物件和 Windows 物件的句柄,您可以呼叫Attach函數將兩者建立關聯,如下例所示:

CWnd myWnd;
myWnd.Attach(hWnd);

這會在永久映射中建立一個條目以連結 myWndhWnd。 現在呼叫 CWnd::FromHandle(hWnd) 將會傳回指向 myWnd 的指標。 刪除 myWnd 時,解構函式會藉由呼叫 Windows DestroyWindow 函式自動終結 hWnd。 如果這是不想要的,在 myWnd 被銷毀之前,hWnd 必須與 myWnd 中斷連結(通常是在離開定義 myWnd 的範圍時)。 方法 Detach 會執行此動作。

myWnd.Detach();

關於暫時物件的詳細資訊

每當 FromHandle 指定尚未具有包裝物件的句柄時,就會建立暫存物件。 這些暫存物件會從其句柄中斷連結,並由函式 DeleteTempMap 刪除。 預設情況下 CWinThread::OnIdle 會自動呼叫 DeleteTempMap 支援暫存句柄映射的每個類別。 這表示您無法假設指向暫時物件的指標在函式執行結束後仍然有效。

包裝函式物件和多個線程

臨時物件和永久物件都是以每個線程為基礎來管理。 也就是說,無論線程是暫時還是永久,一個線程都無法存取另一個線程的C++包裝函式物件。

若要將這些物件從一個線程傳遞至另一個線程,請一律將它們傳送為原生 HANDLE 類型。 將C++包裝函式物件從一個線程傳遞至另一個線程,通常會導致非預期的結果。

另請參閱

依編號的技術注意事項
依類別排序的技術注意事項