Pointer to member function

Started by
21 comments, last by iMalc 14 years, 5 months ago
Urgh! Im writing a general window class which goal is to hide the WIN32/WINAPI and at the same time offer OpenGL support for the window. So instead of creating a application full of WNDCLASSEX, HWND, HDC, HGLRC stuff, I made a cake and baked those things inside it. But as you know, all window handles need a window class, and this window class need a window procedure! Say that I want this procedure to be a member of my window class, like this (and alot more of course):

class Window
{
    private:

        ...
        static WNDCLASSEX m_wc;
        ...

    public:

        ...
        bool create(int, int);
        LRESULT CALLBACK wndProcedure(HWND, UINT, WPARAM, LPARAM);
        ...
};
Now in the 'Window::create' method, we specifies the WNDCLASSEX member:

        ...
        m_wc.lpfnWndProc = &Window::wndProcedure;
        ...
But this will produce the following error: window.cpp:13: error: cannot convert `LRESULT (Window::*)(HWND__*, UINT, WP ARAM, LPARAM)' to `LRESULT (*)(HWND__*, UINT, WPARAM, LPARAM)' in assignment How should I do to solve this???
Advertisement
You can get around this by using a static member function, but then of course you are limited by only being able to create one object of that type.

Either that or come up with a mechanism for forwarding events to the right object.

It kind of seems like you'd only need one of those guys ever though if it contains your wndproc.

anyhow, make it static and it'll work (:

the reason why is because member functions secretly have a "this" parameter as the first parameter passed to the function.

That's why function pointers can't point at them so easily.

Static member functions don't take the "this" pointer though so work just fine.
See here for why that doesn't work and here to make it work.
Actually, the situation becomes more complex when you say so. I do not want to have it static, this because of the following point:

If I do so, the WndProc will have no idea which Window we are operating on, so why would this be necessary? Well the Window class also have a pollEvents method, this takes care of user input, from mouse and keyboard. It gets all that information from the message queue of the HWND. But one message that does not get into that queue is WM_SIZE, but it does get into the WndProc.

Well we could solve it like this (from inside our static WndProc), we send a message with this information to the message queue:
    ...    case WM_SIZE:        PostMessage(hwnd, msg, wparam, lparam);        break;    ...

Great! The only error is that our message queue gets totally screwed up, we need to directly examine the queue after sending this message, that is done by the pollEvents method, but wait we do not know about the Window because the WndProc is STATIC!!!!

rip-off's second link shows you how to hook up a static WndProc to the member version WndProc.

As for your other problem, you should never need to call PeekMessage/GetMessage and pass in a hwnd filter (in fact, you should probably avoid filtering messages entirely because there are just too many special cases - any message that is sent to your window (as opposed to being posted) - WM_SIZE is one that you've already found, but there are many examples - will bypass your message queue and go straight to your WndProc).

As I mentioned, rip-off's second link shows you how to do what you want to do.
Yep, thats what i was talking about too.

Why you need multiple windows btw?

Most applications have a single wndproc why is yours different?
Yeah, I guess I will solve it with a static member that points to the created Window class and uses that one in the WndProc in order to run: "m_createdWindow -> pollEvents()"
You don't need a singleton. Read the second link rip-off gave you.
I solved it by using a reinterpret cast from hwnd to my Window class
Quote:Original post by rikardo
I solved it by using a reinterpret cast from hwnd to my Window class


That sounds suspiciously dangerous. Can you show us the code?

This topic is closed to new replies.

Advertisement