When using a dialog as a main form, what is the bare minimum of checks prior to having the TranslateMessage
and DispatchMessage
? In a code:
MSG msg;
BOOL ret;
hwndDialog = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), nullptr, (DLGPROC)DialogProc);
ShowWindow(hwndDialog, SW_SHOW);
while ((ret = GetMessage(&msg, 0, 0, 0)) != 0) {
if (ret == -1) {
return -1;
}
if (!IsWindow(hwndDialog) || !IsDialogMessage(hwndDialog, &msg)) { // are all these checks needed?
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return 0;
Are !IsWindow(hwndDialog)
and !IsDialogMessage(hwndDialog, &msg)
conditions needed and would a simple:
if (hwndDialog== (HWND) NULL)
suffice for a modeless dialog?
The code in question seems to be based on Creating a Modeless Dialog Box. The scenario serving as the motivation for the example described in the documentation is different from what this question is about: It assumes a GUI that dynamically creates and destroys a modeless dialog.
The dynamic nature of this modeless dialog informed (part of) the design of the message loop showcased in the sample. The call to IsWindow()
specifically serves as a convenience to support a single message loop body that operates reliably regardless of whether the modeless dialog is live.
Since the question is about an application where the lifetime of the (modeless) dialog and the application coincide the IsWindow()
check can safely be dropped.
IsDialogMessage()
, however, is a different beast altogether. Despite its similarity in naming it doesn't just verify a property of a message. The documentation describes its effect as:
Determines whether a message is intended for the specified dialog box and, if it is, processes the message.
The part in bold (rather than its return value) is the primary reason we call this API. "Processes the message" is a cryptic way of saying: "Implements the dialog's keyboard interface". Omitting the call to IsDialogMessage()
on a thread's message loop that owns a modeless dialog renders that dialog dead to keyboard navigation.
In a similar vein, the return value of IsDialogMessage()
is more meaningful than the "uh huh, good to know" of IsWindow()
's response. Its prescriptions are spelled out in the fine print:
Because the
IsDialogMessage
function performs all necessary translating and dispatching of messages, a message processed byIsDialogMessage
must not be passed to theTranslateMessage
orDispatchMessage
function.
The return value is documented as:
If the message has been processed, the return value is nonzero.
In summary, while
if (!IsWindow(hwndDialog) || !IsDialogMessage(hwndDialog, &msg))
appears to be evaluating two conditions, either side of the ||
-operator does vastly different things.
With the groundwork covered let's address the question asked:
When using a dialog as a main form, what is the bare minimum [required]?
If that is the goal things are far simpler: Use a modal dialog and have the system deal with the intricacies of implementing message translation and dispatching. DialogBoxW()
does everything for you already: It creates the dialog, displays it, and runs a message loop.
The only change you'll need to make to your DlgProc
is calling EndDialog()
(instead of DestroyWindow()
) from your WM_CLOSE
message handler to exit the message loop the system spun up.