Before I used THint, and it was working with this code:
procedure TMainForm.FormCreate(Sender: TObject);
begin
Application.OnShowHint := AppShowHint;
end;
procedure TMainForm.AppShowHint(var HintStr: String; var CanShow: Boolean; var HintInfo: Controls.THintInfo);
begin
HintInfo.ReshowTimeout := 1;
end;
Now I use TBalloonHint and want to change hint text when hint is shown. The above procedure is not triggered.
I am changing the hint text each second, so when user enters control, the hint is shown and I want to update the hint text each second, also when user is not moving with the mouse.
How to achieve this with TBalloonHint?
TBalloonHint
does not support this functionality. The following code (Delphi XE3) adds it.
Cons:
TBalloonHint.ShowHint
creates a new TCustomHintWindow
type
TMyHintWindow = class(THintWindow)
public
function CalcHintRect(MaxWidth: Integer; const AHint: string;
AData: TCustomData): TRect; override;
function ShouldHideHint: Boolean; override;
end;
var BalloonHint: TBalloonHint;
_HintPos: TPoint;
function TMyHintWindow.CalcHintRect(MaxWidth: Integer; const AHint: string;
AData: TCustomData): TRect;
begin
Result := Rect(0,0,0,0);
end;
function TMyHintWindow.ShouldHideHint: Boolean;
begin
Result := True;
BalloonHint.Free; BalloonHint := nil;
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
HintWindowClass := TMyHintWindow;
Application.OnShowHint := AppShowHint;
end;
procedure TMainForm.AppShowHint(var HintStr: String; var CanShow: Boolean; var HintInfo: THintInfo);
begin
HintInfo.ReshowTimeout := 1;
if not Assigned(BalloonHint)
then begin
BalloonHint := TBalloonHint.Create(Self);
_HintPos := Point(MaxInt, MaxInt);
end;
if (_HintPos <> HintInfo.HintPos) or (BalloonHint.Description <> HintStr)
then begin
_HintPos := HintInfo.HintPos;
BalloonHint.Description := HintStr;
BalloonHint.ShowHint(_HintPos);
end;
end;
Another ways:
rewrite TMyHintWindow.CalcHintRect
and .Paint
taking code from TBalloonHint
rewrite TMyHintWindow
using Tooltip Controls
Add: Use tooltip control. Try also set HintInfo.ReshowTimeout := 25
.
uses Windows, Vcl.Controls, System.Classes, Winapi.CommCtrl, Winapi.Messages;
type
TTooltipHintWindow = class(THintWindow)
private
TooltipWnd: HWND;
TooltipInfo: TToolInfo;
TooltipText: string;
TooltipPos: TPoint;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure ActivateHint(Rect: TRect; const AHint: string); override;
function CalcHintRect(MaxWidth: Integer; const AHint: string; AData: TCustomData): TRect; override;
function ShouldHideHint: Boolean; override;
end;
implementation
procedure TTooltipHintWindow.ActivateHint(Rect: TRect; const AHint: string);
begin
inherited;
if (TooltipText <> AHint)
then begin // update text
TooltipText := AHint;
TooltipInfo.lpszText := PChar(TooltipText);
SendMessage(TooltipWnd, TTM_UPDATETIPTEXT, 0, LParam(@TooltipInfo));
end;
if (TooltipPos <> Rect.TopLeft)
then begin // update position
TooltipPos := Rect.TopLeft;
SendMessage(TooltipWnd, TTM_TRACKPOSITION, 0, PointToLParam(TooltipPos));
end;
// show
SendMessage(TooltipWnd, TTM_TRACKACTIVATE, WParam(True), LParam(@TooltipInfo));
end;
function TTooltipHintWindow.CalcHintRect(MaxWidth: Integer; const AHint: string;
AData: TCustomData): TRect;
begin
Result := Rect(0,0,0,0);
end;
constructor TTooltipHintWindow.Create(AOwner: TComponent);
var font, boldfont: HFONT;
logfont: TLogFont;
begin
inherited;
// create tooltip
TooltipWnd := CreateWindowEx(WS_EX_TOPMOST or WS_EX_TRANSPARENT,
TOOLTIPS_CLASS, nil,
TTS_NOPREFIX or TTS_ALWAYSTIP or TTS_BALLOON,
0, 0, 0, 0, 0, 0, HInstance, nil);
// set bold font
font := SendMessage(TooltipWnd, WM_GETFONT, 0, 0);
if (font <> 0)
then begin
if GetObject(font, SizeOf(logfont), @logfont) > 0
then begin
logfont.lfWeight := FW_BOLD;
boldfont := CreateFontIndirect(logfont);
SendMessage(TooltipWnd, WM_SETFONT, boldfont, 0);
end;
end;
// set maximum width
SendMessage(TooltipWnd, TTM_SETMAXTIPWIDTH, 0 , 400);
// init
FillChar(TooltipInfo, SizeOf(TooltipInfo), 0);
TooltipInfo.cbSize := SizeOf(TooltipInfo);
TooltipInfo.uFlags := TTF_TRACK or TTF_TRANSPARENT;
TooltipInfo.uId := 1;
SendMessage(TooltipWnd, TTM_ADDTOOL, 0, LParam(@TooltipInfo));
end;
destructor TTooltipHintWindow.Destroy;
begin
DestroyWindow(TooltipWnd);
inherited;
end;
function TTooltipHintWindow.ShouldHideHint: Boolean;
begin
inherited;
// hide
SendMessage(TooltipWnd, TTM_TRACKACTIVATE, WParam(False), LParam(@TooltipInfo));
TooltipPos := Point(MaxInt, MaxInt);
TooltipText := '';
end;