Delphi中平常使用的消息框有四种形式,有ShowMessage、MessageDlg、Application.MessageBox、MessageBox。下面来深入了解下这四种形式的实现和使用。
1.ShowMessage 显示一个带"OK"按钮的消息框
使用这个函数可以显示一个简单的带"OK"按钮的消息框,消息框的标题是应用程序的标题名,参数Msg字符串显示在消息框上。其源码如下:
procedure ShowMessage(
const Msg:
string);
begin
ShowMessagePos(Msg, -
1, -
1);
end;
可以看到它调用了ShowMessagePos函数,我们观察下面的代码,发现跟ShowMessage很有关系,源码如下:
procedure ShowMessageFmt(
const Msg:
string; Params:
array
of
const);
begin
ShowMessage(Format(Msg, Params));
end;
procedure ShowMessagePos(
const Msg:
string; X, Y: Integer);
begin
MessageDlgPos(Msg, mtCustom,
[mbOK],
0, X, Y);
end;
ShowMessageFmt跟ShowMessage类似,只是ShowMessageFmt参数是带格式化的字符串。而它们最终都调用ShowMessagePos,这是在指定的位置显示消息框,显示出来的效果还是跟ShowMessage一样,其参数X、Y坐标为-1的话表示出现在屏幕中间,其实现调用了MessageDlgPos,这跟MessageDlg又有什么关系,先看下面介绍MessageDlg。
2.MessageDlg 在屏幕中间显示带返回值的可自定义消息框
使用这个函数可以显示一个带图标、多种组合按钮、帮助ID,并且有返回值的消息框,其第一个参数Msg是消息框的显示内容,第二个参数DlgType为消息框类型,以图标形式显示在消息框左侧,其取值范围如下:
mtWarning
//带黄色感叹号的警告图标,标题是Warning
mtError
//带红色叉的错误图标,标题是Error
mtInformation
//带蓝色“i”符号的提示图标,标题是Information
mtConfirmation
//带绿色问号的询问图标,标题是Confirmation
mtCustom
//不带图标,消息框标题是应用程序的标题名称
第三个参数Buttons是出现在消息框上的按钮,可以是单个按钮,也可以是组合按钮,其取值范围如下:
mbYes
//按钮'Yes'(默认都是英文,不方便使用)
mbNo
//按钮'No'
mbOK
//按钮'OK'
mbCancel
//按钮'Cancel'
mbAbort
//按钮'Abort'
mbRetry
//按钮'Retry'
mbIgnore
//按钮'Ignore'
mbAll
//按钮'All'
mbNoToAll
//按钮'No to All'
mbYesToAll
//按钮'Yes to All'
mbHelp
//按钮'Help'
也可以是如下的组合按钮:
mbYesNoCancel
//mbYes, mbNo, and mbCancel(默认都是英文,不方便使用)
mbYesNoAllCancel
//mbYes, mbYesToAll, mbNo, mbNoToAll, and mbCancel
mbOKCancel
//mbOK and mbCancel
mbAbortRetryIgnore
//mbAbort, mbRetry, and mbIgnore
mbAbortIgnore
//mbAbort, mbIgnore
第四个参数HelpCtx是帮助ID,是在消息框按“Help”按钮或按F1出现的帮助文档,若无需帮助的话,设置为0即可。返回值是用户按下了消息框上的按钮,所返回的值,其值与消息框上的各种按钮分别对应,如下所示:
mbOK
//mrOk
mbCancel
//mrCancel(消息框右上角的”关闭“按钮也是返回这个值)
mbYes
//mrYes
mbNo
//mrNo
mbAbort
//mrAbort
mbRetry
//mrRetry
mbIgnore
//mrIgnore
mbAll
//mrAll
mbNoToAll
//mrNoToAll
mbYesToAll
//mrYesToAll
下面是MessageDlg源码:
function MessageDlg(
const Msg:
string; DlgType: TMsgDlgType;
Buttons: TMsgDlgButtons; HelpCtx: Longint): Integer;
begin
Result := MessageDlgPosHelp(Msg, DlgType, Buttons, HelpCtx, -
1, -
1,
'');
end;
发现其下面还有两个类似的函数,它们源码如下:
function MessageDlgPos(
const Msg:
string; DlgType: TMsgDlgType;
Buttons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer): Integer;
begin
Result := MessageDlgPosHelp(Msg, DlgType, Buttons, HelpCtx, X, Y,
'');
end;
function MessageDlgPosHelp(
const Msg:
string; DlgType: TMsgDlgType;
Buttons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer;
const HelpFileName:
string): Integer;
begin
with CreateMessageDialog(Msg, DlgType, Buttons)
do
try
HelpContext := HelpCtx;
HelpFile := HelpFileName;
if X >=
0
then Left := X;
if Y >=
0
then Top := Y;
if (Y <
0)
and (X <
0)
then Position := poScreenCenter;
Result := ShowModal;
finally
Free;
end;
end;
在这里我们看到了MessageDlgPos函数,这就是ShowMessage最终调用的函数,而MessageDlgPos与MessageDlg都调用了MessageDlgPosHelp函数,MessageDlgPosHelp是显示一个带帮助文件的消息框,其实现是调用了CreateMessageDialog函数,其函数原型如下:
function CreateMessageDialog(
const Msg:
string; DlgType: TMsgDlgType; Buttons: TMsgDlgButtons): TForm;
于是乎,我们可以直接使用CreateMessageDialog来创建一个消息框,当我们在开发程序的时候,经常需要使用某些消息框,那么用这个来创建,然后用ShowMoDal来显示和获取返回值即可。继续观察CreateMessageDialog函数,可以发现它是使用TMessageForm创建的。
3.Application.MessageBox 用户自定义消息框
这个函数是Delphi应用程序类对Windows API的消息框函数MessageBox的封装,使其方便调用。其第一个参数是消息框内容文本,第二个参数是消息框标题,第三个参数是标识,指定消息框按钮、图标、默认按钮等等。其函数原型如下:
function TApplication.MessageBox(
const Text, Caption: PChar; Flags: Longint): Integer;
参看其实现源码,我们可以发现它的具体实现:
function TApplication.MessageBox(
const Text, Caption: PChar; Flags: Longint): Integer;
var
{省略····}
begin
{省略···}
if UseRightToLeftReading
then Flags := Flags
or MB_RTLREADING;
try
Result := Windows.MessageBox(Handle, Text, Caption, Flags);
finally
{省略···}
end;
end;
明白它是调用Windows API的MessageBox函数,把自身句柄传递进去。而第三个参数Flags等下面介绍Windows.MessageBox时一起讲解。
4.MessageBox 系统API消息框函数
这个函数包含在Windows单元下,完整的函数名是Windows.MessageBox,是系统API函数,不仅可以自定义消息内容和标题,还有自定义按钮、图标、默认按钮、扩展风格等等。其函数原型如下:
function MessageBox(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer;
stdcall;
其第一个参数为标识消息框的所有者,如果这个参数是0的话,则消息框没有父窗口,与应用程序同等级。第二三个参数不再介绍。第四个参数为标识参数,各种自定义效果风格皆在此设置。下面详细介绍:
自定义出现的按钮:
MB_ABORTRETRYIGNORE
//按钮: 终止、重试、忽略
MB_OK
//按钮: 确定 (默认出现的按钮)
MB_OKCANCEL
//按钮: 确定、取消
MB_RETRYCANCEL
//按钮: 重试、取消
MB_YESNO
//按钮: 是、否
MB_YESNOCANCEL
//按钮: 是、否、取消
自定义出现的图标:
MB_ICONEXCLAMATION, MB_ICONWARNING
//带感叹号的提醒图标
MB_ICONINFORMATION, MB_ICONASTERISK
//带”i“符号的信息提示图标
MB_ICONQUESTION
//带问号的询问图标
MB_ICONSTOP, MB_ICONERROR, MB_ICONHAND
//带停止标志的图标
自定义默认焦点的按钮:
MB_DEFBUTTON1
//第一个按钮设为默认(默认参数是第一个按钮)
MB_DEFBUTTON2
//第二个按钮设为默认
MB_DEFBUTTON3
//第三个按钮设为默认
MB_DEFBUTTON4
//第四个按钮设为默认
自定义消息框显示模式:
MB_APPLMODAL
//用户必须响应消息框才能继续在由hWnd参数标识的窗口工作,MB_APPLMODAL 是默认参数
MB_SYSTEMMODAL
//跟MB_APPLMODAL相似,但是多了WS_EX_TOPMOST窗口风格
MB_TASKMODAL
//跟MB_APPLMODAL相似,但是当参数句柄为空时,属于当前任务的所有顶级窗口被禁用
此外,还有一些其他标识:
MB_DEFAULT_DESKTOP_ONLY
//默认桌面才能创建成功
MB_HELP
//添加一个”帮助“按钮
MB_RIGHT
//消息文本右对齐
MB_RTLREADING
//从右到左显示消息内容和标题
MB_SETFOREGROUND
//使消息框成为前置窗口
MB_TOPMOST
//使消息框在最上层显示
MB_SERVICE_NOTIFICATION
//Windows NT only
MB_SERVICE_NOTIFICATION_NT3X
//Windows NT only
当没有足够内存创建消息框的时候,返回值为0,否则正常返回值如下:
IDABORT
//'终止'按钮被按下
IDCANCEL
//'取消'按钮被按下
IDIGNORE
//'忽略'按钮被按下
IDNO
//'否'按钮被按下
IDOK
//'确定'按钮被按下
IDRETRY
//'重试'按钮被按下
IDYES
//'是'按钮被按下
总结:ShowMessage、MessageDlg是TMessageForm消息窗体类创建的,而Application.MessageBox、MessageBox实质都是Windows API函数MessageBox。相比之下,后两者的可自定义性更强一些。下面举例下使用方法:
procedure TForm1.btn1Click(Sender: TObject);
begin
ShowMessage(
'这是ShowMessage消息框');
ShowMessage(
'这是ShowMessage换行消息框' + #
13#
10 +
'无幻博客http://blog.csdn.net/akof1314');
MessageDlg(
'这是MessageDlg消息框', mtCustom,
[mbOK],
0);
if MessageDlg(
'这是MessageDlg消息框', mtWarning, mbOKCancel,
0) = mrOk
then
begin
//···
end;
Application.MessageBox(
'这是Application.MessageBox消息框',
'标题', MB_OK);
if Application.MessageBox(
'这是Application.MessageBox消息框',
'标题', MB_OKCANCEL + MB_ICONQUESTION + MB_DEFBUTTON2 + MB_TOPMOST) = IDOK
then
begin
//···
end;
MessageBox(
0,
'这是MessageBox消息框',
'标题', MB_OK);
MessageBox(Handle,
'这是MessageBox消息框',
'标题', MB_OK);
case MessageBox(Handle,
'这是MessageBox消息框',
'标题', MB_YESNOCANCEL + MB_ICONSTOP + MB_DEFBUTTON3)
of
IDCANCEL:
begin
//···
end;
IDYES:
begin
//···
end;
IDNO:
begin
//···
end;
end;
end;
运行结果如下: