Sign in to follow this  
b1gjo3

WndProc

Recommended Posts

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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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 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);
}
}

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
i hope this helps, sorry i didnt know how to do it this way at first


//in my window wrapper class
LRESULT 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 wrong
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;
}

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);
}

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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]

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