How can you get hints for cells in a TStringGrid appearing more smoothly?
Asked Answered
G

2

7

I am running Lazarus 0.9.30.

I have a standard TStringGrid on a form and want to show a different hint as I move my mouse pointer over a column title. I am using this code to do this and it sort of works but you often have to click on the cell to get the hint to change, when I actually want it to change as the mouse pointer moves over it. I have all the hints stored in a collection that I search through using the column index as the key. Is there a way to get more smooth display of hints?

procedure TTmMainForm.SgScoutLinkMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
  R, C: Integer;
begin
  R := 0;
  C := 0;

  SgScoutLink.MouseToCell(X, Y, C, R);

  with SgScoutLink do
  begin
    if (R = 0) then
      if ((C >= 3) and (C <= 20)) then
      begin
        SgScoutLink.Hint := FManager.ScoutLinkColumnTitles.stGetColumnTitleHint(C-3);
        SgScoutLink.ShowHint:= True;
      end; {if}
  end; {with}
end;
Gulf answered 14/2, 2012 at 14:46 Comment(0)
I
10

Assign an event handler to the TApplication.OnShowHint or TApplicationEvents.OnShowHint event, or subclass the TStringGrid to intercept the CM_HINTSHOW message. Any one of those will provide you access to a THintInfo record that is used to control the behavior of the hint window. You can customize the coordinates of the THintInfo.CursorRect member as needed. The hint window is reactivated with the latest Hint property text (which can be customized with the THintInfo.HintStr member before it is displayed) whenever the mouse moves outside of that rectangle. The smaller the rectangle, the more often the hint window is reactivated. This feature allows a UI control to have multiple subsections within its client area that display different hint strings while the mouse is moving around that same UI control.

The value of the TApplication.HintShortPause property (or from intercepting the CM_HINTSHOWPAUSE message) controls whether the hint window disappears before reactivating. If you set the pause value to zero, the hint window updates its text immediately without disappearing. If you set the pause value to a non-zero value, the hint window disappears and then reappears after the specified number of milliseconds have elapsed, as long as the mouse remains over the same UI control.

For example:

procedure TTmMainForm.FormCreate(Sender: TObject);
begin
  Application.OnShowHint := AppShowHint;
end;

procedure TTmMainForm.FormDestroy(Sender: TObject);
begin
  Application.OnShowHint := nil;
end;

procedure TTmMainForm.AppShowHint(var HintStr: String; var CanShow: Boolean; var HintInfo: THintInfo);
var 
  R, C: Integer; 
begin
  if HintInfo.HintControl = SgScoutLink then
  begin
    R := 0; 
    C := 0; 
    SgScoutLink.MouseToCell(HintInfo.CursorPos.X, HintInfo.CursorPos.Y, C, R); 
    if (R = 0) and (C >= 3) and (C <= 20) then 
    begin 
      HintInfo.CursorRect := SgScoutLink.CellRect(C, R);
      HintInfo.HintStr := FManager.ScoutLinkColumnTitles.stGetColumnTitleHint(C-3); 
    end;
  end;
end;

Edit: I just noticed that you are using Lazarus. What I described is how to handle this issue in Delphi. I have no clue if it also applies to Lazarus or not.

Isothere answered 15/2, 2012 at 1:38 Comment(2)
I think the SgScoutLink.MouseToCell call will not work as expected. It expects coordinates relative to the TGrid control, but those in CursorPos are absolute screen coordinates. So SgScoutLink.ScreenToClient should be called first.Wham
@Wham THintInfo.CursorPos contains relative client coordinates within THintInfo.CursorRect, not screen coordinatesIsothere
A
0

I came to the following solution... have no idea if it works in lazarus but my delphi is ok with it... Write the following pseudo-code for the grid mousemove handler:

if (current_coords==old_coords) then   
    {showhint=true;hint=use_mousetocell_call_to_create}   
else   
    {showhint=false;hint=''} old_coords=current_coords;
Ayer answered 11/11, 2015 at 1:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.