説明:
右から左への読み取りモード (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 モードでツリー ビューを使用してヒット テストを行うにはどうすればよいですか? たとえば、右からマウスの水平位置を計算する必要がありますか?