How to get this pointer in static member Wndproc Function
Hi*!
I hav a class that needs to create a window for each instance of itself. I want to do the message handling of that window in that class not in my global main WndProc for the main window. Dont want to clutter it up ;). I am able to declare and work with that MEMBER STATIC WndProc function but the problem comes when i want to access the non-static member functions of the same class I dont hav the this pointer. I cant modify the WndPRoc signature, neither can i delcare a static var i.e. that contains the this pointer (then it would be same around all the instances of the class). The only way i can think of is maintaing a global list/map of pointers and then finding the correct pointer and then invoking a funtion on the obj. Or is there better way to do it?????
Any Comments Suggestion are most welcome,
Thanks for your time,
Regards,
Usman.
Re: How to get this pointer in static member Wndproc Function
Quote:
Originally posted by usman999_1
The only way i can think of is maintaing a global list/map of pointers and then finding the correct pointer and then invoking a funtion on the obj.
This method is perfectly OK. This is how MFC keeps track of the CWnd objects, by creating a map of HWND's to CWnd pointers. As a matter of fact, this solution is rather elegant if you use STL maps
Code:
#include <map>
class WindowClass;
typedef std::map<HWND, WindowClass*> WndMap;
class WindowClass
{
public:
static LRESULT GlobWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
static WndMap m_ThisMap;
virtual LRESULT InstanceProc (UINT msg, WPARAM wParam, LPARAM lParam);
virtual ~WindowClass() { }
WindowClass( ) { }
void Attach( HWND h, WindowClass *pClass) { m_ThisMap[h] = pClass; }
};
class DerivedWndClass : public WindowClass
{
public:
LRESULT InstanceProc (UINT msg, WPARAM wParam, LPARAM lParam);
};
LRESULT WindowClass::GlobWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
WndMap::iterator it = m_ThisMap.find( hWnd );
if ( it != m_ThisMap.end())
{
WindowClass *pClass = it.second;
return pClass->InstanceProc( msg, wParam, lParam );
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
void CreateBasicWindow()
{
HWND h = CreateWindow( whatever );
HWND h2 = CreateWindow( whatever );
WindowClass *pClass = new WindowClass;
WindowClass *pClass2 = new DerivedWndClass;
// Attach this class to an HWND;
WindowClass::Attach(h, pClass);
WindowClass::Attach(h2, pClass2);
}
This is just a rough outline of how you would approach this method (the code has not been compiled!). There are many missing pieces, such as the destruction of the Window objects at the end of the program.
The map is contained in the window object, even though it is "global". There is a static WndProc, which will find the object and call the member function InstanceProc(). Then in InstanceProc, you do whatever you need to do, given the message, wParam, and lParam values.
There are variations of this, where the actual message functions can be function objects, all residing in a member container in each WindowClass. You do a secondary search within the window object to see if there is a message handling function for the message. If there is, you call it, otherwise you return DefWindowProc(). This is loosely similar to the BEGIN_MESSAGE_MAP type stuff that MFC does.
If you want another alternative besides the "map of handles" method, you can store the pointer to your window class within the "extra bytes" data member of each HWND. I don't know how sound this is, since you may want to map a standard Windows control (like a combo box or something), and your pointer may potentially screw up any data that Windows puts in this field for its controls. I don't know if I'm right or wrong about this, though. In any event, you still have to get the pointer and do something with it -- so either method, whether you use a map, or whether you store the pointer along with the HWND, you're going to have to write code to call your member function.
Regards,
Paul McKenzie