Take the 2-minute tour ×

I'm creating my app window in code and I'm trying to show a message box as soon as the window exists. But I can't. I see only the newly created window, no msg box. If I quit the app by closing its window, the msg box suddenly appears, as if it were waiting in some queue, to be shown only when the app window is closed. Does the way I create the window somehow block modal msg boxes? Note: the MessageBox line is there just for testing. I'll take it out for normal use, as it would obviously interfere with the GetMessage loop.

//start relevant section of WinMain:
WNDCLASS wc={0};
wc.lpfnWndProc = WindowProc;
if (!RegisterClass(&wc) || !CreateWindow("mc", "mc", WS_POPUPWINDOW|WS_CAPTION|WS_VISIBLE, 100, 50, 100, 100, NULL, NULL, hInstance, NULL)) {
  Error("Can't create window");
  return 0;
ShowWindow(win, SW_SHOWNORMAL);
MessageBox(0, "Test", 0 ,0);
//end relevant section of WinMain

long FAR PASCAL WindowProc(HWND h, UINT m, WPARAM wParam, LPARAM l)
    switch (m) {
        //process other messages
        case WM_CREATE:
            //init stuff, paint something in the main window
    return DefWindowProc(h, m, wParam, l);
share|improve this question
Saving the return value of CreateWindow would be better than using a global variable. –  Ben Voigt Nov 11 '10 at 22:56
I changed the "!CreateWindow..." part to "!(win=CreateWindow...)" and removed "win=h" from WM_CREATE. No change in behavior: still no msg box. –  MrSparkly Nov 12 '10 at 1:28
You are not posting your full WindowProc, or some other piece of code is missing. MessageBox contains a near identical GetMessage loop so it should not matter. –  Chris Becke Nov 12 '10 at 15:17
Went through WindowProc line by line and finally found the culprit. 3 lines: case WM_PAINT: return 0; break; a remnant of a past experiment. I thought naively that "return 0" will just skip the WM_PAINT block (like commenting it out), but of course it doesn't. It means: when you get a WM_PAINT message, do NOTHING. This screws up window display, of course. Had I thought this may be relevant to the problem I'd have included it here. Then again, had I known this were the problem, I'd have taken it out and not bothered people on SO in the first place. Thx for forcing me to re-analyze WindowProc. –  MrSparkly Nov 13 '10 at 12:54

1 Answer 1

It sounds like you're not returning immediately from WM_CREATE like you're supposed to, but your window's entire lifetime is inside CreateWindow. So MessageBox doesn't actually get called until your window is dead, and trying to pass wnd as the parent of the message box is an invalid argument (the window no longer exists).

You shouldn't call DefWindowProc for WM_CREATE. You shouldn't have a message loop (i.e. DispatchMessage) inside WindowProc (exception: a message loop handling a modal dialog that is a child of the main window).

Re-entrancy of window procedures is something to avoid if possible.

share|improve this answer
DefWindowProc is outside the switch block, not part of WM_CREATE (see above). There's no DispatchMessage inside WindowProc, it's in WinMain (see above). I just added "MessageBox(0, "Test create", 0 ,0)" at the end of the "case WM_CREATE" block, just before "break". I see "Test create" msg box before the app window appears. This tells me that WM_CREATE finishes its job. –  MrSparkly Nov 12 '10 at 1:23
Just noticed: If I remove both the WS_VISIBLE flag from CreateWindow and the "ShowWindow(win, SW_SHOWNORMAL)" line (basically, if I create an invisible window), the "Test" msg box shows up. When I click OK on the msg box, I get an invisible app running. So it's the visibility of the main window that blocks the msg box. –  MrSparkly Nov 12 '10 at 3:25

Your Answer


