Holy cow, I wrote a book!
Setting focus in a dialog box is more than just calling
For example, open the Run dialog from the Start menu.
Observe that the OK button is the default button;
it has a different look from the other buttons.
But focus is on the edit control.
Your typing goes to the edit control, until you hit Enter; the
Enter activates the default button, which is OK.
As you tab through the dialog, observe what happens to the default
button. When the dialog box moves focus
to a pushbutton, that pushbutton becomes
the new default button.
But when the dialog box moves focus
to something that isn't a pushbutton at all,
the OK button resumes its position as the default button.
The dialog manager remebers which control was the default button
when the dialog was initially created, and when it moves focus
to something that isn't a button, it restores that original button
as the default button.
You can ask a dialog box what the default button is by sending
the DM_GETDEFID message;
similarly, you can change it with
the DM_SETDEFID message.
(Notice that the return value of the DM_GETDEFID message packs the
control ID in the low word and flags in the high word.
Another place where expanding dialog control IDs to 32-bit values
doesn't buy you anything.)
As the remarks to the DM_SETDEFID function note, messing directly
with the default ID carelessly can lead to odd cases like a dialog box
with two default buttons.
Fortunately, you rarely need to change the default ID for a dialog.
A bigger problem is using SetFocus to shove focus around a dialog.
If you do this, you are going directly to the window manager,
bypassing the dialog manager. This means that you can create
"impossible" situations like having focus on a pushbutton without
that button being the default!
To avoid this problem, don't use SetFocus to change focus on a dialog.
the WM_NEXTDLGCTL message.
void SetDialogFocus(HWND hdlg, HWND hwndControl)
SendMessage(hdlg, WM_NEXTDLGCTL, (WPARAM)hwndControl, TRUE);
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 default, all that good stuff.
Now you can update dialog boxes like the professionals,
avoiding oddities like having no default button, or worse,
multiple default buttons!