At some point in all but the simplest program you will need to display a message box to the user. You may want to inform the user of something that has occurred in the program or you may want to get a simple yes-or-no answer from the user.
There are a variety of ways you can display message boxes in your programs. In this article I’m going to discuss several of these ways and I’m going to show you three simple inline functions that will make using message boxes easier.
Let’s assume that you are writing a VCL-based program and that you want to display a message box inside a TMyForm, which is derived from TForm. You want the caption of the message box to be the title of the application and the message box to display a message contained in an AnsiString object. The message box should make a sound when first displayed and then wait until the user acknowledges the message by clicking OK. How can it be done?
Using the Windows API to create and display a message box is easy. The most common method is to use the MessageBox() function. Here is a simple code fragment:
AnsiString msg = "This is my message.";
MessageBox(Handle, msg.c_str(),
Application->Title.c_str(),
MB_OK | MB_ICONINFORMATION);
There are two lines of code. The first argument to the MessageBox() function is the window handle of TMyForm. The second is the message to display and the third is the application’s title. The fourth argument consists of flags that tell the message box to display an OK button and an icon indicating that the message box is providing information to the user.
Although using this Windows API function is not hard, it could be easier. You have to pass a window handle. You cannot pass an AnsiString for the message, you have to pass a char * by calling the AnsiString function c_str(). You have to explicitly pass the Application’s title, again using c_str(). And, finally, you have to explicitly pass in the flags for the OK button and the icon.
There are two more Windows API functions that create message boxes. They are MessageBoxEx() and MessageBoxIndirect(). I won’t discuss them here; but you can look them up in the online help for the Windows API.
As it turns out, the VCL offers several functions for creating message boxes and they are somewhat more convenient to use than the Windows API.
The first is a method contained in the TApplication class. It is also named MessageBox(). Here is an example:
AnsiString msg = "This is my message.";
Application->MessageBox(msg.c_str(),
Application->Title.c_str(),
MB_OK | MB_ICONINFORMATION);
As you can see, this method is nearly identical to the Windows API MessageBox(). The only difference is that TApplication::MessageBox() eliminates the window handle as an argument. In fact, I think this method is too much like the Windows API version. It is a VCL function and it won’t accept an AnsiString for either the message or the caption arguments!
Another VCL function is ShowMessage(). This function takes only one argument, an AnsiString containing the message to be displayed. Here is an example of code using ShowMessage():
AnsiString msg = "This is my message.";
ShowMessage(msg);
This couldn’t be any be easier; but it turns out to be too good to be true. ShowMessage() does not display an icon and it does not make any sounds when displayed.
There are some other VCL functions that will also display a message box. They are ShowMessageFmt(), MessageDlg() and MessageDlgPos(). Each of these three functions suffers from its Delphi heritage though. ShowMessageFmt() allows you to format the message using multiple parameters. However, it does involve using TVarRec which is very awkward to use in C++. MessageDlg() and MessageDlgPos() take arguments that are Sets from Delphi and are also awkward in C++.
The answer to the inconveniences of the VCL functions is to write your own message box functions. These can take advantage of C++ features to make programming message boxes even easier. Here are three functions you can use:
inline int MessageBox(
char *msg, unsigned short flags =
MB_OK | MB_ICONINFORMATION)
{
return(Application->MessageBox(msg,
Application->Title.c_str(), flags));
}
inline int MessageBox(
String msg, unsigned short flags =
MB_OK | MB_ICONINFORMATION)
{
return(Application->MessageBox(
msg.c_str(),
Application->Title.c_str(), flags));
}
inline int MessageBox(int strID,
unsigned short flags =
MB_OK | MB_ICONINFORMATION)
{
return(Application->MessageBox(
LoadStr(strID).c_str(),
Application->Title.c_str(), flags));
}
All three functions are inline, so they are very efficient. They all use the TApplication::MessageBox() function internally, so you don’t need to pass in a window handle. They also fill in the caption for the message box using the application’s title.
Finally, they all use C++ default arguments to pass in flags for an OK button and the information icon. In case you are wondering, using any of the MB_ICONxxx flags also causes Windows to play a sound associated with the icon, so these functions all play a sound. Here’s the revised code using the new MessageBox() function:
AnsiString msg = "This is my message.";
MessageBox(msg);
This uses the first of the three inline functions. It is just as easy as the VCL function, ShowMessage(); but it displays an icon and makes a sound.
The other two inline functions work in a similar fashion. The second takes a
char * instead of AnsiString and the third takes an integer representing a string resource.
There is a demonstration program on the Bridges Publishing Web site for this article. The code includes a header file, MessageBox.h with the three inline functions. Include this file in your programs and get the message out.