1

XP マシンで Delphi 6 を使用しています。

セルの内容を取得するために、stringgrid 内で Onmousemove を使用します。次に、セルの内容を使用してヒントを設定します。次に、Application.ActivateHint を使用してヒントを表示します。しかし、ヒント値を更新するたびに、OS は別の MouseMove イベントを送信します。これにより、ヒントのかなりひどいちらつきが発生します。

マウスが動いていないことはわかっていますが、MouseMove イベントが殺到します。マウスムーブは、ヒントの更新などを引き起こすマウスムーブを引き起こしたヒントの更新を引き起こします。

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で を 1x1 の四角形に設定するだけです。THintInfo.CursorPosマウスを動かさなくても定期的にヒントを更新する場合はTHintInfo.ReshowTimeout、ミリ秒単位でゼロ以外の間隔を設定します。

于 2013-10-30T00:06:08.593 に答える