Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Closing multiple custom windows?

SephirothSephiroth Fayetteville, NC, USAMember Posts: 1,035
Alright, I am creating two windows of my own class, one being the child of the other, each with a seperate window process function. When I create only the main window (the parent) everything runs fine, but if the child is present and I close the application, the windows close and disappear, but the process never fully exits and sucks down CPU. I am going to post the basic code here to show off how I am doing this.
[code]
/* -------- Parent window procedure -------- */
LRESULT CALLBACK ETWindow::ProcessMessage(HWND hwndWindow, UINT uiMessage, WPARAM wpCode, LPARAM lpCode)
{
switch(uiMessage)
{
case WM_CLOSE:
DestroyWindow(hwndWindow);
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;

case WM_COMMAND:
switch(LOWORD(wpCode))
{
case IDM_FILE_NEW:
return 0;

case IDM_FILE_SAVE:
return 0;

case IDM_FILE_SAVEAS:
return 0;

case IDM_FILE_EXIT:
SendMessage(hwndWindow, WM_CLOSE, 0, 0);
return 0;
}
break;
}

return DefWindowProc(hwndWindow, uiMessage, wpCode, lpCode);
}



/* -------- Child window procedure -------- */
LRESULT CALLBACK ETViewport::ProcessMessage(HWND hwndWindow, UINT uiMessage, WPARAM wpCode, LPARAM lpCode)
{
switch(uiMessage)
{
case WM_CREATE:
MessageBox(hwndWindow, "View: Create", "Debug", MB_OK);
break;

case WM_PAINT:
Render();
return 0;

case WM_CLOSE:
MessageBox(hwndWindow, "View: Close", "Debug", MB_OK);
DestroyWindow(hwndWindow);
return 0;

case WM_DESTROY:
MessageBox(hwndWindow, "View: Destroy", "Debug", MB_OK);
PostQuitMessage(0);
return 0;
}

return DefWindowProc(hwndWindow, uiMessage, wpCode, lpCode);
}
[/code]
Can anybody spot anything wrong here? I am posting quit messages in both windows as you can see, but something is not working. I get the child window messagebox that tells me the window is created, but when I close the parent window I hear the windows sound of a messagebox popping up, but never see one. Thanks for any help you can offer!

-[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/green][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h[/red][/b][/italic]

Comments

  • AsmGuru62AsmGuru62 Member Posts: 6,519
    [color=Blue]
    WM_CLOSE is basically serviced by DefWindowProc(), so you do not need to to do any processing (DefWindowProc() calls DestroyWindow() for you). Unless, you want to perform any UI, like asking User to save files, etc. - you do not need the "case WM_CLOSE".

    Also, why PostQuitMessage() in child procedure? This should be only in the parent (main) application window. Do you want to close the whole thing, when child is closed? If you do then post (not send) a WM_CLOSE message to parent. Also, post it in case of IDM_FILE_EXIT - I see you sending it - it will call directly your window procedure and destroy your window before all messages are processed fully - that is why post (not send) is needed.
    [/color]
  • SephirothSephiroth Fayetteville, NC, USAMember Posts: 1,035
    I made the suggested changes and still nothing. The child window is somehow preventing the entire application from closing. I have removed handling of everything except WM_PAINT from the child callback, and when my menu IDM_FILE_EXIT is recieved, it now posts the message instead of sending it. Perhaps the problem is with my main loop that processes messages for the two windows?
    [code]
    //The main program loop
    while((pWindow->Handle() != NULL) || (pViewport->Handle() != NULL))
    {
    if(PeekMessage(&msgWindow, pWindow->Handle(), 0, 0, PM_REMOVE) > 0)
    {
    TranslateMessage(&msgWindow);
    DispatchMessage(&msgWindow);
    }

    if(PeekMessage(&msgViewport, pViewport->Handle(), 0, 0, PM_REMOVE) > 0)
    {
    TranslateMessage(&msgViewport);
    DispatchMessage(&msgViewport);
    }
    }
    [/code]
    This loops until both window handles are gone due to being destroyed. Remember, I created each window (parent and child) with my own class using WNDCLASSEX and each one has a seperate callback.The parent window seems to function perfectly, but the child window does not process anything. Ideas?

    I also believe that it should NOT be this hard to deal with child windows. The MSDN has been almost completely useless in helping me figure out how to tell a child window message from a parent window message, which is why I am now creating my own window classes just so they can have their own callback functions, but this isn't working either. Is there a tutorial ANYWHERE online that actually shows how to deal with child windows? All I can find are basic things like "how to make a button" or other such primitive subjects. I can make child windows all day, but I want their messages to go to their own procedures, NOT the parent!

    -[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/green][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h[/red][/b][/italic]
  • AsmGuru62AsmGuru62 Member Posts: 6,519
    [color=Blue]
    Your message loop is way too complicated. It should look like this: (no matter how many window instances in your program)
    [/color]

    [color=Black]
    [code]
    while (GetMessage (&message, NULL, 0, 0))
    {
    TranslateMessage (&message);
    DispatchMessage (&message);

    // To use Accelerators and modeless
    // dialogs you need more code here ^^^...
    }
    [/code]
    [/color]

    [color=Blue]
    Also, you should know that destroying the parent window will cause destroying of all child windows as well. Windows does it automatically.
    [/color]
  • SephirothSephiroth Fayetteville, NC, USAMember Posts: 1,035
    Yeah I went back to only using my primary window as a custom class, and everythign appears to work. Now what I need to do is figure out what child window messages are sent from and handle them seperately. After a week of searching the MSDN, I think I need to use "EnumChildWindows()", but I am not sure exactly how. Here is my theory, which will capture and handle mouse-clicks in ONLY one child window. Correct me if I am wrong.
    [code]
    //Parent window callback
    LRESULT CALLBACK MainCalls(HWND hwndWindow, UINT uiMessage, WPARAM wpCode, LPARAM lpCode)
    {
    switch(uiMessage)
    {
    ...
    case WM_LBUTTONDOWN:
    EnumChildWindows(hwndParent, ClickFunction, lpCode);
    break;
    ...
    }

    return DefWindowProc(...);
    }

    //Code to handle clicks from the one specific window ONLY
    void CALLBACK ClickFunction(HWND hwndHandle, LPARAM lpCode)
    {
    //hwndViewport is the handle to the ONLY window I want to handle clicks for
    if(hwndHandle != hwndViewport)
    return;

    ...
    }
    [/code]
    I am assuming that the main window sends all the child window handles, one at a time, to this function along with the LPARAM of the main window callback. This function should then retun automatically for every window except the oen I want to deal with, correct?

    -[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/green][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h[/red][/b][/italic]
Sign In or Register to comment.