检测 MessageBox 中的帮助按钮单击?

use*_*348 4 delphi messagebox delphi-xe7

在 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;
Run Code Online (Sandbox Code Playgroud)

那么我如何才能点击 MessageBox 帮助按钮,以及如何检测它来自哪个 MessageBox?

Dav*_*nan 5

文档说,我的重点是:

系统所有者发送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;
Run Code Online (Sandbox Code Playgroud)

至于如何检测哪个消息框负责发送的消息,使用MessageBox. 也许最好的办法是切换到MessageBoxIndirect. 这允许您在 的dwContextHelpId字段中指定一个 ID MSGBOXPARAMS。该 ID 被传递给WM_HELP消息的接收者,如文档中所述。

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