What is it?
This article presents a way to use WTL template classes on MFC window
classes, that is how to transform the MFC
CWnd class to its ATL/WTL
CWindow, while leaving the class usable from MFC code.
Here you can find the required files, a detailed explanation in 10 steps and
a working demo.
How to do it, step by step
These are the basic steps to obtain hybrid MFC/WTL windows. They have been
used on MFC dialog based projects, but should work with any MFC application.
Add WTL support to an MFC application
- Take an MFC project you want to modify so that it supports ATL/WTL
functions and classes.
- Open its precompiled header file (usually
and add the following lines:
This prevents the WTL headers to automatically merge the WTL namespace
to the global namespace. This avoids conflicts with MFC classes with the
same names, such as
CDC and others.
extern WTL::CAppModule _Module;
The ATL/WTL code may access the global
so it must have external linkage.
We add the common WTL header here to exploit precompiled headers, but
you may want to include it only where you really need it.
- Open the project main file, where the
is implemented, and modify it as follows:
_Module variable must be defined somewhere and
this is a good place.
InitInstance() as follows:
- If not present, add the
ExitInstance() virtual function to
the application object, for example using ClassWizard, then modify it as
Make an hybrid window class
Assume we want to add scrolling capabilities to a static bitmap control. We
may want to use the WTL template class
together with the MFC class
CStatic, as there is no such a window
class in MFC.
- Make a new class, derived from
CStatic (or any other CWnd-derived
class), for example using ClassWizard.
- Open the class header file and include any WTL header you need:
Remember that if you didn't choose to use the precompiled header at
point 3 above, you need to add that line here, before any other WTL
- Include the necessary header to turn a
CWnd class into a
It contains a template class that defines the missing members:
You may want to put the above line into your precompiled header
instead, like all the other WTL headers, if you use them many times, to
speed up recompilation. That's completely at your choice.
- Then modify the class declaration to make the conversion to
and to use the WTL template class you have chosen:
class CScrollPicture : public CWnd2Window<CScrollPicture, CStatic>,
- Add any other function the WTL class may require, paying attention to
specify the WTL namespace for its arguments. In this example we need to
DoPaint() to work with scrolling:
void DoPaint(WTL::CDCHandle dc)
void OnDraw(CDC* pDC);
Notes on implementation
It may be a good idea not to mix the code too much with MFC and WTL classes
used anywhere, as it could become quite confusing. An efficient way could be
defining inline helper functions that translates WTL arguments to their MFC
counterpart, unless you want to write the required functions using only WTL.
Note that you can safely mix WTL objects with MFC code, but you always need to
specify the WTL namespace when appropriate.
Using helper functions could also make writing "bridge" classes
easier. For example, you could define a
CScrollWnd class to reuse
(through inheritance) whenever you need scrolling capabilities and custom
drawing, declaring a virtual
OnDraw() function like in
void DoPaint(WTL::CDCHandle dc)
virtual void OnDraw(CDC* pDC) = 0;
I used a pure virtual function, but
defines a base
implementation that just fires an assertion. These are just some ideas, but feel
free to suggest new.
Sounds good... but how does it work?
Well, nothing special or mysterious. The ATL class
which is used by WTL, has only one member variable,
m_hWnd, that is
exactly the same as the one you can find in the
CWnd class. So all
CWindow member functions need just that member variable, that
can also be found in a
What I did was to copy all the
CWindow members, except
to a include file and define a new template class.
template <class T, class TBase> class CWnd2Window : public TBase
To use the template you need to pass both the derived class and the base
class, as you can see in the example above about a scrolling control.
Then I added the necessary code to enable WTL message maps. I implemented the
DefWindowProc(), that is called after
when no entry is found in the MFC message map.
virtual LRESULT DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
T* pT = static_cast<T*>(this);
if (pT->ProcessWindowMessage(m_hWnd, nMsg, wParam, lParam, lResult))
return TBase::DefWindowProc(nMsg, wParam, lParam);
WindowProc() is called first. If it is not
overridden or if you pass the message to the base implementation in
the MFC message handler is called. If the corresponding entry is not found in
the MFC message map or if you call the base implementation in your message
handler or if you explicitly call
Default(), the message finally
DefWindowProc() that calls the ATL/WTL message map
Note that you don't have to change the MFC message map macros, that skip to
the MFC base class ignoring the intermediate template
I don't define an MFC message map there, so this is perfectly legal.
I also commented out "dangerous" member functions already defined
by MFC, such as
DestroyWindow(), but there may be others to comment out I'm not
aware of. As far as I know
Detach deal with
DestroyWindow set up Windows
hooks or call some virtual functions. So if you still want to use your class as
CWnd, you need to call the original functions, not those defined
There may be also some functions identical to the MFC ones, that could be
removed. Feel free to suggest improvements.
So far, so good... but what changes?
Well, you have to pay attention to a few things:
- You need to explicitly specify namespaces when accessing WTL objects,
which is not a bad practice anyway.
- And you may find that the compiler complains about some member functions
of your hybrid classes. That's because many
members have the same name and you must resolve the ambiguity to compile.
That's all. I just used this method a couple of times, so I'm not aware of
any other problems. But I expect comments...
I suppose you can freely use the code as long as you have the right to use
ATL source code. There is no original code here, except for the
class, only a nice idea. All the source code by me is released to the public
domain, you may do what you want with it. As for the
class, almost all the code is copyright of Microsoft Corporation.
The demo project
In the attached demo project you can find a very simple implementation of a
scrolling picture control. Since I subclass a
CStatic control, I
need to override the default behaviour sometimes. A much cleaner implementation
would have used a
CWnd, but that way I can show that message
routing works as expected, even mixing MFC message handlers with
To test the control use the mouse on the scroll bars or move the focus on it
and use the keyboard arrows, holding down the CTRL key to scroll by pages. There
is no focus indicator, so you have to guess by exclusion. There is also a button
to load external BMP files.
Please note that this control is not meant to be fully featured, but only an
example of use for WTL templates in MFC projects. In particular, I expect bugs
if the control is used in a resizable dialog, as to my experience the WTL
classes that implement scrolling are not "perfect" from that point of
view. I'm working on a replacement class, but no time to release it yet.
Any idea to improve this article, please let me know!