Advertisement

Message Handler can be Wrapped?

Started by July 04, 2001 04:51 PM
1 comment, last by Prozak 23 years, 7 months ago
Hi all, i''ve been trying to wrap the message handler, in my win32 app (vc++6), but this type of function seems darn hard to wrap. Hows ya do it? I''ll be smaking mi head off till someone gives me thi answer, arrgg... bye mate, Hugo Ferreira UniteK Future
theres a few ways to do it... they way im doing it in my current project is this...

here is a cutdown version of my base window class.

  class Window  {public:	Window(LPCSTR title, int width, int height);	virtual ~Window();protected:	HWND _window;	LPCSTR _caption;	LPCSTR _RegisterClass(LPCSTR className);	HWND _CreateWindow(LPCSTR className, int width, int height, DWORD style);	//friend functions	friend LRESULT CALLBACK MsgHandler(HWND win,UINT message, WPARAM wParam, LPARAM lParam);		//message handlers	virtual bool OnCreate(CREATESTRUCT const * create) {return 0;}	virtual bool OnDestroy() {::PostQuitMessage(0); return 0;}	virtual bool OnClose() {return false;}	virtual bool OnCommand (int cmdId, bool isAccel) {return false;}	virtual bool OnLButtonDown (int x, int y, DWORD keyState) {return 0;}	};  

when i create the window i pass with it the this pointer, which is basically a pointer to the Window.
  HWND Window::_CreateWindow(LPCSTR className, int width, int height, DWORD style){	HWND hWnd;	hWnd = CreateWindowEx(0, className, _caption, style, 0, 0, width, height, NULL,		                  NULL, ::GetModuleHandle(NULL), this);	return hWnd;}  

the window procedure(MsgHandler) code is like this...
the this pointer is retrieved when WM_NCCREATE is called and stored in the GWL_USERDATA section of the window.
then each time the handler is called it retrieves the pointer and casts it to a Window*.. then you call various funtions corrsponding to the messages.

  LRESULT CALLBACK MsgHandler(HWND win,UINT message, WPARAM wParam, LPARAM lParam){	Window *pWin = reinterpret_cast<Window*>(GetWindowLong(win, GWL_USERDATA));	switch(message)	{	case WM_NCCREATE:		{			LPCREATESTRUCT create = reinterpret_cast<LPCREATESTRUCT>(lParam);			pWin = static_cast<Window*>(create->lpCreateParams);			SetWindowLong(win, GWL_USERDATA, (LONG)pWin);			return TRUE;		}break;	case WM_CREATE:		{			return pWin->OnCreate(reinterpret_cast<CREATESTRUCT*>(lParam));					}break;	case WM_DESTROY:		{			pWin->OnDestroy();			return 0;		}break;	case WM_LBUTTONDOWN:		{			pWin->OnLButtonDown((int)LOWORD(lParam), (int)HIWORD(lParam), (DWORD)wParam);				return 0;		}break;	}//end switch		//default processing	return DefWindowProc(win, message, wParam, lParam);}  

when you derive from this class and want to handle new messages you need to create a new window procedure and subclass your window. in the new window procedure you can cast the pointer to that of a pointer to the derived class. make sure that the new message handler calls the previous one for any unhandled messages.. just like you call DefWindowProc in the one above.

you can probably a better version/explanation at http://www.relisoft.com
Advertisement
along mostly the same line, but a little more flexible....

i use a static member function for the message handler, and it does much the same thing, as far as associating a HWND with an event handler class instance during WM_NCCREATE. however, that is the only message that it directly handles. for all other messages, it pulls out the pointer to the event handling class, and sends the message to the event handler''s HandleEvent function, thus acting mostly like a dispatcher. if the event handler doesnt handle the message, it passes the message along to DefWindowProc.

the event handler''s HandleEvent function (a virtual function) is the one that routes the message to the specific handler. because the routing is done by the event handler object and not by the message handling procedure, more messages can be added in derived classes without requiring any modification to the message dispatching function.

Get off my lawn!

This topic is closed to new replies.

Advertisement