What is the mysterious fourth message box button?

Raymond Chen

Raymond


When you call the MessageBox function,
you pass flags specifying which of a fixed set of button
patterns you want (for example, Yes/No and OK/Cancel)
and which button you want to be the default
(MB_DEFBUTTON1 through MB_DEFBUTTON4.)



Wait a second.
What’s with this
MB_DEFBUTTON4?
None of the button patterns are four-button patterns.
The highest number of buttons you can specify is three:
Abort/Retry/Ignore.
How can you set a nonexistent button to be the default?



Let’s do some header file spelunking.
The flag for this magical fourth button is defined here:



#define MB_DEFBUTTON1 0x00000000L
#define MB_DEFBUTTON2 0x00000100L
#define MB_DEFBUTTON3 0x00000200L
#if(WINVER >= 0x0400)
#define MB_DEFBUTTON4 0x00000300L
#endif /* WINVER >= 0x0400 */


Aha, the magic fourth button was added in
WINVER 4.0.
Therefore, whatever the fourth button is, it was introduced
when WINVER == 0x0400.
Let’s see what other message box flags were introduced then:



#define MB_OK 0x00000000L
#define MB_OKCANCEL 0x00000001L
#define MB_ABORTRETRYIGNORE 0x00000002L
#define MB_YESNOCANCEL 0x00000003L
#define MB_YESNO 0x00000004L
#define MB_RETRYCANCEL 0x00000005L
#if(WINVER >= 0x0500)
#define MB_CANCELTRYCONTINUE 0x00000006L
#endif /* WINVER >= 0x0500 */

#define MB_ICONHAND 0x00000010L
#define MB_ICONQUESTION 0x00000020L
#define MB_ICONEXCLAMATION 0x00000030L
#define MB_ICONASTERISK 0x00000040L

#if(WINVER >= 0x0400)
#define MB_USERICON 0x00000080L
#define MB_ICONWARNING MB_ICONEXCLAMATION
#define MB_ICONERROR MB_ICONHAND
#endif /* WINVER >= 0x0400 */

#define MB_ICONINFORMATION MB_ICONASTERISK
#define MB_ICONSTOP MB_ICONHAND

#define MB_DEFBUTTON1 0x00000000L
#define MB_DEFBUTTON2 0x00000100L
#define MB_DEFBUTTON3 0x00000200L
#if(WINVER >= 0x0400)
#define MB_DEFBUTTON4 0x00000300L
#endif /* WINVER >= 0x0400 */

#define MB_APPLMODAL 0x00000000L
#define MB_SYSTEMMODAL 0x00001000L
#define MB_TASKMODAL 0x00002000L
#if(WINVER >= 0x0400)
#define MB_HELP 0x00004000L // Help Button
#endif /* WINVER >= 0x0400 */

#define MB_NOFOCUS 0x00008000L
#define MB_SETFOREGROUND 0x00010000L
#define MB_DEFAULT_DESKTOP_ONLY 0x00020000L

#if(WINVER >= 0x0400)
#define MB_TOPMOST 0x00040000L
#define MB_RIGHT 0x00080000L
#define MB_RTLREADING 0x00100000L
#endif /* WINVER >= 0x0400 */

#ifdef _WIN32_WINNT
#if (_WIN32_WINNT >= 0x0400)
#define MB_SERVICE_NOTIFICATION 0x00200000L

#else
#define MB_SERVICE_NOTIFICATION 0x00040000L
#endif
#define MB_SERVICE_NOTIFICATION_NT3X 0x00040000L
#endif



We can discount the flags like MB_ICONWARNING
which are just alternate names for existing flags,
as well as MB_SERVICE_NOTIFICATION which
already existed but with a different value.
This leaves the following:



#define MB_USERICON 0x00000080L
#define MB_HELP 0x00004000L // Help Button
#define MB_TOPMOST 0x00040000L
#define MB_RIGHT 0x00080000L
#define MB_RTLREADING 0x00100000L


Of these flags, MB_USERICON affects the icon,
and MB_TOPMOST, MB_RIGHT and
MB_RTLREADING affect the dialog box’s position and layout;
none of them affect the buttons.
But wait, there’s MB_HELP.
Ah, that flag “adds a Help button to the message box.”
That’s our magical fourth button!
Let’s celebrate by showing a four-button message box with the
default set to the fourth button:



#include <windows.h>

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev,
LPSTR lpCmdLine, int nShowCmd)
{
return MessageBox(NULL, TEXT(“Four buttons!”), TEXT(“Title”),
MB_ABORTRETRYIGNORE | MB_HELP | MB_DEFBUTTON4);
}

Raymond Chen
Raymond Chen

Follow Raymond   

0 comments

Comments are closed.