Alexander Shargin (rudankort@softspb.com), January 14, 2003.
I created a window of my custom class using MFC and noticed that the class name of the window got "WCE_" prefix. Why was it added? How can I get rid of it?
"WCE_" prefix is added by MFC library. This happens in wce_PreCreateWindow function (called by CWnd::CreateEx) just prior to the window creation:
Why MFC is doing this? The matter is that when the window is created using CreateWindow(Ex) API it recieves some messages (WM_CREATE etc.) before CreateWindow returns. Normally these messages get to the window proc and MFC class associated with the window doesn't have a chance to handle them. But MFC wants to give you a chance to do this. So it needs to subclass the window and assign AfxWndProc window proc to it BEFORE CreateWindow returns.
There are only 2 ways to do this. First way is to use Win32 hooks. Hooks are used in the desktop version of MFC. But on CE the hooks are not supported, so the developers from Microsoft had to use the other way. This way is to change the window proc associated with the window class to wce_FirstDefWindowProc. This proc is called only once. It emulates CBT hook and then assigns AfxWndProc to the window. You can find its implementation in wcealt.cpp file from MFC sources.
But there is one problem with this approach. Win32 API doesn't allow one to change window proc of an existing window class. So MFC registers a new one. This new class is exactly the same as the original one but has another window proc and "WCE_" prefix in its name. This is exactly what MFC does in the wce_PreCreateWindow function I showed above.
Note: from the code above it is obvious that window classes with "Afx" prefix are not reregistered with "WCE_" prefix. Such classes are internally registered by MFC and have AfxWndProc assigned to them by default.
So the trick with early subclassing works, but has some unpleasant side-effects. For example, when you create a window of your own class and then try to search for it (using FindWindow) by the name of your class (e. g. from another instance of your app to activate the first instance), you will surprised to find that the window with such class name can't be found. If you use SIPPREF control to provide smart SIP handling in your dialogs, it will not work with edit boxes created dynamically. When the SIPREF control is created it searches for all edit boxes in the dialog box. Naturally it searches them by the window class ("EDIT" for edit boxes). But if you create the edit box dynamizally using MFC class CEdit, the control gets "WCE_EDIT" class name. Oops!
In some cases you will not want to change this MFC behaviour. All you need to know is that "WCE_" prefix is appended to your class names so you can just use these wce-prefixed names to work with your window. For example, if you need to find the window by its window class, specify wce-prefixed name in the search criteria:
Next, you can use a class name with "Afx" prefix to make MFC believe this class is registered by it internally and it is not required to change it.
Finally, you can create the window using "pure" Win32 API calls and then attach the created window to the MFC class. Thus, to create an edit box programmatically and have its class name unchanged (in order that SIPPREF could recognize it), you can use this code:
Note: if you prevent MFC from doing its wce_PreCreateWindow tricks you will not be able to handle WM_CREATE and other initialization messages through MFC message maps.