AlainD
AlainD

Reputation: 6645

Determine size of popup hint message (THintInfo::HintStr) at runtime

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.

Upvotes: 1

Views: 455

Answers (1)

nil
nil

Reputation: 1328

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;

Upvotes: 5

Related Questions