1

I am using Delphi 6 on a XP machine.

I use Onmousemove within a stringgrid to get the contents of a cell. Then I use the cell contents to set the hint. then I use Application.ActivateHint to display the hint. But every time I update the hint value the OS sends another MouseMove event. This causes pretty bad flickering of the hint.

I know the mouse is not moving but I get flooded with MouseMove events. a mousemove causes a hint update that caused a mousemove that causes a hint update etc.

4

1 回答 1

7

你采取了完全错误的方法。与其使用OnMouseMove事件手动设置Hint和调用Application.ActivateHint(),不如让 VCL 为您处理一切。

使用TApplication.OnShowHint事件,或者子类化 StringGrid 来拦截CM_HINTSHOW消息,以自定义 StringGrid 的本机提示的行为方式。任何一种方法都可以让您访问THintInfo记录,这允许您在显示/更新当前提示之前对其进行自定义。特别是,该THintInfo.CursorRect成员允许您设置 VCL 用来跟踪鼠标并决定何时/是否需要触发新OnShowHint事件或CM_HINTSHOW消息以更新当前提示的矩形,而鼠标仍在显示的控件内提示。该更新比现在的更新更加干净和无缝TApplication.ActivateHint()

例如:

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

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

procedure TForm1.AppShowHint(var HintStr: string; var CanShow: Boolean; var HintInfo: THintInfo);
var
  Col, Row: Longint;
begin
  if HintInfo.HintControl := StringGrid1 then
  begin
    StringGrid1.MouseToCell(HintInfo.CursorPos.X, HintInfo.CursorPos.Y, Col, Row);
    if (Col >= 0) and (Row >= 0) then
    begin
      HintInfo.CursorRect := StringGrid1.CellRect(Col, Row);
      HintInfo.HintStr := StringGrid1.Cells[Col, Row];
    end;
  end;
end;

或者:

private
  OldWndProc: TWndMethod;

procedure TForm1.FormCreate(Sender: TObject);
begin
  OldWndProc := StringGrid1.WindowProc;
  StringGrid1.WindowProc := StringGridWndProc;
end;

procedure TForm1.StringGridWndProc(var Message: TMessage);
var
  HintInfo: PHintInfo;
  Col, Row: Longint;
begin
  if Message.Msg = CM_HINTSHOW then
  begin
    HintInfo := PHintInfo(Message.LParam);
    StringGrid1.MouseToCell(HintInfo.CursorPos.X, HintInfo.CursorPos.Y, Col, Row);
    if (Col >= 0) and (Row >= 0) then
    begin
      HintInfo.CursorRect := StringGrid1.CellRect(Col, Row);
      HintInfo.HintStr := StringGrid1.Cells[Col, Row];
      Exit;
    end;
  end;
  OldWndProc(Message);
end;

如果您希望在单元格内的每次鼠标移动时更新提示,只需将 设置THintInfo.CursorRect为当前THintInfo.CursorPos位置的 1x1 矩形。如果您希望即使鼠标没有移动也能定期更新提示,请将 设置为THintInfo.ReshowTimeout非零间隔(以毫秒为单位)。

于 2013-10-30T00:06:08.593 回答