检测 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。
在 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。