0

Using WinAPI in C, there are two ways to create a dialog with WinAPI: the more common one is to create a dialog resource in the project's .rc file and then use it with DialogBox(), which automates the creation of a standart dialog. The other way is to use CreateWindowEx with specific parameters so that the created window acts like a dialog.

An example of dialog creation with DialogBox can be seen at winprog.org: http://www.winprog.org/tutorial/dialogs.html

Out of pure interest, I've tried to recreate the dialog created with DialogBox(), using CreateWindowEx. To do this, I simply disabled the main window and then CreateWindowEx'ed the dialog. However, what I got still had one difference from the dialog created with DialogBox: when I click on the disabled main window, a DialogBox-created dialog flashes (most probably with the FlashWindowEx function).

Here's my code for creating a dialog box with CreateWindowEx:

    HWND hwndParent;

    HINSTANCE ghInstance;

    LPCWSTR g_szDialogClassName = L"DialogClass";

    void populateDialog(HWND hwnd){
        /* Create various dialog controls */
    }

    LRESULT CALLBACK aboutDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam){
        switch(Message){
            case WM_CREATE:
                populateDialog(hwnd);
                return DefWindowProc(hwnd, Message, wParam, lParam);

            case WM_COMMAND:
                switch(LOWORD(wParam)){
                    case IDC_CLOSEDLG:
                        EnableWindow(hwndParent, TRUE);
                        DestroyWindow(hwnd);
                        UnregisterClass(g_szDialogClassName, ghInstance);
                    break;
                }
            break;

            case WM_CLOSE:
                EnableWindow(hwndParent, TRUE);
                DestroyWindow(hwnd);
                UnregisterClass(g_szDialogClassName, ghInstance);
            break;

            default:
                return DefWindowProc(hwnd, Message, wParam, lParam);
        }
        return DefWindowProc(hwnd, Message, wParam, lParam);
    }

    int createDialogBox(HWND hwnd, HINSTANCE hInstance){
        if (registerClass(hInstance, g_szDialogClassName, (WNDPROC)aboutDlgProc) == 0){
            MessageBoxA(NULL, "Dialog Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
            return 0;
        }
        EnableWindow(hwnd, FALSE);
        CreateWindowEx(WS_EX_DLGMODALFRAME | WS_EX_TOPMOST | WS_EX_TOOLWINDOW, g_szDialogClassName, L"About", WS_VISIBLE | WS_CAPTION | WS_POPUP | WS_SYSMENU, 100, 100, 450, 150, NULL, NULL, hInstance, NULL);

        hwndParent = hwnd;
    }

Now I am very interested in how is this done inside DialogBox()? How can a disabled window recieve mouse input? Or maybe it wasn't disabled by standart means (by something different than EnableWindow(hwnd, FALSE))? Or is it impossible to reproduce this effect with normal WinAPI calls?

  • Please show an MCVE, otherwise we have to guess as to what your code is – David Heffernan Aug 10 '14 at 17:01
  • This is code that's baked inside the operating system. It intercepts the mouse message before it is returned by GetMessage(), flashing the window instead. You can do this yourself as well with your message loop. Not with DialogBox() however, the message loop it uses is baked-in as well. – Hans Passant Aug 10 '14 at 17:05
  • @HansPassant: so basically, I'd need to process the message before it is processed by GetMessage() in my message loop? How would I do that? –  Aug 10 '14 at 17:13
  • @DavidHeffernan: added my code. –  Aug 10 '14 at 17:14
  • 1
    It looks odd that the window you create has no owner. Surely you need it to be owned by the main window. My guess is that once you do that, you'll be fine. You should also read Raymond Chen's articles on modality: http://stackoverflow.com/questions/15696885/why-does-a-messagebox-not-block-the-application-on-a-synchronized-thread/15700193#15700193 – David Heffernan Aug 10 '14 at 17:25
  • @DavidHeffernan: thank you, that solved my problem! Windows actually automates the flash effect if I create the dialog as a child window! You can post this as an answer, and I'll mark it as correct –  Aug 10 '14 at 17:31

1 Answers1

2

The problem with your code is that you created the window un-owned. Specify the main window as the owner when you call CreateWindowEx.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • this is the correct answer! Windows actually automates the flash effect if I create the dialog as a child window! Great thanks! =) –  Aug 10 '14 at 17:54
  • 1
    @Mints97: The operating system automatically flashes an owned window when the user clicks the owner. It does so by calling the [`FlashWindowEx`](http://msdn.microsoft.com/en-us/library/windows/desktop/ms679347.aspx) API. – IInspectable Aug 10 '14 at 20:46