一つのコントロール内で、場所によって違うヒントを表示する方法です。サンプルとして 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.
|