We have a TListView with ShowHint
enabled. In the OnInfoTip
handler, a hint message is constructed that is specific to the item over which the mouse is hovering. The message may include newline (#13#10) characters.
An override has been created to process CM_HINTSHOW
messages and the hint message about to be displayed can be seen in msg.HintInfo.HintStr
. It may be possible to calculate the size at runtime but this seems risky because the implementation details may be complex or platform-dependent.
Can the THintInfo
be queried for its' bounding rectangle or is there another way to determine exactly how big the popup hint message will be when it is displayed?
This is required so an exact position of the hint (msg.HintInfo.HintPos
) can be set.
THintWindow
has the function CalcHintRect
that can be used for this case. The VCL will use this function when showing a HintWindow:
with HintInfo do
HintWinRect := FHintWindow.CalcHintRect(HintMaxWidth, HintStr, HintData);
As FHintWindow
is inaccessible outside of TApplication
a temporary instance would need to be created.
procedure TMyListView.CMHintShow(var Message: TCMHintShow);
var
AHintWindow: THintWindow;
AHintWinRect: TRect;
...
begin
AHintWindow := Message.HintInfo.HintWindowClass.Create(nil);
try
AHintWinRect := AHintWindow.CalcHintRect(...);
...
finally
AHintWindow.Free;
end;
end;
How correct this is depends on the THintWindowClass
's implementation. But the HintWindow would show incorrectly if one could not rely on it.
A potential pitfall could be in middle-eastern locale when BidiMode
is right-to-left. Then following is done additionally:
if FHintWindow.UseRightToLeftAlignment then
with HintWinRect do
begin
Delta := MultiLineWidth(HintInfo.HintStr) + 5;
Dec(Left, Delta);
Dec(Right, Delta);
end;