Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect help button click in MessageBox?

In Delphi XE7, I need to use the Help button in a MessageBox. MSDN states:

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.

However, when I click the Help button in the MessageBox, no WM_HELP message seems to be sent to the application:

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;

So how can I get the MessageBox Help button click and how can I detect which MessageBox did it come from?

like image 255
user1580348 Avatar asked Mar 16 '23 16:03

user1580348


1 Answers

The documentation says, with my emphasis:

the system sends a WM_HELP message to the owner.

That is MSDN code for the fact that the message is delivered synchronously directly to the window procedure. In other words, it has been sent using SendMessage, or an equivalent API.

You've attempted to handle it in TApplicationEvents.OnMessage which is used to intercept asynchronous messages. That is messages that are placed on the message queue. These messages are (typically) placed on the queue with PostMessage.

So the reason for you never seeing the message in TApplicationEvents.OnMessage is that the message is never placed in the queue. Instead you need to handle the message in the owner window's window procedure. In Delphi the simplest way to do that is as follows:

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;

As for how to detect which message box was responsible for the message being sent, there's no simple way when using MessageBox. Perhaps the best would be to switch to 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.

If you are going to display a topic an a help file, in response to the user pressing the help button, then you might consider the VCL function MessageDlg. That allows you to pass a help context ID, and the framework will show the application help file, passing on that help context ID.

like image 116
David Heffernan Avatar answered Mar 24 '23 01:03

David Heffernan