我正在为项目使用ATL和WTL的组合,并从CWindowImpl
派生了我自己的类,看起来像这样:
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
将我的课程附加到其中,但这是一个kludge。
有没有人知道如何在不实际创建窗口的情况下注册CWindowImpl
派生类,因此我可以成功将类名传递给CreateWindowEx
?我认为有一种标准的方法可以用ATL窗口做到这一点,因为我不能成为第一个遇到这个问题的人。
答案 0 :(得分:2)
你要做的事情是行不通的。这是因为ATL / WTL窗口的创建必须通过ATL类。该类使用窗口thunk注册其此 ptr。这个thunk成为WNDPROC并用对象实例的 this ptr替换WNDPROC的HWND参数。
简而言之,如果您知道ATL窗口是如何工作的,那么您就不会尝试这样做。如果您能够注册窗口类,则CreateWindowEx调用将成功创建窗口。但是,不会创建WNDPROC thunk,并且没有对象实例与窗口关联,也不会调用任何消息处理程序。相反,看看你是否可以使用CWindowImpl :: Create创建窗口,并在创建ATL控件时将第三方库传递给它。
答案 1 :(得分:0)
您可以直接调用Win32 API RegisterClassEx函数。
答案 2 :(得分:0)
您可以使用:
WNDPROC pUnusedWndSuperProc;
pUnusedWndSuperProc = NULL;
CMyControl::GetWndClassInfo().Register(&pUnusedWndSuperProc);
虽然......我不确定你为什么不只是创建一个窗口实例并将其隐藏起来。它有点开销,但它避免了与窗口逻辑的内容混淆(这是非常复杂的东西......你想要的最后一件事是“thunking”的一些意外或不寻常的问题。)