再谈 Delphi MessageBox 系统消息框的扩展

  在笔者《Delphi MessageBox消息框应用窗口居中实用解决方案-CSDN博客》中,提到了用新线程操作 MessageBox 消息对话框,使其显示在 HWND 窗口中央而不是桌面中央。其实,在新线程中还可以对消息框做更多的操作。本文就增加一个定时回答默认按钮的功能,可在一定时间后自动选择默认选项,关闭消息对话框,从而让程序自动进行下去。只增加几行代码和一个指定等待时间的全局变量就能实现这个功能。具体代码如下:

implementation

{$R *.dfm}

//============从这里开始到下面结束这段代码放在调用程序之前即可================

type
  TMyThread = class(TThread)        //定义新线程
  protected
    procedure Execute; override;      //新线程创建后即运行
  end;

var
  hMain: HWND;                
  MsgTitle: string;
  WaitColse: integer;                          //全局变量,通过它们向新线程传递相关参数

procedure TMyThread.Execute;                  //新线程执行程序
var
  mR, pR, sR: TRect;
  X, Y: Integer;
  hMsg: HWND;
begin
  FreeOnTerminate := True; { 这可以让线程执行完毕后随即释放 }
  sleep(5);                                    // 等消息框建立
  hMsg := FindWindow(nil, PChar(MsgTitle));    //根据消息窗口标题获取其句柄

  GetWindowRect(hMsg, mR);                     // 取消息框窗口矩形位置大小
  GetWindowRect(hMain, pR);                    // 取父窗口矩形位置大小
  GetWindowRect(GetDesktopWindow, sR);         // 取屏幕桌面矩形位置大小

  X := pR.Left + (pR.Width - mR.Width) div 2;
  Y := pR.Top + (pR.Height - mR.Height) div 2; //将消息框座标设定在HWND窗口中央

  if X < 0 then
    X := 0;
  if X > sR.Width - mR.Width then
    X := sR.Width - mR.Width;
  if Y < 0 then
    Y := 0;
  if Y > sR.Height - mR.Height then
    Y := sR.Height - mR.Height;              //将消息框限制在桌面内

  SetWindowPos(hMsg, HWND_TOP, X, Y, 0, 0, SWP_NOSIZE or SWP_SHOWWINDOW or
    SWP_NOOWNERZORDER);                      //将消息框移动到 HWND 窗口中央。

  if WaitColse = 0 then                      //如果等待时间为0,则与原来一样,等待用户响应
    exit;

  sleep(1000 * WaitColse );                  //等待WaitColse秒。

  PostMessage(hMsg, WM_KEYDOWN, 13, 0);
  PostMessage(hMsg, WM_KEYUP, 13, 0);        //向消息框窗口发送回车,选择默认按钮
end;

// 主函数。在HWND中央显示消息框。Wait为等待时间(秒),为0或省略则一直等待用户选择。 
function MsgBox(const HWND: HWND; const msg, title: string;
  const mbType: WORD; const Wait: integer = 0): WORD;
begin
  hMain := HWND;
  if not IsWindow(hMain) then
    hMain := GetDesktopWindow;  //如果HWND不存在则为桌面
  if title <> '' then
    MsgTitle := title
  else
    MsgTitle := #32;            //如果消息对话框无标题则将标题设为空格方便新线程查找
  WaitColse := Wait;              
  TMyThread.Create(False);      //创建新线程且立即运行
  result := MessageBox(HWND, PChar(msg), PChar(MsgTitle), mbType + MB_TOPMOST);
end;
// ===========================代码结束=================================


  扩展后的函数为 MsgBox,如果HWND = 0且省略 Wait 参数,则与 MessageBox 完全一样。扩展用法:

  如果 HWND 存在,MessageBox 窗口将显示在该窗口的中央,否则显示在桌面中央;
  如果有 Wait 参数且不为0,则用户如果在 Wait 秒内没有选择按钮,到时自动选择默认按钮。

  例如:

procedure TForm3.Button1Click(Sender: TObject);
begin
 if MsgBox(handle, '消息内容', '消息标题', MB_YESNO or MB_DEFBUTTON2, 5) = mrYes then
   close;
end;


   按  Form3 中的 Button1 按钮后,消息框会显示在 Form3 窗口中央。在5秒内用户如果按Yes,则关闭 Form3,如果5秒后还未操作,则自动按默认选项 No,关闭消息对话框。 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值