TN003: 對應的 Windows 處理物件
這張便箋說明 MFC 支援對應 Windows 的常式的物件控點以 C++ 物件。
問題
視窗物件通常是由各種處理物件的 MFC 類別包裝 Windows 與 C++ 物件的物件控制代碼。 文繞圖的 MFC 類別程式庫函式的控制代碼可讓您尋找具有特定的控制代碼的視窗物件的 C++ 物件。 不過,有時候物件並沒有 C++ 的包裝函式物件,而且在這些時候,系統會建立一個暫存物件以做為 C++ 的包裝函式。
使用處理常式對應的 Windows 物件如下所示:
HWND (CWnd 和CWnd-衍生類別)
HDC (CDC 和CDC-衍生類別)
HMENU (CMenu)
HPEN (CGdiObject)
HBRUSH (CGdiObject)
HFONT (CGdiObject)
HBITMAP (CGdiObject)
HPALETTE (CGdiObject)
HRGN (CGdiObject)
HIMAGELIST (CImageList)
通訊端 (CSocket)
這些物件的任何一個給定控制代碼,您可以找到 MFC 物件包裝的控制代碼藉由呼叫靜態方法FromHandle。 例如,假設呼叫 HWND hWnd下, 面這一行會傳回變數的指標, CWnd包裝hWnd:
CWnd::FromHandle(hWnd)
如果hWnd沒有特定的包裝函式物件,暫時CWnd的建立是要換行hWnd。 這樣可以從任何控制代碼取得有效的 C++ 物件。
包裝函式物件之後,您可以取得它的控制代碼的包裝函式類別的公用成員變數。 如果是CWnd, m_hWnd包含該物件的 HWND。
附加至 MFC 物件的控制代碼
新建立的控制代碼的包裝函式物件和控制代碼指定給 Windows 物件時,您可以將關聯這兩個藉由呼叫Attach函式,如下例所示:
CWnd myWnd;
myWnd.Attach(hWnd);
這使得永久對應關聯的項目myWnd和hWnd。 呼叫CWnd::FromHandle(hWnd)將會立即傳回變數的指標, myWnd。 當myWnd會被刪除,解構函式會自動終結hWnd藉由呼叫 Windows DestroyWindow 函式。 如果不希望如此, hWnd必須是中斷連結來源myWnd之前myWnd損毀 (通常在離開的範圍時,才myWnd所定義)。 Detach方法並不會這樣。
myWnd.Detach();
進一步了解暫存物件
建立暫存物件,只要FromHandle都還沒有包裝函式物件的控制代碼。 這些暫存物件會中斷其控制代碼,並會藉由刪除DeleteTempMap函式。 預設狀況下CWinThread::OnIdle會自動呼叫DeleteTempMap為每個支援暫存的處理常式對應的類別。 這表示您無法假設一個暫存物件的指標都是有效的函式的結束點以後的部分已經取得滑鼠指標的位置。
包裝函式物件和多個執行緒
暫時和永久的物件會維護每一執行緒為基礎。 也就是說,一個執行緒無法存取另一個執行緒的 C++ 的包裝函式,不論物件是否為暫時還是永久。
若要將這些物件從一個執行緒,我要傳送它們做為其原HANDLE型別。 從一個執行緒的 C++ 的包裝函式物件傳遞至另一個會造成未預期的結果。