Archived

This topic is now archived and is closed to further replies.

Red Ant

How do I turn my message procedure into a member function of a class?

Recommended Posts

Hi there, As of now my Win32 application isn''t very OOP yet. I wanna change that but I can''t seem to figure out what I have to do to actually make my message procedure into a member function. Can somebody maybe give me a pointer to a tutorial or something? Thanks in advance.

Share this post


Link to post
Share on other sites
The problem you have if you make it static is that you only have one window procedure for many window instantiations. However, you must give a global or static method to the WNDCLASS argument. So what you do is make a static window procedure that acts as a message router. This static procedure maps the message to the appropriate C++ window object.

static int WndProcRouter(HWND hwnd, ...etc)

Now the problem is that in the static wndproc you don''t have the C++ object that the message was directed to. BUT we do have the HWND. We need a method that given the HWND as an argument returns us the corresponding C++ window object. We want something like:

Window* win = GetWindowObject(hwnd);

Then we can write:

win->msgProc(...);

There are several ways to associate a c++ window object with a HWND. We can keep a static data structure that stores the HWND and a ptr to its corresponding C++ object. Then procide an interface that searches the data structure for a particular HWND and returns the Window object.

During creation:

dataStructure.AddWindow(_hwnd, this);

then:

Window* GetWindowObject(HWND hwnd)
{
Window* win = dataStructure.get(hwnd);

win->msgProc(...);
}





ECKILLER

Share this post


Link to post
Share on other sites
Thanks for your help. However, if I make my WndProc static then how can I call any other methods (which are non-static) from within the window procedure?

Share this post


Link to post
Share on other sites
ECKILLER suggest associating window handles with object pointers in some way (say, through a static table). A message router defined as
LRESULT WINAPI WndProcRouter(HWND hwnd, ...); 

is then specified as the window procedure for every window of the class (or even of the entire application). This handler will then call a function of the form
window * GetWindow(HWND hwnd); 

provided by yourself (where window is the name of your class that encapsulates windows), which (the function) looks up the object pointer in the table described above.

The message router will now call the WindowProc function of the returned object:
window *win = NULL;
win = GetWindow(hwnd);
if(!win)
throw "failed to obtain window object";
win->WindowProc(hwnd, umsg,...);

A very elegant solution he has detailed more than once on these fora. Any further questions, why not email him?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
The best way to do this is to allocate extra storage in the window class, 4 bytes, to store the "this" pointer... pass this along when you do OpenWindowEx().

Then, have a standard procedure as your default message handler for your window class that retrieves this "this" pointer, and calls your own message procedure member function.

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
The best way to do this is to allocate extra storage in the window class, 4 bytes, to store the "this" pointer... pass this along when you do OpenWindowEx().

Then, have a standard procedure as your default message handler for your window class that retrieves this "this" pointer, and calls your own message procedure member function.


Exactly. I was trying to find the specifics on doing so. I know that the extra data is requested/reserved via cbClsExtra and/or cbWndExtra, but I don''t know where to place the pointer itself. If you would post some specifics, I''d be much obliged.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Once you''ve got win->msgProc(...); all the members of win are exposed to the msgProc - pdc imo.

Share this post


Link to post
Share on other sites