Search code examples
c++winapimodeless-dialog

How to use the Enter key in a modeless dialog?


I've been working on a WinAPI Project for university and we are asked to implement the full program in a dialog box. At first, I used a modal dialog box and everything worked fine, except that there was no icon in the taskbar for the dialog box because I created it directly on WM_CREATE and didn't make the main window visible anyway, since it isn't used.

Now I dumped the main window handle altogether and only used CreateDialog to create a modeless dialog, but since then I can't use the Enter key as an alternative to my default push button.

case WM_COMMAND:
    if(LOWORD(wparam) == IDOK || LOWORD(wparam) == IDC_OK) {
        [...] //doing stuff
    }
    break;

and this is my full main function:

int WINAPI WinMain(HINSTANCE dieseInstanz, HINSTANCE vorherigeInstanz, LPSTR lpszArgument, int Fensterstil) {
    MSG Meldung;
    HWND dialog = NULL;

    dialog = CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDC_DIALOG), NULL, dialogHandler);
    if(dialog != NULL) {
        ShowWindow(dialog, SW_SHOW);
    } else {
        MessageBox(NULL, "CreateDialog returned NULL", "Warning!", MB_OK | MB_ICONINFORMATION);
    }

    while(GetMessage(&Meldung, NULL, 0, 0)) {
        TranslateMessage(&Meldung);
        DispatchMessage(&Meldung);
    }
    return Meldung.wParam;
}

Did I just do some basic thing wrong or doesn't it work in general in the way I want to do it?

To clarify: If I press the Enter key in my dialog box, I'm only getting the typical Windows notification sound.


Solution

  • Your message loop needs to include a call to IsDialogMessage():

    Determines whether a message is intended for the specified dialog box and, if it is, processes the message.

    ...

    When IsDialogMessage processes a message, it checks for keyboard messages and converts them into selections for the corresponding dialog box. For example, the TAB key, when pressed, selects the next control or group of controls, and the DOWN ARROW key, when pressed, selects the next control in a group.

    Because the IsDialogMessage function performs all necessary translating and dispatching of messages, a message processed by IsDialogMessage must not be passed to the TranslateMessage or DispatchMessage function.

    Per Using Dialog Boxes: Creating a Modeless Dialog Box:

    The second part of the example is the application's main message loop. The loop includes the IsDialogMessage function to ensure that the user can use the dialog box keyboard interface in this modeless dialog box.

    This is also stated in the CreateDialog() documentation:

    After CreateDialog returns, the application displays the dialog box (if it is not already displayed) by using the ShowWindow function. The application destroys the dialog box by using the DestroyWindow function. To support keyboard navigation and other dialog box functionality, the message loop for the dialog box must call the IsDialogMessage function.

    So, change your message loop to look more like this instead:

    while (GetMessage(&Meldung, NULL, 0, 0)) {
        if (!IsWindow(dialog) || !IsDialogMessage(dialog, &Meldung)) {
            TranslateMessage(&Meldung);
            DispatchMessage(&Meldung);
        } 
    }