An MFC class to support MFC subclassing (Obsolete)
Welcome to CHookWnd, an MFC class to
support sub-classing of any CWnd instance. The problem it fixes is that you cannot have 2
CWnd instances attached to the one HWND at the same time. This becomes a problem when you
want to derive one of your classes from 2 base classes which are both derived from CWnd
themselves. An example is, suppose you have 2 classes namely CBitmapMenuFrameWnd which is
derived from CFrameWnd and implements bitmap menus ALA Office 97 and CReBarFrameWnd which
implements command bar menus ALA IE4. When you are implementing your own CMainFrame class
you then have the problem that you can only derive from one of these classes and you must
copy the source from the other one into your class.
This class fixes this problem by subclassing the window before MFC
gets to it using a plugin method. The code is based in part on a class developed by Paul
DiLascia namely "CSubclassWnd" for the MSJ magazine.
The enclosed zip file contains the
CHookWnd source code and a simple SDI MFC application which demonstrates all the
functionality of the class. For further details about the example program have a look at
the view.cpp module.
- You are allowed to include the source code in
any product (commercial, shareware, freeware or otherwise) when your product
is released in binary form.
- You are allowed to modify the source code in
any way you want except you cannot modify the copyright details at the top
of each module.
- If you want to distribute source code with
your application, then you are only allowed to distribute versions released
by the author. This is to maintain a single distribution point for the
V1.0 (25 February 1999)
V1.01 (29 March 1999)
- Minor update to remove some unnecessary
comments from the code.
V1.02 (10 May 1999)
- Minor update to fix a small
bug in the demo app. No changes to the actual HookWnd code itself.
V1.03 (21 March 2003)
- Significant rework following comprehensive testing with
the Tray icon class.
- Fixed reported resource leaks caused by SetProp thanks
- Now includes copyright details in the source code
V1.04 (29 March 2003)
- A number of functions now use return values instead of
using VERIFY internally and not returning an error code.
- Made the Hook and UnHook methods virtual
- HWND -> CWnd mapping which uses the SetProp method now
uses ATOMs. This makes the lookup much faster.
- Made additional public methods of the class thread
- Fixed a bug in SizeOfHookChain, FirstInChain,
LastInChain and MiddleOfChain which would unnecessarily ASSERT if called for a
non hooked window
- Made destructor of the class virtual
- Fixed another SetProp resource leak in the "Remove"
- Addition of OnHook and OnUnHook virtual functions which
are called when a hook is being installed or removed.
V1.05 (31 March 2003)
- As pointed out by Martin Richter, the class is not
fully thread safe, quoting: The problem is that the thread executing the
WindowProc might enter the window Proc while a second thread is removing the
hook. There is only a rare chance, but the chance exists! You should write
this into your docs. As long as there is a chance to retrieve the window
property from the windows thread and to change it from a second thread in the
same time it is not threadsafe!". So basically you need to be aware of this
- Now includes the concept of auto deletion. This
allows heap allocated CHookWnds to be destroyed when the associated window is
destroyed. Again thanks to Martin Richter for this nice addition.
- Reworked the way the code handles calling the WNDPROC hook. The
code now instead the ATL mechanism of installing an assembly language thunk.
This results in much less code required to implement the hook. From 435 lines
to c. 300!
- The code also now uses the variable and method naming
convention as in the ATL implementation.
V1.06 (2 April 2003)
- First hook is now stored in a Windows property. This
avoids potential problems identifying the first hook in cases where the window
is already subclassed by a thunk such as ATL. Thanks to Martin Richter for
spotting this issue.
- Now displays a warning if code is compiled on a non X86
- Various code tidy up's following testing with trayicon
- Fixed a bug where only 2 hooks in the chain of hooks
- Went back to the Hook / Unhook naming convention
- Addition of various public helper methods
V1.07 (17 April 2003)
- Fixed a level 4 unreferenced warning in
CHookWnd::WindowProc. Thanks to Frank Fesevur for reporting this.
V1.08 (1 November 2004)
- Fixed a number of warnings when the code is compiled using the Detect 64 bit portability issues in Visual Studio .Net. Please note that the code as it currently stands does not compile to native IA64 or AMD64 code yet.
27 June 2006
- Please note that this code is now obsolete because you can just as easily
use ATL's "CWindowsImpl" class to implement multiple sub classing of an MFC
window. For an example of this please check out my class
CTrayNotifyIcon which as of v1.51 uses CWindowImpl
to handle the various top level frame messages including WM_TIMER and the
shell resurrection message for a completely robust implementation. Also
because we are using a standard built in class, we can now easily update
client code going forward e.g. CE, Itanium or x64 implementations. You should
update your code to use this standard class instead of my CHookWnd class.