预注册ATL窗口类

时间:2009-02-22 19:27:37

标签: winapi atl wtl classname

我正在为项目使用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窗口做到这一点,因为我不能成为第一个遇到这个问题的人。

3 个答案:

答案 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”的一些意外或不寻常的问题。)