Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can WM_NEXTDLGCTL be used with non-dialog windows?

The documentation for WM_NEXTDLGCTL states, that this message is to be used with dialogs:

Sent to a dialog box procedure to set the keyboard focus to a different control in the dialog box.

If this message cannot be used with non-dialog control parents, it would be very tedious to subclass controls in a generic way (as illustrated in this question), since the window procedure would have to call either SetFocus or send a WM_NEXTDLGCTL message, based on not quite trivial to determine context.

Since other dialog-specific APIs can be used with non-dialog windows (e.g. IsDialogMessage), it would feel natural to be able to use WM_NEXTDLGCTL in this setup as well.

Question: Can WM_NEXTDLGCTL be used with non-dialog control parents?

like image 414
IInspectable Avatar asked May 18 '15 08:05

IInspectable


1 Answers

Can WM_NEXTDLGCTL be used with non-dialog control parents?

I dont think you can use it in non dialog parent windows (at least with no changes to parent window), the cause is that it is implemented inside DefDlgProc. So your other non-dialog windows would have to call it to make this message work.

This is the quote I have found in The Old New Thing: Practical Development Throughout the Evolution of Windows: What happens inside DefDlgProc?

As the remarks for the WM_NEXTDLGCTL message observe, the DefDlgProc function handles the WM_NEXTDLGCTL message by updating all the internal dialog manager bookkeeping, deciding which button should be the default, all that good stuff.

Another reason why it is dialog only message is the fact that it (quote from msdn for WM_NEXTDLGCTL):

sets the default control identifier

to do it it must send DM_SETDEFID, which is defined as:

#define DM_SETDEFID         (WM_USER+1)

so it is WM_USER, and as such it might be used for some other purpose on non dialog window (this fact is also mentioned in Raymond Chens book). The interesting thing is that according to this book IsDialogMessage also sends DM_SETDEFID/DM_GETDEFID to your window. So if you want to use TAB like navigation inside you non dialog window (using dialog code), you must adhere to some rules, you can read on them inside: What happens inside IsDialogMessage? of above book. This means among others to use following message loop:

while (GetMessage(&msg, NULL, 0, 0)) {
    if (IsDialogMessage(hwnd, &msg)) {
        /* Already handled by dialog manager */
    } else {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

so if you dont want to do major changes to your parent windows code, then I am afraid you are out of luck.

like image 172
marcinj Avatar answered Oct 20 '22 00:10

marcinj