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

Detect help button click in MessageBox?

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

MB_HELP 0x00004000L Adds a Help button to the message box. When the user clicks the Help button or presses F1, the system sends a WM_HELP message to the owner.

但是,当我单击 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?

最小工作样本:

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;

文档说,我强调:

the system sends a WM_HELP message to the owner.

这是 MSDN 代码,用于将消息直接同步传送到 window 过程。换句话说,它是使用 SendMessage 或等效的 API.

发送的

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

队列中

所以您从未在 TApplicationEvents.OnMessage 中看到消息的原因是消息从未放入队列中。相反,您需要在所有者 window 的 window 过程中处理消息。在 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. That allows you to specify an ID in the dwContextHelpId field of MSGBOXPARAMS. That ID is passed to the recipient of the WM_HELP message, as described in the documentation.

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