Skip to main content
GameDev.net gamedev.net
🔒 Locked

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

Started by Red Ant Nov 16, 2001 at 9:44 PM 10 replies 4.7k views
Original Post
Red Ant
Red Ant
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.
ECKILLER
ECKILLER
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
ECKILLER
Red Ant
Red Ant
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?
Oluseyi
Oluseyi
quote:
Original post by Red Ant
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?

Read the post before yours... carefully.
Red Ant
Red Ant
Sorry, I must have read that post for the 20th time now but I still don''t know how to do it. Help me!
Oluseyi
Oluseyi
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?
Oluseyi
Oluseyi
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.
Oluseyi
Oluseyi
Found it. Use cbWndExtra to specify how much extra memory, in bytes, is required per window (in this case 4 bytes to store the this pointer). Then use SetWindowLong() and GetWindowLong() to commit/retrieve the data.

Cool.
Red Ant
Red Ant
Okay, I think I got it now. Thanks a bunch for helping me, guys!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.