views:

451

answers:

1

Hi. I'm trying to paint VirtualStringTree's cell differently when mouse is over it. How can I detect the coords of hot node? I know there's a HotNode property but it returns only Node that is under mouse cursor. I need to get cell coords (X,Y) of that node.

+2  A: 

You can get the coordinates of any node with the GetDisplayRect method. Also, InvalidateNode will tell you the coordinates of the node you just invalidated.

For your purposes, I don't think you need to know the coordinates of any arbitrary node, though. Instead, you need to know, when you're painting the node, whether the node you're painting is the hot one. All the node-specific owner-draw events tell you both the current node and the coordinates, except for OnPaintText, which only tells you the node. There's no need to track the current hot node yourself, though. Just check whether Node = Sender.HotNode to determine what style to use for painting the node and its text.

You might be able to avoid the whole issue, though. The control has a fair amount of hot-node-specific code already, so it might just be a matter of finding what properties to configure instead of having to paint everything yourself.

Rob Kennedy
The problem is that I need to paint the node's cell differently from the mouse current position under it. E.g., if i have 5 blank stars painted in the cell, then if mouse is under the third star, i want to draw these stars as "selected" ones.
Linas
OK, then ignore the final paragraph. In the OnMouseMove event, call `InvalidateNode(HotNode)`. In the paint event, check the current mouse position. Do not do your painting *in* the mouse-move event.
Rob Kennedy
You can use `GetHitTestInfoAt()` with the current cursor position to find out if the node you are painting is the node the mouse is over. Call this in your paint event, then compare `HitInfo.HitNode` with the node you are painting.
Nat
Is there much point to doing that, though, Nat? You already know that HotNode is the node the mouse is over. Only use GetHitTestInfoAt if you need additional information about which *part* of the node you're over. Otherwise, just use GetNodeAt, as in Mghie's answer.
Rob Kennedy
"There's no need to track the current hot node yourself." Right, but how is the previous hot node going to be erased? Your answer doesn't address this. Either the node is tracked manually, or the `toHotTrack` paint style flag needs to be set. Maybe that's worth pointing out?
mghie
It will have been invalidated at the same time the current hot node was. The control already keeps track of the hot node as the mouse moves. There's no need to reconstruct that concept externally. If the HotNode property is returning anything (and it is, since that's what Linas said), then the toHotTrack bit is already set.
Rob Kennedy
You are wrong, `HotNode` returns the node under the mouse cursor even when that bit is not set (which makes sense, as it is a *paint* option flag), and in that case invalidating only the current hot node leaves all previous hot nodes intact. As for "It will have been invalidated..." - no it will not, not without the bit set. I tried.
mghie

related questions