2009-02-22 35 views
3

我使用ATL和WTL的組合爲一個項目,並已得出我自己的類從CWindowImpl,它看起來是這樣的:預註冊的ATL窗口類

class CMyControl : public CWindowImpl<CMyControl> 
{ 
public: 
    DECLARE_WND_CLASS(_T("MyClassName")) 
    ... 
    BEGIN_MSG_MAP(CMyControl) 
     ... 
    END_MSG_MAP() 
}; 

這是所有好,如果我使用CMyControl::Create來創建控件的實例,那麼它可以正常工作,CWindowImpl::Create函數將註冊Win32類(在本例中稱爲MyClassName)。

但是,正是這種行爲 - 創建實例時註冊的Win32類 - 這讓我很頭疼。我希望能夠預先註冊課程,以便我可以使用另一個第三方庫的類名稱,該庫將使用Win32 CreateWindowEx調用創建該窗口,但我找不到一個簡單的方法來完成此操作。目前我通過使用static作爲CreateWindowEx類名解決此問題,然後使用CMyWindow::SubclassWindow將我的類附加到它,但這是一個混亂。

有沒有人知道如何註冊CWindowImpl派生類,而實際上沒有創建窗口,所以我可以成功傳遞類名爲CreateWindowEx?我認爲有一個標準的方法來做到這一點與ATL窗口,因爲我不能成爲第一個遇到這個問題。

回答

2

你正在試圖做的事情不會奏效。這是因爲創建ATL/WTL窗口必須通過ATL類。該班級將這個 ptr用窗口thunk註冊。該thunk成爲WNDPROC,並將WNDPROC的HWND參數替換爲對象實例的 ptr。所以簡而言之,如果你知道ATL窗口如何在引擎蓋下工作,你就不會試圖嘗試這個。如果您能夠註冊窗口類,則CreateWindowEx調用將成功創建該窗口。但是WNDPROC thunk不會被創建,並且不會有對象實例將您的窗口與您的窗口關聯,也不會有您的消息處理程序調用。相反,看看你是否可以使用CWindowImpl :: Create創建窗口,並且一旦創建了ATL控件的第三方庫就可以傳遞ATL控件的hwnd。

0

您可以使用:

WNDPROC pUnusedWndSuperProc; 
pUnusedWndSuperProc = NULL; 
CMyControl::GetWndClassInfo().Register(&pUnusedWndSuperProc); 

雖然...我不知道爲什麼你不只是創建窗口的實例,並把它隱藏起來。它的一小部分開銷,但它避免了開窗口邏輯的內疚(這是非常複雜的東西...你最不想要的是一些意想不到的或不尋常的問題,「thunking」)。