Recent

Author Topic: TstatusBar OnHint not called unless AutoHint is checked But!  (Read 4501 times)

jamie

  • Hero Member
  • *****
  • Posts: 6090
TstatusBar OnHint not called unless AutoHint is checked But!
« on: October 03, 2017, 03:52:34 am »
 The OnHint event does not get called if I don't check mark the AutoHint property..

  However, the hint I set in the HintText still auto shows when I hover over it if I set the
ShowHint to true, but no OnHint event is called.

 This is with Laz 1.6.4 32bit IDE ,windows

 So  is a it a bug or bad documentation ?

BTW, I have 2 panels allocated at the moment.
The only true wisdom is knowing you know nothing

BlueIcaro

  • Hero Member
  • *****
  • Posts: 792
    • Blog personal
Re: TstatusBar OnHint not called unless AutoHint is checked But!
« Reply #1 on: October 03, 2017, 11:13:05 am »
Hi, did you put false in ParentShowHint property?

/BlueIcaro

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: TstatusBar OnHint not called unless AutoHint is checked But!
« Reply #2 on: October 03, 2017, 11:32:36 pm »
ParentShowHint is false.

 the ShowHint works as it should when I Set it, it shows the actual hint I have in the
hint text but it just does not  trigger the OnHint event Like I said.

  Need to use AutoHint for the event to work.

 What I do is test the mouse over in that event and find out which panel I am
over and then change the Hint.Text for that specific panel.

 I used a BEEP test for verification.



The only true wisdom is knowing you know nothing

wp

  • Hero Member
  • *****
  • Posts: 11855
Re: TstatusBar OnHint not called unless AutoHint is checked But!
« Reply #3 on: October 04, 2017, 01:25:06 am »
What I do is test the mouse over in that event and find out which panel I am
over and then change the Hint.Text for that specific panel.
This sentence gives me the feeling that you want to show different hints for various controls/panels and that you try to achieve this by modifying the OnHint event.

The intended way to achieve this to assign an individual hint text to the Hint property of each panel and leave the event alone. You can even specify different texts for popup hint and statusbar hint by separating them with a | character in the Hint property.

Code: Pascal  [Select][+][-]
  1. Panel1.Hint := 'Popup hint for panel 1|This is the statusbar hint of panel 1.';
  2. Panel2.Hint := 'Hint for both popup and statusbar';

I do notice that this does not work if a handler is assigned to the statusbar's OnHint.

If you want the hint to change while moving the mouse across the same control you can hook into the OnMouseMove event of the control:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,  Y: Integer);
  2. begin
  3.   if X < Panel1.Width div 2 then begin
  4.     Panel1.Hint := 'Popup hint for Panel1/left half';
  5.     Application.Hint := 'Statusbar hint for Panel1/left half';
  6.     Panel1.Caption := Format('X = %d, left', [x]);
  7.   end else begin
  8.     Panel1.Hint := 'Popup hint for Panel1/right half';
  9.     Application.Hint := 'Statusbar hint for Panel1/right half';
  10.     Panel1.Caption := Format('X = %d, right', [x]);
  11.   end;
  12.   Application.CancelHint;
  13.   Application.ActivateHint(Mouse.CursorPos);
  14. end;
  15.  

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: TstatusBar OnHint not called unless AutoHint is checked But!
« Reply #4 on: October 04, 2017, 02:18:58 am »
 
Code: Pascal  [Select][+][-]
  1.  
procedure TDesign.StatusBar1Hint(Sender: TObject);
var
  P:TPoint;
  X:Integer;
begin
  P := Mouse.CursorPos;
  P:= StatusBar1.ScreenToClient(P);
  X := statusbar1.GetPanelIndexAt(P.X,P.Y);
  if X <> -1 Then
  Case X of
   0:StatusBar1.Hint := 'X,Y'+#13+'Pixels';
   1:StatusBar1.Hint := 'X,Y'+#13+MetricString[Ord(TheLabel.LayOutInfo.Metric)];
   Else
     StatusBar1.Hint := '';
  end;
end;     
The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: TstatusBar OnHint not called unless AutoHint is checked But!
« Reply #5 on: October 04, 2017, 02:20:51 am »
I can seem to get pasting in a code window working here but.. The last post shows
what I am doing with the OnHint Handler so  I can assign different hints.

  Btw.
    I don't have any HINT property on the TStatusPanel in my edition of Laz..

The only true wisdom is knowing you know nothing

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: TstatusBar OnHint not called unless AutoHint is checked But!
« Reply #6 on: October 05, 2017, 02:57:48 am »
Code: Pascal  [Select][+][-]
  1. procedure TDesign.StatusBar1Hint(Sender: TObject);
  2. var
  3.   P:TPoint;
  4.   X:Integer;
  5. begin
  6.   P := Mouse.CursorPos;
  7.   P:= StatusBar1.ScreenToClient(P);
  8.   X := statusbar1.GetPanelIndexAt(P.X,P.Y);
  9.   if X <> -1 Then
  10.   Case X of
  11.    0:StatusBar1.Hint := 'X,Y'+#13+'Pixels';
  12.    1:StatusBar1.Hint := 'X,Y'+#13+MetricString[Ord(TheLabel.LayOutInfo.Metric)];
  13.    Else
  14.      StatusBar1.Hint := '';
  15.   end;
  16. end;

In Delphi, I would use the VCL's TApplication.OnShowHint event for that, as it is the official way to sub-divide a control into multiple hint areas (or, you can subclass a control to handle the VCL's CM_HINTSHOW message) eg:

Code: Pascal  [Select][+][-]
  1. procedure TMyForm.FormCreate(Sender: TObject);
  2. begin
  3.   // or, use a TApplicationEvents component instead...
  4.   Application.OnShowHint := ApplicationShowHint;
  5. end;
  6.  
  7. procedure TMyForm.FormDestroy(Sender: TObject);
  8. begin
  9.   Application.OnShowHint := nil;
  10. end;
  11.  
  12. procedure TMyForm.ApplicationShowHint(var HintStr: string;
  13.   var CanShow: Boolean; var HintInfo: THintInfo);
  14. var
  15.   I, X: Integer;
  16.   R: TRect;
  17. begin
  18.   if HintInfo.HintControl = StatusBar1 then
  19.   begin
  20.     X := -1;
  21.     for I := 0 to StatusBar1.Panels.Count-1 do
  22.     begin
  23.       SendMessage(StatusBar1.Handle, SB_GETRECT, I, LPARAM(@R));
  24.       if PtInRect(R, HintInfo.CursorPos) then
  25.       begin
  26.         X := I;
  27.         Break;
  28.       end;
  29.     end;
  30.     case X of
  31.       0: HintStr := ...;
  32.       1: HintStr := ...;
  33.     else
  34.       HintStr := '';
  35.       Exit;
  36.     end;
  37.     HintInfo.CursorRect := R;
  38.   end;
  39. end;

FreePascal/Lazarus also has a similar TApplication.OnShowHint event, so try something like this:

Code: Pascal  [Select][+][-]
  1. procedure TDesign.ApplicationShowHint(var HintStr: string;
  2.   var CanShow: Boolean; var HintInfo: THintInfo);
  3. var
  4.   X: Integer;
  5.   R: TRect;
  6. begin
  7.   if HintInfo.HintControl = StatusBar1 then
  8.   begin
  9.     X := StatusBar1.GetPanelIndexAt(HintInfo.CursorPos.X, HintInfo.CursorPos.Y);
  10.     case X of
  11.       0: HintStr := ...;
  12.       1: HintStr := ...;
  13.     else
  14.       HintStr := '';
  15.       Exit;
  16.     end;
  17.     // manually calculate client rect of TStatusPanel at index X, as
  18.     // TStatusBar and TStatusPanel don't have a method for that..
  19.     R := ...;
  20.     HintInfo.CursorRect := R;
  21.   end;
  22. end;
« Last Edit: October 05, 2017, 03:05:54 am by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

 

TinyPortal © 2005-2018