【问题标题】:Detect help button click in MessageBox?检测 MessageBox 中的帮助按钮单击?
【发布时间】:2015-03-21 10:58:46
【问题描述】:

在 Delphi XE7 中,我需要使用 MessageBox 中的帮助按钮。 MSDN 状态:

MB_HELP 0x00004000L 向消息框添加帮助按钮。当。。。的时候 用户点击帮助按钮或按 F1,系统发送 WM_HELP 给主人留言。

但是,当我单击 MessageBox 中的帮助按钮时,似乎没有向应用程序发送 WM_HELP 消息:

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
begin
  if Msg.message = WM_HELP then
    CodeSite.Send('ApplicationEvents1Message WM_HELP');
end;

procedure TForm1.btnShowMessageBoxClick(Sender: TObject);
begin
  MessageBox(Self.Handle, 'Let''s test the Help button.', 'Test', MB_ICONINFORMATION or MB_OK or MB_HELP);
end;

那么我怎样才能让 MessageBox 帮助按钮点击,我怎样才能检测到它来自哪个 MessageBox?

【问题讨论】:

    标签: delphi messagebox delphi-xe7


    【解决方案1】:

    文档说,我强调:

    系统发送一条 WM_HELP 消息给所有者。

    这是 MSDN 代码,用于将消息直接同步传递到窗口过程。换言之,它是使用 SendMessage 或等效 API 发送的。

    您已尝试在用于拦截异步消息的TApplicationEvents.OnMessage 中处理它。那是放置在消息队列中的消息。这些消息(通常)以PostMessage 放置在队列中。

    因此,您从未在TApplicationEvents.OnMessage 中看到该消息的原因是该消息从未放入队列中。相反,您需要在所有者窗口的窗口过程中处理消息。在 Delphi 中,最简单的方法如下:

    type
      TForm1 = class(TForm)
      ....
      protected
        procedure WMHelp(var Message: TWMHelp); message WM_HELP;
      end;
    ....
    procedure TForm1.WMHelp(var Message: TWMHelp);
    begin
      // your code goes here
    end;
    

    至于如何检测是哪个消息框负责发送消息,在使用MessageBox时没有简单的方法。也许最好的办法是切换到MessageBoxIndirect。这允许您在MSGBOXPARAMSdwContextHelpId 字段中指定一个ID。该 ID 将传递给WM_HELP 消息的接收者,如documentation 中所述。

    如果您要显示一个主题和一个帮助文件,以响应用户按下帮助按钮,那么您可以考虑使用 VCL 函数MessageDlg。这允许您传递帮助上下文 ID,框架将显示应用程序帮助文件,并传递该帮助上下文 ID。

    【讨论】:

    • 感谢 David 和 Denis 的广泛而有力的回答!
    • 大卫,您在答案的第一段和第二段中都使用了synchronous 这个词是不是错字?或者其中没有一个是Asynchronous
    • @user1580348 你是对的。谢谢你。我现在已经修好了。
    【解决方案2】:

    最小工作样本:

    type
      TForm20 = class(TForm)
        procedure FormCreate(Sender: TObject);
      protected
        procedure WMHelp(var Message: TWMHelp); message WM_HELP;
      end;
    
    procedure TForm20.FormCreate(Sender: TObject);
    begin
      MessageBox(Handle, 'Help test', nil, MB_OK or MB_HELP);
    end;
    
    procedure TForm20.WMHelp(var Message: TWMHelp);
    begin
      Caption := 'Help button works';
    end;
    

    【讨论】:

    • 谢谢丹尼斯。那么为什么这不适用于 TApplicationEvents 呢?以及如何检测消息来自哪个 MessageBox? (无需在调用 MessageBox 之前设置变量)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-14
    • 2012-10-16
    • 2013-05-23
    • 1970-01-01
    • 2019-12-23
    相关资源
    最近更新 更多