Welcome back to Application Menus and Dialogs. We are now in Lesson 2, which means we already have a working menu from the previous lesson and can start making the app behave more like a real desktop program. In this lesson, we will improve the Exit command so it does not close the window right away.
This small change matters a lot. When an action is important, a good application pauses and asks for confirmation. By the end of this lesson, we will use MessageBoxW to interrupt the flow, ask a clear question, and only close the app when the user truly means it.
Before we touch the code, let us build the right mental model. A confirmation dialog is useful when an action is hard to undo, such as quitting an app. In WinAPI, MessageBoxW gives us a standard Windows dialog, so we do not need to design a custom window for a simple Yes or No choice.
The key idea is that this dialog is modal: while it is open, the user must respond to it before returning to the main window. That makes it perfect for decisions that should not be ignored.
- The app receives a
command. - A
message boxappears and asks for confirmation. - The app checks the
result. - The app either continues running or initiates the closing sequence.
As we may recall from the previous unit, the menu setup itself does not change. We still define the same command IDs, open the same window procedure, and build the same File menu during WM_CREATE. That existing structure is what gives us a place to attach the new confirmation step.
This part is our foundation:
#include <windows.h>gives access toWinAPItypes and functions.ID_FILE_OPENandID_FILE_EXITare the command IDs we check later.WM_CREATEbuilds the menu bar and attaches theFilemenu to the window.
So, the interface stays the same; what changes is the behavior behind Exit.
The next step is to revisit WM_COMMAND, because that is where menu clicks arrive. We still use LOWORD(wParam) to extract the selected command ID. The Open command remains a placeholder for now, and the Exit command gets its own block because we are about to add extra logic inside it.
There are two small but important details here. First, ID_FILE_OPEN does nothing yet on purpose, which keeps the code ready for the next lesson. Second, case ID_FILE_EXIT uses braces {} so we can safely declare a local variable inside that case. That variable will store the result returned by the confirmation dialog.
Now we add the core feature of this lesson: a modal confirmation dialog. The MessageBoxW function displays a standard Windows message box and waits until the user chooses a button. Its return value tells us which button was pressed.
Each argument has a clear role:
hwnd: makes the message box belong to our main window.- The text asks the actual question.
- The title labels the dialog clearly.
MB_YESNO | MB_ICONQUESTIONcombines two style flags, so the dialog showsYesandNobuttons plus a question icon.
We can also change the available buttons by swapping MB_YESNO with other style flags:
MB_OKCANCEL: Shows OK and Cancel buttons.MB_RETRYCANCEL: Shows Retry and Cancel buttons.MB_YESNOCANCEL: Shows Yes, No, and buttons.
Once the dialog closes, MessageBoxW gives us a result code. We do not close the app blindly; instead, we check whether the user clicked Yes. Only then do we trigger the window destruction process.
This is the safety check that changes the app flow. If the result is IDYES, DestroyWindow(hwnd) is called. If the result is anything else, such as clicking No, the function reaches break, then returns 0 for WM_COMMAND, and the app stays open.
A Note on Window Closing: This
ifcheck insideWM_COMMANDonly handles the "Exit" menu item. If the user clicks the "X" button on the top-right of the window, Windows sends aWM_CLOSEmessage instead of a command message. We will implement confirmation for the "X" button in the upcoming practices.
Even with a confirmation dialog added, we need to handle the final shutdown step properly. When the window is destroyed—either by our DestroyWindow call or the default system behavior—we must ensure the application exits its message loop by responding to WM_DESTROY.
So, the app still shuts down cleanly; we have simply added a decision point in the menu before that shutdown begins.
In this lesson, we kept the menu structure from the previous unit, returned to WM_COMMAND, and upgraded the Exit path with a modal MessageBoxW confirmation. We also refined our window procedure to handle WM_CLOSE and WM_DESTROY as distinct steps.
This is a strong step forward because our program now behaves with more care and feels closer to a real Windows application. In the practice tasks ahead, we will reinforce this pattern so we can add confirmation logic with confidence.
