如何使TStringGrid中单元格的提示显示更加平滑?

7

我正在使用Lazarus 0.9.30。

我在一个表单上有一个标准的TStringGrid,希望当鼠标指针移动到列标题上时显示不同的提示。我使用以下代码来实现,但它只能部分工作,通常必须单击单元格才能更改提示,而我实际上希望在鼠标指针移动时就更改提示。我将所有提示存储在一个集合中,使用列索引作为键进行搜索。 有没有办法获得更平滑的提示显示?

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;
2个回答

10

将事件处理程序分配给TApplication.OnShowHintTApplicationEvents.OnShowHint事件,或者子类化TStringGrid以拦截CM_HINTSHOW消息。任何一种方法都将为您提供访问THintInfo记录的方式,该记录用于控制提示窗口的行为。您可以根据需要自定义THintInfo.CursorRect成员的坐标。每当鼠标移动到该矩形外时,提示窗口都会使用最新的Hint属性文本重新激活(在显示之前可以使用THintInfo.HintStr成员进行自定义)。矩形越小,提示窗口被重新激活的频率越高。此功能可使UI控件在其客户区域内具有多个子部分,在鼠标在同一UI控件周围移动时显示不同的提示字符串。

TApplication.HintShortPause属性的值(或通过拦截CM_HINTSHOWPAUSE消息)控制提示窗口是否在重新激活之前消失。如果将暂停值设置为零,则提示窗口立即更新其文本而不会消失。如果将暂停值设置为非零值,则提示窗口将消失,然后在指定的毫秒数经过后重新出现,只要鼠标仍停留在同一UI控件上。

例如:

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;

编辑:我刚刚注意到你在使用Lazarus。我所描述的是如何在Delphi中处理此问题的方法。我不知道它是否也适用于Lazarus。


我认为 SgScoutLink.MouseToCell 调用不会按预期工作。它期望相对于 TGrid 控件的坐标,但 CursorPos 中的坐标是绝对屏幕坐标。因此,应首先调用 SgScoutLink.ScreenToClient。 - dummzeuch
@dummzeuch THintInfo.CursorPos 包含相对于 THintInfo.CursorRect 的客户端坐标,而不是屏幕坐标。 - Remy Lebeau

0
我想到了以下解决方案...不知道在lazarus中是否可行,但我的delphi可以处理它...为网格mousemove处理程序编写以下伪代码:
if (current_coords==old_coords) then   
    {showhint=true;hint=use_mousetocell_call_to_create}   
else   
    {showhint=false;hint=''} old_coords=current_coords;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接