win32/c++ modeless dialog hides main window behind other apps on close

I have a modeless dialog (referred to as Toolbar) with a close control and two buttons that each open their own messagebox. If I open the toolbar, press a button, close the resulting messagebox, and then close the toolbar, the main window of my application disappears behind any other open applications.

I don't know why it's happening, but I tried fixing it with SetFocus and SetActiveWindow, as per various vaguely similar questions found via google; but I'm not sure how to point to the main window; or if either function can be used this way.

Does anyone here know a simple solution to this issue? Is there something specific in my code that's causing it?

main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include <windows.h>
#include "resource.h"

//g_ = global
//sz_ = string zero I guess?

//forward declare toolbar id
HWND g_hToolbar = NULL;

//Register Window Class
const char g_sz_myClass [] = "window1";

//Toolbar Process >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
LRESULT CALLBACK ToolDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_COMMAND:
        {
            switch(LOWORD(wParam))
            {
                case IDC_PRESS:
                    MessageBox(hwnd, "This does nothing.", "NULL", MB_OK | MB_ICONINFORMATION);
                break;
                case IDC_OTHER:
                    MessageBox(hwnd, "This also does nothing", "NULL", MB_OK | MB_ICONINFORMATION);
                break;
            }
        break;
        }
        case WM_CLOSE:{
            ShowWindow(g_hToolbar, SW_HIDE);
            //I tried SetActiveWindow and SetFocus here, with no result.
        break;
        }
        default:
            return FALSE;
    }
    return TRUE;
}
//Toolbar Process <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

//Main Window Process >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_COMMAND:{
            switch(LOWORD(wParam)){
                // MenuBar Command >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                case ID_FILE_EXIT:{
                    PostMessage(hwnd, WM_CLOSE, 0, 0);
                break;
                }
                //MenuBar Command <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

                //Toolbar Command >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                case ID_TOOLBAR_ON:
                    if(g_hToolbar == NULL){
                        g_hToolbar = CreateDialog(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_TOOLBAR), hwnd, ToolDlgProc);
                        ShowWindow(g_hToolbar, SW_SHOW);
                    }
                    else{
                        ShowWindow(g_hToolbar, SW_SHOW);
                    }
                break;
                case ID_TOOLBAR_OFF:
                    ShowWindow(g_hToolbar, SW_HIDE);
                break;
                //Toolbar Command <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            }
        break;
        }

        //Close Command >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        case WM_CLOSE:{
                DestroyWindow(hwnd);
            break;
            case WM_DESTROY:
                DestroyWindow(g_hToolbar);
                PostQuitMessage (0);
            break;
        break;
        }
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
        }
        //Close Command <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    return 0;
}
//Main Window Process <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

//Main Window Register >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int CmdShow)
{
    WNDCLASSEX test;
    HWND hwnd;
    MSG msg;

    test.cbSize = sizeof (WNDCLASSEX);
    test.style = 0;
    test.lpfnWndProc = WndProc;
    test.cbClsExtra = 0;
    test.cbWndExtra = 0;
    test.hInstance = hInstance;
    test.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    test.hCursor = LoadCursor(NULL, IDC_ARROW);
    test.hbrBackground = CreateSolidBrush(RGB(24, 15, 56));
    test.lpszMenuName = MAKEINTRESOURCE(IDR_MENUBAR);
    test.lpszClassName = g_sz_myClass;
    test.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    if(!RegisterClassEx(&test))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }
    //Create Window >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    hwnd = CreateWindowEx(
    WS_EX_CLIENTEDGE,
    g_sz_myClass,
    "myWindowName",
    WS_OVERLAPPEDWINDOW,
    15, 15, 1200, 700,
    NULL, NULL, hInstance, NULL);

    if(hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }
    // Create Window <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

    ShowWindow(hwnd, CmdShow);
    UpdateWindow(hwnd);

    while(GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
//Main Window Register <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 


resource.h
1
2
3
4
5
6
7
8
9
#define IDR_MENUBAR 10
#define IDD_TOOLBAR 11

#define ID_FILE_EXIT 12
#define IDC_PRESS 13
#define IDC_OTHER 14
#define ID_TOOLBAR_ON 15
#define ID_TOOLBAR_OFF 16


resources.rc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <windows.h>
#include "resource.h"


IDR_MENUBAR MENU {
    POPUP "File"
    {
        MENUITEM "Exit", ID_FILE_EXIT
    }
    POPUP "Toolbar"
    {
        MENUITEM "On", ID_TOOLBAR_ON
        MENUITEM "Off", ID_TOOLBAR_OFF
    }
}

IDD_TOOLBAR DIALOGEX 665, 10, 100, 60
STYLE DS_MODALFRAME | WS_SYSMENU | WS_CAPTION
EXSTYLE WS_EX_TOOLWINDOW
CAPTION "Toolbar"
FONT 8, "MS Sans Serif"
{
    PUSHBUTTON "Press This Button",IDC_PRESS,10,5,80,20
    PUSHBUTTON "Or This One",IDC_OTHER,10,30,80,20
}



(also, am I including too much code? I'm not sure what and how much should cut off. I've already removed anything superfluous. And I don't know if this is a beginner or intermediate question. I don't know what I'm doing so I consider myself a beginner. I'm also not sure if there's a better place to ask win32/winapi related questions).
Last edited on
I found a sort of workaround, but it only works if I open a messagebox when the toolbar is closed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//Toolbar Process >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
LRESULT CALLBACK ToolDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_COMMAND:
        {
            switch(LOWORD(wParam))
            {
                case IDC_PRESS:
                    MessageBox(hwnd, "This does nothing.", "NULL", MB_OK | MB_ICONINFORMATION);
                break;
                case IDC_OTHER:
                    MessageBox(hwnd, "This also does nothing", "NULL", MB_OK | MB_ICONINFORMATION);
                break;
            }
        break;
        }
        case WM_CLOSE:{
            ShowWindow(g_hToolbar, SW_HIDE);
            PostMessage(hwnd, WM_FOCUS, 0, 0);
        break;
        }
        case WM_FOCUS:{
                    //SetForegroundWindow(hwnd);
                    //^ worthless
                    MessageBox(hwnd, "Toolbox closed", "close", MB_OK | MB_ICONINFORMATION);
                break;
        }
        default:
            return FALSE;
    }
    return TRUE;
}


resource.h
1
2
3
4
5
6
7
8
9
10
11

#define IDR_MENUBAR 10
#define IDD_TOOLBAR 11

#define ID_FILE_EXIT 12
#define IDC_PRESS 13
#define IDC_OTHER 14
#define ID_TOOLBAR_ON 15
#define ID_TOOLBAR_OFF 16

#define WM_FOCUS (WM_USER + 0x0001) 


This doesn't work with if I replace

1
2
3
4
case WM_CLOSE:{
            ShowWindow(g_hToolbar, SW_HIDE);
            PostMessage(hwnd, WM_FOCUS, 0, 0);
        break;


with

1
2
3
4
case WM_CLOSE:{
            DestroyWindow(g_hToolbar);
            PostMessage(hwnd, WM_FOCUS, 0, 0);
        break;
Last edited on
This is very much a Windows-specific thing, so maybe you'd have more luck asking in the Windows Programming forum?
Huh, don't know how I missed that. Thanks.
Try the message loop in WinMain from this tutorial and also the dialog styles.
http://www.winprog.org/tutorial/modeless_dialogs.html
@Thomas that's the tutorial I'm learning from (or an excerpt from it). The Forgers WinAPI Tutorial. I didn't include the message loop in my code here, but I've tried the code with and without the updated message loop with the same result.

I did find a solution though. You can read it here:

http://www.cplusplus.com/forum/windows/240346/
Topic archived. No new replies allowed.