Having a tree view in right-to-left reading mode (RTL), how to get node that was clicked knowing just the click coordinates ? Here is an interposed class, that makes the tree view to use the RTL display and that contains a click handler in which you can see the problem:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, CommCtrl;
type
TTreeView = class(ComCtrls.TTreeView)
protected
procedure CNNotify(var Msg: TWMNotify); message CN_NOTIFY;
procedure CreateParams(var Params: TCreateParams); override;
end;
type
TForm1 = class(TForm)
TreeView1: TTreeView;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TTreeView }
procedure TTreeView.CNNotify(var Msg: TWMNotify);
var
Node: TTreeNode;
Point: TPoint;
begin
inherited;
if Msg.NMHdr.code = NM_CLICK then
begin
Point := ScreenToClient(Mouse.CursorPos);
Node := GetNodeAt(Point.X, Point.Y);
if Assigned(Node) then
ShowMessage('This message never shows...');
end;
end;
procedure TTreeView.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.Style := Params.Style or TVS_RTLREADING;
Params.ExStyle := Params.ExStyle or WS_EX_LAYOUTRTL or WS_EX_RIGHT;
end;
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
var
Node: TTreeNode;
begin
Node := TreeView1.Items.AddChild(nil, 'Item 1');
TreeView1.Items.AddChild(Node, 'SubItem 1');
end;
end.
The problem with this code (or better to say with such tree view in RTL mode) is, that when you click the node (or wherever), the GetNodeAt
method never returns a valid node (always nil
). For those, who don't have Delphi, the GetNodeAt
method internally calls the TreeView_HitTest
macro which when the tree view is in RTL mode, returns NULL
like there won't be any item. I am passing to that macro the coordinates obtained through the GetCursorPos
function calculated relatively to the control by the ScreenToClient
function.
My question is, how to get the clicked node knowing just the mouse coordinates ? How to make a hit test with the tree view in RTL mode ? Should I for instance calculate the mouse horizontal position from right, and if so, how ?
From ScreenToClient
documentation:
Do not use ScreenToClient when in a mirroring situation, that is, when changing from left-to-right layout to right-to-left layout. Instead, use
MapWindowPoints
. For more information, see "Window Layout and Mirroring" in Window Features.
The corrected code could be like:
..
Point := Mouse.CursorPos;
MapWindowPoints(0, Handle, Point, 1);
Node := GetNodeAt(Point.X, Point.Y);
..
Also see: Window Layout and Mirroring
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With