当使用RTL布局时,如何通过命中测试获取树视图项目? [英] How to get a tree view item by the hit test when RTL layout is used?

查看:161
本文介绍了当使用RTL布局时,如何通过命中测试获取树视图项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从右到左阅读模式(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆