views:

311

answers:

3

I am using a combination of the ATL and WTL for a project and have derived my own class from CWindowImpl, which looks something like this:

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

This is all good, and if I use CMyControl::Create to create an instance of the control, then it works fine as under the hood, the CWindowImpl::Create function will register the Win32 class (in this case called MyClassName).

However, it is this behaviour - the Win32 class being registered when an instance is created - that is causing me a headache. I want to be able to register the class up-front so I can use the class name with another 3rd-party library that will create the window using the Win32 CreateWindowEx call, but I can't find a simple way to do this. Currently I workaround this by using static as the CreateWindowEx class name and then use CMyWindow::SubclassWindow to attach my class to it, but this is a kludge.

Does anyone know how to register a CWindowImpl derived class without actually creating a window, so I can pass the class name to CreateWindowEx successfully? I would of thought there was a standard way to do this with ATL windows as I can't be the first to come across this issue.

A: 

you can call Win32 API RegisterClassEx function directly. http://msdn.microsoft.com/en-us/library/ms633587(VS.85).aspx

Yigang Wu
A: 

You can use:

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

Though... I'm not sure why you don't just create an instance of the window and keep it hidden. Its a little bit of overhead but it avoids mucking with the guts of the windowing logic (which is pretty complicated stuff... the last thing you want is some unexpected or unusual problem with "thunking").

+1  A: 

What you are trying to do won't work. This is because the creation of the ATL/WTL Window must go through the ATL class. The class registers its this ptr with a window thunk. This thunk becomes the WNDPROC and replaces the HWND parameter of the WNDPROC with the this ptr of the object instance.

So in short, if you knew how ATL windowing worked under the hood, you would not endeavor to try this. If you were able to register the window class, the CreateWindowEx call would succeed in creating the window. However the WNDPROC thunk would not be created and there would be no object instance to associate your window with and none of your message handlers would called. Instead, see if you can create your window using the CWindowImpl::Create and pass your 3rd party library the hwnd of an ATL control once it is created.

m-sharp