当使用RTL布局时,如何通过命中测试获取树视图项目? [英] How to get a tree view item by the hit test when RTL layout is used?
问题描述
从右到左阅读模式(RTL)拥有树视图,如何获取点击的节点只知道点击坐标?这是一个插入的类,它使树视图使用RTL显示,并包含一个点击处理程序,您可以在其中看到问题:
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.
此代码的问题(或者更好地说使用RTL模式下的这种树视图)是当您点击节点(或任何地方)时, GetNodeAt
方法永远不会返回一个有效的节点(总是 nil
)。对于那些谁没有德尔福, GetNodeAt
方法内部调用 TreeView_HitTest
宏,当树视图处于RTL模式时,返回 NULL
喜欢不会有任何项目。我通过 GetCursorPos
函数相对于 ScreenToClient
功能。
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 Delp 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.
我的问题是,如何让点击的节点知道鼠标坐标?如何使用RTL模式下的树视图进行命中测试?我应该如何从右边计算鼠标的水平位置,如果是这样,那么如何?
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 ?
推荐答案
从 ScreenToClient
文档:
在镜像情况下,请勿使用 ScreenToClient
从左到右布局更改为从右到左的布局。相反,
使用MapWindowPoints
。有关详细信息,请参阅窗口功能中的窗口布局和
镜像。
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.
更正的代码可能如下所示: / p>
The corrected code could be like:
..
Point := Mouse.CursorPos;
MapWindowPoints(0, Handle, Point, 1);
Node := GetNodeAt(Point.X, Point.Y);
..
另见:窗口布局和镜像
这篇关于当使用RTL布局时,如何通过命中测试获取树视图项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!