Archived

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

crazemanx

Class member as window callback function???

Recommended Posts

Is it possible to set a member function of a class object as the message callback function for a window? I have tried simply setting my WINCLASS''s lpfnWndProc = myobject.mycallbackfunction but my compiler strenuously objects to this. Nick

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
No, that is not posible. What you have to do is have a static structure\class that has the callback. Say that your class is this:
class CWtf
{
public:
LRESULT WndProc(...);
CWtf();
virtual ~CWtf();
}
... k, so thats your class ...
then in the source file whare you create the window:
CWtf* g_pWtf = NULL; // thats the global

/* Now (this is important), this is going to be the proc that you put in WC when creating the window. */
LRESULT WndProcDummy(...)
{
return g_pWtf->WndProc(...);
}


/* In the class constructor, the g_pWtf has to be created */
CWtf::CWtf()
{
g_pWtf = this; // Very important !!!
...
}

Now you can use WndProcDummy as your window proc. Without any errors. Hope that helped

AfTeRmAtH

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
No, that is not posible. What you have to do is have a static structure\class that has the callback.

Wrong.

class MyClassThatHasItsOwnWndProc
{
public:
// class stuff
//
static WNDPROC WndProc;
HRESULT InitializeWindow(HINSTANCE hinst, HWND &hwnd);
//
private:
// private stuff
};
//
WNDPROC MyClassThatHasItsOwnWndProc::WndProc = NULL;
//
HRESULT MyClassThatHasItsOwnWndProc::InitializeWindow(HINSTANCE hinst, HWND &hwnd)
{
WNDCLASSEX wc;
// initialize wc fields
//...
wc.WndProc = WndProc; // assign window handler
//...
if(!RegisterClassEx(&wc))
result false;
// rest of window initialization
return true;
}

Share this post


Link to post
Share on other sites
Personally, I allocate sizeof(Window*) bytes of per-window data when I call RegisterClass. Then when I create the window, in the Window constructor I do a SetWindowLong(hWnd, 0, (long) this) . In the WndProc (which I define as a static top-level function), I use Window *window = (Window *) GetWindowLong(hWnd, 0) . Later in the WndProc, I call window->windowProc(hWnd, uMsg, wParam, lParam) .

That's better than storing the Window in a global, because then you can have multiple instances of the window.

Signatures? We don't need no steenking signatures!

PS. Using RegisterClass for each window is valid, but bare in mind that on 95-based systems, there is limit to how many window classes can be registered - and thus how many windows you can have. Although your program is unlikely to fail unless it creates thousands of windows (which is asking for trouble anyway), it's probably good practice to use up as few system resources as possible.

Edited by - Mayrel on October 31, 2001 9:11:31 AM

Share this post


Link to post
Share on other sites
Mayrel: That is an interesting idea. I usually store the class pointers in a global std::map (sort of like MFC does). But GetWindowLong should be faster than searching a map(?). Any idea how Windows stores the extra bytes for the window class?

Share this post


Link to post
Share on other sites
GetWindowLong ought to be faster than a map. The longs you store are kept in the same bit of memory that Windows allocates for the style, extended style, and a few other bits and pieces, which will be referenced by the internal window array. At least, I assume all the handles are kept in an array, so finding the GetWindowLong should just be a matter of something like:
  
long WINAPI GetWindowLong(HWND hWnd, long offset) {
WINDOW *win;
// Is it a window?

if (handles[hWnd].type != HT_WINDOW)
return NULL;
win = (WINDOW*) handles[hWnd].object;
// Is there that much window data?

if (win->dataLength < offset + sizeof(long))
return NULL;
// Return the long.

return (long*)(win->data)[offset];
}

Assuming it''s like that, a lookup with GetWindowLong should complete in constant time, whilst a lookup in a map will take longer as more windows are added, although it''ll never take a really long time.

Signatures? We don''t need no steenking signatures!

Share this post


Link to post
Share on other sites