WndProc

Started by
8 comments, last by b1gjo3 15 years, 12 months ago
OK Everyone. I have a WinWrapper class with a static WndProc and a member Function WndProc. The Static Proc gets a long pointer to the window and uses the member function wndproc. The problem im having is capturing messages so i can exit my app when i hit the close button. Code: LRESULT CALLBACK Window::StaticProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { Window* pParent; if(message == WM_CREATE) { pParent = (Window*)((LPCREATESTRUCT)lParam)->lpCreateParams; SetWindowLongPtr(hWnd,GWL_USERDATA,(LONG_PTR)pParent); } else { pParent = (Window*)GetWindowLongPtr(hWnd,GWL_USERDATA); if(!pParent) return DefWindowProc(hWnd,message,wParam,lParam); } pParent->myHwnd = hWnd; return pParent->WndProc(message,wParam,lParam); } LRESULT Window::WndProc(UINT message, WPARAM wParam, LPARAM lParam) { //check any available messages from the queue switch (message) { case WM_KEYDOWN: switch(wParam) { //check if user hit escape key case VK_ESCAPE: PostQuitMessage(0); break; } break; //the user hit the close button case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProc(myHwnd, message, wParam, lParam); } and i have another class that is a child of class Window that overrides the wndproc.. LRESULT InputBox::WndProc(UINT message, WPARAM wParam, LPARAM lParam) { //check any available messages from the queue switch (message) { case WM_COMMAND: switch(LOWORD(wParam)) { case IBOX_CMD_CANCEL: DestroyWindow(myHwnd); break; case IBOX_CMD_OK: int length = Edit_GetTextLength(txtField->GetHWND()) + 1; if (myText != NULL) delete [] myText; myText = new char[length]; len = Edit_GetText(txtField->GetHWND(), myText, length); DestroyWindow(myHwnd); break; } break; //the user hit the close button case WM_DESTROY: DestroyWindow(myHwnd); break; } return DefWindowProc(myHwnd, message, wParam, lParam); } and the constructor of the child class has this infinte loop that will never receive WM_DESTROY (note: myHwnd is a protected member variable in Window class) MSG msg = {0}; while (WM_DESTROY != msg.message) { while(PeekMessage(&msg, myHwnd, 0, 0, PM_REMOVE) == TRUE) { TranslateMessage(&msg); DispatchMessage(&msg); } } can someone please tell me what im doing wrong. Thank you everyone
Advertisement
Try changing

while (WM_DESTROY != msg.message)

to

while (WM_QUIT != msg.message)

and see if that does it.
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
Never call DestroyWindow() in response to WM_DESTROY. DestroyWindow() sends WM_DESTROY to the window's message queue so calling DestroyWindow() when handling WM_DESTROY will cause an infinite loop
thank you for the quick reply.

I have tried changing WM_DESTROY to WM_QUIT, but my msg doesnt seem to get a message at all when i look at it while debugging.

I have also removed the case WM_DESTROY from the InputBox::WndProc

still having problems
Wow, ouch use source tags. Keep forgetting how horrible code is to read without them.

LRESULT CALLBACK Window::StaticProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){Window* pParent;if(message == WM_CREATE){pParent = (Window*)((LPCREATESTRUCT)lParam)->lpCreateParams;SetWindowLongPtr(hWnd,GWL_USERDATA,(LONG_PTR)pParent);}else{pParent = (Window*)GetWindowLongPtr(hWnd,GWL_USERDATA);if(!pParent) return DefWindowProc(hWnd,message,wParam,lParam);}pParent->myHwnd = hWnd;return pParent->WndProc(message,wParam,lParam);}LRESULT Window::WndProc(UINT message, WPARAM wParam, LPARAM lParam){//check any available messages from the queueswitch (message){case WM_KEYDOWN:switch(wParam){//check if user hit escape keycase VK_ESCAPE: PostQuitMessage(0);break;}break;//the user hit the close buttoncase WM_DESTROY:PostQuitMessage(0);break;}return DefWindowProc(myHwnd, message, wParam, lParam);}and i have another class that is a child of class Window that overrides the wndproc..LRESULT InputBox::WndProc(UINT message, WPARAM wParam, LPARAM lParam){//check any available messages from the queueswitch (message){case WM_COMMAND:switch(LOWORD(wParam)){case IBOX_CMD_CANCEL:DestroyWindow(myHwnd);break;case IBOX_CMD_OK:int length = Edit_GetTextLength(txtField->GetHWND()) + 1;if (myText != NULL)delete [] myText;myText = new char[length];len = Edit_GetText(txtField->GetHWND(), myText, length);DestroyWindow(myHwnd);break;}break;//the user hit the close buttoncase WM_DESTROY:DestroyWindow(myHwnd);break;}return DefWindowProc(myHwnd, message, wParam, lParam);}and the constructor of the child class has this infinte loop that will never receive WM_DESTROY(note: myHwnd is a protected member variable in Window class)MSG msg = {0};while (WM_DESTROY != msg.message){while(PeekMessage(&msg, myHwnd, 0, 0, PM_REMOVE) == TRUE){TranslateMessage(&msg);DispatchMessage(&msg);}}

"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin

lol went to edit my post but apparently (even though I had JUST posted) I couldn't because I wasn't logged in, hit back, logged in.. Hit edit, same dealie. Nice!

Anyways, edit your original post and actually format the code right would be great (or re-copy/paste it).

Anyways might not matter but good habit to do anyways. Read the MSDN docs on each item like WM_DESTROY it tells you what to return (0 in that case). Sometimes matters.

Also

Try:

while (msg.message != WM_QUIT)

It's what I use.

Also try debugging things Windows and Visual Studios comes with a lot of tools. MessageBox being one of the easiest to use.

"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin

i hope this helps, sorry i didnt know how to do it this way at first

//in my window wrapper classLRESULT CALLBACK Window::StaticProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){	Window* pParent; 	// Get pointer to window	if(message == WM_CREATE)	{		pParent = (Window*)((LPCREATESTRUCT)lParam)->lpCreateParams;		SetWindowLongPtr(hWnd,GWL_USERDATA,(LONG_PTR)pParent);	}	else	{		pParent = (Window*)GetWindowLongPtr(hWnd,GWL_USERDATA);		if(!pParent) return DefWindowProc(hWnd,message,wParam,lParam);	}	//Call the non-static window proc	pParent->myHwnd = hWnd;	return pParent->WndProc(message,wParam,lParam);}LRESULT Window::WndProc(UINT message, WPARAM wParam, LPARAM lParam){	//check any available messages from the queue	switch (message)	{		case WM_KEYDOWN:			switch(wParam)			{				//check if user hit escape key				case VK_ESCAPE: PostQuitMessage(0); 				break;			}			break;                    		//the user hit the close button		case WM_DESTROY:			PostQuitMessage(0);			break;	}	return DefWindowProc(myHwnd, message, wParam, lParam);}//where im trying to solve whats wrongLRESULT InputBox::WndProc(UINT message, WPARAM wParam, LPARAM lParam){	//check any available messages from the queue	switch (message)	{		case WM_COMMAND:			switch(LOWORD(wParam))			{				case IBOX_CMD_CANCEL:					DestroyWindow(myHwnd);					break;				case IBOX_CMD_OK:					int length = Edit_GetTextLength(txtField->GetHWND()) + 1;					if (myText != NULL)						delete [] myText;					myText = new char[length];					len = Edit_GetText(txtField->GetHWND(), myText, length);					DestroyWindow(myHwnd);					break;			}			break;	}	return DefWindowProc(myHwnd, message, wParam, lParam);}InputBox::InputBox(HWND parent, LPCSTR title, LPCSTR message, LPCSTR defaultText):Window(title, 350, 120){	myParent = parent;	myText = NULL;	EnableWindow(myParent, false);	SetForegroundWindow(myHwnd);	SetWindowStyle(WS_CAPTION | WS_SYSMENU | WS_POPUP);	SetWindowExStyle(WS_EX_TOOLWINDOW);	InitWindow();	lblMessage = new Label(myHwnd, this->GetINST(), message, 12, 9, 180, 13, IBOX_LBL_FIELD);	txtField = new TextBox(myHwnd, this->GetINST(), defaultText, 12, 88, 323, 20, IBOX_TXT_FIELD);	cmdCancel = new CmdButton(myHwnd, this->GetINST(), "Cancel", 280, 39, 55, 23, IBOX_CMD_CANCEL);	cmdOk = new CmdButton(myHwnd, this->GetINST(), "OK", 280, 9, 55, 23, IBOX_CMD_OK);	SetFocus(txtField->GetHWND());	Edit_SetSel(txtField->GetHWND(), 0, Edit_GetTextLength(txtField->GetHWND()));	MSG msg = {0};	while (WM_QUIT != msg.message)	{		while(PeekMessage(&msg, myHwnd, 0, 0, PM_REMOVE) == TRUE)		{			TranslateMessage(&msg);			DispatchMessage(&msg);		}	}	EnableWindow(myParent, true);	SetForegroundWindow(myHwnd);}
Ok so right now the problem is that InputBox::WndProc() isnt being called? Is Window::WndProc() a virtual function? If not, it should be.
Instead of this
PeekMessage(&msg, myHwnd, 0, 0, PM_REMOVE)
I use
PeekMessage(&msg, 0, 0, 0, PM_REMOVE)
I remember it caused problems when i specified the HWND of the window.You may try that too maybe it helps.

yes they are virtual functions, and i will try later today to not specify the HWND, thanks

--

setting hwnd to null doesnt fix it either. im completely stumped. Even when i insert DestroyWindow(myHwnd) inside of the while loop, it still wont get the message

[Edited by - b1gjo3 on April 22, 2008 10:08:25 AM]

This topic is closed to new replies.

Advertisement