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

时间:2015-03-21 10:58:46

标签: 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;

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

2 个答案:

答案 0 :(得分:4)

文档说明了我的重点:

  

系统向所有者发送 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。

答案 1 :(得分: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;