-
subclassing
I am wondering if it is possible to subclass a window from within a class. Consider the following class:
Code:
class Base
{
public:
Base() {}
virtual ~Base() {}
BOOL Subclass(HWND hWnd)
{
long lpfnNewProc = (long)this->MsgHandler; //<-- This is my error
long lpfnOldProc = SetWindowLong(hWnd, GWL_WNDPROC, lpfnNewProc);
return TRUE;
}
LRESULT CALLBACK MsgHandler(HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
// Do something with the message
return 0;
}
};
Now, I realize this is not a complete class. I cannot get a function pointer to the MsgHandler function of the class. I realize this is because Windows wants (requires?) that the callback function be a global function and not an instance function, but is there some way around this? If not then I have to have a global MsgHandler and store all the hWnds and function pointers in global arrays and I really don't want to do this. If there is a way to pull off what I am trying to do, can somebody please let me know how.
Thanks
-
This is what seems to be the best option...
Make the MsgHandler function static, and also have an InternalMsgHandler function of the same type, just not static:
Code:
class Base {
static LRESULT CALLBACK MsgHandler(...) { ... }
LRESULT InternalMsgHandler(...) { ... }
};
You put the specific code into the InternalMsgHandler function.
This is where it gets clever :D When you subclass it, use SetWindowLong like so:
Code:
SetWindowLong(hWnd, GWL_USERDATA, (long)this);
This associates your class with the window, since the GWL_USERDATA property is a 4-byte long integer (how useful... ;)). Then, in MsgHandler, just use:
Code:
Base *pHandler = GetWindowLong(hWnd, GWL_USERDATA);
if(pHandler) {
pHandler->InternalMsgHandler(hWnd, uMsg, wParam, lParam);
}
// Call the previous function here
It's a bit nasty I know...can you see what I'm getting at?
-
Ahhh...pretty clever indeed. Thank you very much.
You could also use the GetProp and SetProp functions to associate the pointer with the window.
Again thanks.
-
Proudly stolen from Microsoft's own samples :)
You can use the properties, but I think it's simpler this way. Oh, and for your information, I think this is called delegating...not sure though :eek: Looks a bit like the description.