コントロール内の場所によってヒント文字を変更

一つのコントロール内で、場所によって違うヒントを表示する方法です。サンプルとして TStringGrid を派生させ、セルに文字が収まりきらない部分にマウスが行くとヒントを表示するクラス THintStringGrid を作ります。

やり方は実はとっても簡単です。コントロールで CM_HINTSHOW メッセージを捕まえ、そこで処理をするだけです。ヒントを表示する場合はこのメッセージの戻り値に0を設定します。(表示しない場合は1)
早速コードを書いてみましょう。(あ、ShowHintプロパティはTrueにしてくださいね(^^;)

unit HintStrGrid;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Grids;

type
  THintStringGrid = class(TStringGrid)
  private
    { Private 宣言 }
    procedure CMHINTSHOW(var Msg: TCMHintShow); message CM_HINTSHOW;
  protected
    { Protected 宣言 }
  public
    { Public 宣言 }
  published
    { Published 宣言 }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Additional', [THintStringGrid]);
end;

{ THintStringGrid }

procedure THintStringGrid.CMHINTSHOW(var Msg: TCMHintShow);
var
  ACol, ARow: Integer;
  S: String;
  RC: TRect;
begin
  with Msg.HintInfo^.CursorPos do
    MouseToCell(x, y, ACol, ARow);
  if (ACol <> -1) and (ARow <> -1) then
  begin
    S := Cells[ACol, ARow];
    if S <> '' then
    begin
      RC := CellRect(ACol, ARow);
      if Canvas.TextWidth(S) >= (RC.Right - RC.Left) then
      begin
        with Msg.HintInfo^ do
        begin
          //セルから外れたらヒントを消す
          CursorRect    := RC;
          //ヒントを表示する位置をカスタマイズ(スクリーン座標)
          HintPos       := ClientToScreen(RC.TopLeft);
          //セル内の文字列を表示
          HintStr       := S;
          //時間が経っても消えないようにする
          HideTimeout   := -1;
          //500ミリ秒経過したらもう一度調べる
          ReshowTimeout := 500;
        end;
        Msg.Result := 0;//表示するので0を返す
      end else
        inherited;//デフォルトの動作をさせる 
    end else
      inherited;//デフォルトの動作をさせる
  end else
    inherited;//デフォルトの動作をさせる
end;

end.

Copyright 2001 Rinka Kouzuki All Rights Reserved.