0

I have a VCL form that is set for bsDialog with biHelp enabled ("?" icon in application bar).

I am following this example: http://delphi.about.com/od/adptips2006/qt/custom_bihelp.htm

However I cannot get the WMNCLBUTTONDOWN Windows Message to appear when I click the "?" button. It only seems to fire when I click on the title bar (like I was going to drag the window around.

Code:

procedure TMainFrm.WMNCLBUTTONDOWN(var Msg: TWMNCLButtonDown);
begin
  ShowMessage('WMNCLBUTTONDOWN Pre-Help') ;

  if Msg.HitTest = HTHELP then
    Msg.Result := 0 // "eat" the message
  else
    inherited;
 end;

procedure TMainFrm.WMNCLBUTTONUP(var Msg: TWMNCLButtonUp);
 begin

  if Msg.HitTest = HTHELP then
  begin
    Msg.Result := 0;
    ShowMessage('Need help?') ;
  end
  else
    inherited;
 end;

Again, I see the "Pre-Help" message when I click on the title bar, but not when I click on the "?" button. Why is this? I'm trying to show a separate form when that button is clicked.

ikathegreat
  • 2,311
  • 9
  • 49
  • 80
  • When you display the message box, you interrupt the message sequence. You won't get a mouse-up message for your form when the message box is displayed at the same time. Do you still get the same problem when you don't have your debugging dialogs? Use `OutputDebugString` to record a message without interfering with other operations. – Rob Kennedy Jul 12 '14 at 19:04

1 Answers1

1

The modal message loop of ShowMessage interferes with the message processing. Use OutputDebugString, for example, to see that the messages fire as your expect:

type
  TMainFrm = class(TForm)
  protected
    procedure WMNCLButtonDown(var Msg: TWMNCLButtonDown); 
      message WM_NCLBUTTONDOWN;
    procedure WMNCLButtonUp(var Msg: TWMNCLButtonUp); 
      message WM_NCLBUTTONUP;
  end;
....
procedure TMainFrm.WMNCLButtonDown(var Msg: TWMNCLButtonDown);
begin
  if Msg.HitTest = HTHELP then
  begin
    OutputDebugString('Help button down');
    Msg.Result := 0;
  end
  else
    inherited;
end;

procedure TMainFrm.WMNCLButtonUp(var Msg: TWMNCLButtonUp);
begin
  if Msg.HitTest = HTHELP then
  begin
    OutputDebugString('Help button up');
    Msg.Result := 0;
  end
  else
    inherited;
end;

Remember that buttons are not pressed until they are released. So you should not be taking action like showing dialogs when the button goes down. Wait until WM_NCLBUTTONUP before showing another dialog.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Thanks for your suggestion about `OutputDebugString`. I am still not getting any of the Help debug outputs. If I add `OutputDebugString('WMNCLBUTTONDOWN');` outside of the `if Msg.HitTest = HTHELP` if block, I do still see that in the Debug output. Any other suggestions? – ikathegreat Jul 12 '14 at 19:16
  • There's no need for any other suggestions. You simply have to use the code that is in my answer. You will see output from both help button down, and help button up. I trust you know where to find this output, do you? – David Heffernan Jul 12 '14 at 19:27
  • Yes, I'm saying I see the output, but only if I add something outside the `if Msg.HitTest = HTHELP` block. I cannot see the "Help button down/up" outputs at any point. – ikathegreat Jul 12 '14 at 19:32
  • The code in my answer produces output on both button down and button up – David Heffernan Jul 12 '14 at 19:33
  • Okay, I found the difference. My project is using a Custom Style (Project Options > Application > Appearance > Aqua Light Slate). The Default Style is NOT Windows. When the project is set to Windows, the above code works as expected. Is there no way to capture this same behavior while using a Custom Style in the application? – ikathegreat Jul 12 '14 at 20:24
  • That's pretty much a different question. I think I answered the question that you asked. It's a bit late to drop in VCL styles. – David Heffernan Jul 12 '14 at 20:26