CHookWnd
v1.08 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.
Copyright
- 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 source code.
Updates
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.
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.
V1.07 (17 April 2003)
- Fixed a level 4 unreferenced warning in CHookWnd::WindowProc. Thanks to
Frank Fesevur for reporting this.
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 compiler
- Various code tidy up's following testing with trayicon class.
- Fixed a bug where only 2 hooks in the chain of hooks being called.
- Went back to the Hook / Unhook naming convention
- Addition of various public helper methods
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 issue.
- 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.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 safe.
- 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" method
- Addition of OnHook and OnUnHook virtual functions which are called when
a hook is being installed or removed.
V1.03 (21 March 2003)
- Significant rework following comprehensive testing with the Tray icon class.
- Fixed reported resource leaks caused by SetProp thanks to BoundsChecker.
- Now includes copyright details in the source code modules.
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.01 (29 March 1999)
- Minor update to remove some unnecessary comments from the code.
V1.0 (25 February 1999)