delphi – 如何在使用RTL布局时通过命中测试获取树视图项?

前端之家收集整理的这篇文章主要介绍了delphi – 如何在使用RTL布局时通过命中测试获取树视图项?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
描述:

具有从右到左阅读模式(RTL)的树视图,如何获取被点击的节点只知道点击坐标?这是一个插入的类,它使树视图使用RTL显示,并包含一个单击处理程序,您可以在其中查看问题:

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).对于那些没有Delphi的人,GetNodeAt方法在内部调用TreeView_HitTest宏,当树视图处于RTL模式时,返回NULL,就像没有任何项目一样.我将通过GetCursorPos函数获得的坐标相对于ScreenToClient函数的控制计算得到.

题:

我的问题是,如何让点击的节点只知道鼠标坐标?如何在RTL模式下使用树视图进行命中测试?我应该从右边计算鼠标水平位置,如果是这样,怎么样?

解决方法

ScreenToClient文档:

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 07001. For more information,see “Window Layout and
Mirroring” in Window Features.

更正后的代码可能如下:

..
  Point := Mouse.CursorPos;
  MapWindowPoints(0,Handle,Point,1);
  Node := GetNodeAt(Point.X,Point.Y);
  ..

另见:Window Layout and Mirroring

猜你在找的Delphi相关文章