Sign in to follow this  
gamedream

Window Proc Problem

Recommended Posts

gamedream    122
When I read the sample source code from Microsoft I can see that: static CD3DApplication* g_pD3DApp = NULL; LRESULT CALLBACK WndProc(HWND hWND, UNIT uMSG, WPARAM wParam, LPARAM lParam) { return g_pD3DApp->MSgProc(hWnd, uMsg, wParam, lParam) }; ... CD3DApplication::Create(HINSTANCE hInstance) { .... WNDCLASS wndClass= {0, WndProc, 0, 0, hInstance, NULL, NULL, NULL, NULL, "WINDOWCLASS"}; } Actually, when we want to use the OO method to develop our game, the MsgProc will write on the Object like CD3DApplication. Therefore, the Pointer of WindowProc in the WNDCLASS should point to MsgProc, not point to WndProc. This is make me so confuse? and I don't know why the sample will create another variable "static CD3DApplication* g_pD3DApp" and called it from the WindProc I hope you can know what I mean? Please tell me more detail that why the sample do that. Thank you

Share this post


Link to post
Share on other sites
Structural    328
So, if I understand correctly you want the events to call CD3DApplication::MsgProc. You can't do this directly. You can not let the message callback call member functions. This is quite crap, I agree.

There is no real neat manner of getting around this. I have been puzzling to do this in a neat OO manner too, yet I have not found one.

At this moment I use a central EventHandler that defines an extern WndProc function. All messages are first relayed through the messagehandler, and then passed on to specialised handler.


OpenGLWindow : public Eventhandler
{
long processEvent(int source, unsigned int msg, int p1, long p2);
};

OpenGLWindow::OpenGLWindow()
{
EventManager::INSTANCE()->registerHandler(this, WM_CLOSE);
EventManager::INSTANCE()->registerHandler(this, WM_ACTIVATE);
EventManager::INSTANCE()->registerHandler(this, WM_ACTIVATEAPP);
EventManager::INSTANCE()->registerHandler(this, WM_SYSCOMMAND);
EventManager::INSTANCE()->registerHandler(this, WM_SIZE);
EventManager::INSTANCE()->registerHandler(this, WM_WINDOWPOSCHANGED);
}

long OpenGLWindow::processEvent(int source, unsigned int msg, int p1, long p2)
{
switch(msg)
{
case WM_CLOSE:
// ... etc etc
}
}





// EVENTHANDLER.H

extern LRESULT CALLBACK WndProc( HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam);





/ EVENTHANDLER.CPP

LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window
UINT uMsg, // Message For This Window
WPARAM wParam, // Additional Message Information
LPARAM lParam) // Additional Message Information
{
return EventManager::INSTANCE()->processEvent((int)hWnd, uMsg, wParam, lParam);
}




It is very difficult to use a pure OO method when working with callbacks. You might want to look into the topic of "Functors" which allow such constructions, but they are not always easy/intuitive to use.
For Windows callbacks you will always need a global or static function.

Share this post


Link to post
Share on other sites
Wavarian    850
..Well you could of course try this:


void CWindow::Create() {

HINSTANCE hInst = (HINSTANCE)GetModuleHandle(NULL);
...(WNDPROC)WndProc;
m_hWnd = CreateWindowEx(...,this);
}

LRESULT CWindow::MsgProc(...) {

return DefWindowProc(...);
}

static LRESULT CALLBACK CWindow::WndProc(...) {

if(msg == WM_NCCREATE) {

LPCREATESTRUCT cs = (LPCREATESTRUCT)lParam;
SetWindowLong(hWnd,GWL_USERDATA,(LONG)cs->lpCreateParams);
}

return ((CWindow *)GetWindowLong(hWnd,GWL_USERDATA))->MsgProc(...);
}





Naturally you'd have to fix a few things to make it work.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this