Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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;
like image 246
user1174918 Avatar asked Feb 14 '12 14:02

user1174918


1 Answers

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.

like image 134
Remy Lebeau Avatar answered Oct 21 '22 17:10

Remy Lebeau