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
Try changing
while (WM_DESTROY != msg.message)
to
while (WM_QUIT != msg.message)
and see if that does it.
while (WM_DESTROY != msg.message)
to
while (WM_QUIT != msg.message)
and see if that does it.
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
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);}}
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.
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.
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.
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]
--
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
Popular Topics
Advertisement