Checking the demo further, I discovered that even the system-drawn hints and tooltips (GridDemo, WindowsXPStyleDemo) suffer from the described issue. Supposedly, that's how the Windows handles the mouse staying inside the same Control, but I may be wrong and just need to investigate mouse handling within VirtualTree further.
-----
However, I've made some progress on reducing the boilerplate code of drawing a simple text hint for the VDT. Currently, it makes no use of
OnGetHindKind and
vhkText, using
vhkOwnerDraw by default. Thus, I added the
TVTHintKind to
TVTHintData, so it's preserved over
CMHintShow() calls.
Next, I added
OnGetHint to VDT, being called if
TVTHintData.Kind = vhkText. And finally, inside
TVirtualTreeHintWindow.CalcHintRect() I replaced
// The draw tree gets its hint size by the application (but only if not a header hint is about to show).
// This size has already been determined in CMHintShow.
if (Tree is TCustomVirtualDrawTree) and Assigned(Node) then
with
// The draw tree gets its hint size by the application (but only if not a header or vhkText hint is about to show).
// This size has already been determined in CMHintShow.
if (Tree is TCustomVirtualDrawTree) and Assigned(Node) and (FHintData.Kind = vhkOwnerDraw) then
resulting in hint rect size being calculated automatically if
TVTHintData.Kind = vhkText. Thus,
OnGetHintSize is not required for the text hints in the VDT.
Next steps should be
getting rid of OnDrawHint if vhkText is set, and
trying to fix unresponsiveness if the cursor stays inside VT.
UPD: Removing
OnDrawHint turned out to be pretty easy after previous changes - just added
TVTHintData.Kind check to
TVirtualTreeHintWindow.Paint():
if (Tree is TCustomVirtualDrawTree) and Assigned(Node) and (Kind = vhkOwnerDraw) then
Thus, the cute system text hint is shown.
UPD2: Managed to fix unresponsiveness! (regardless of TVTHintData.Kind)
VT tracks which node/column is hovered (hot) in the
TBaseVirtualTree.HandleHotTrack() (regardless to
toHotTrack). It has a check if the hot node/column has changed, which can be extended for our purposes:
if (HitInfo.HitNode <> FCurrentHotNode) or (HitInfo.HitColumn <> FCurrentHotColumn) then
begin
{...}
// If we left the old hot node, then we should hide it's hint
if ShowHint then
Application.HideHint;
end;
Works like a charm for moving mouse over columns, however, to work as expected for rows (nodes),
toFullRowSelect must be set. The reason for such requirement is an object to discover, and that's enough for today.
-----
If anyone would share the correct repository I should make a PR/send a patch to, I'd be grateful.