unit uNode;interface
uses
ComCtrls,Menus,Controls,Messages;
type
TCNode=class(TTreeNode)
private
FPop:TPopupMenu;
FItem:TMenuItem;
procedure RButtonDown(var Message:TMessage);message WM_RBUTTONDOWN;
public
constructor create();
end;
implementation{ TCNode }constructor TCNode.create;
begin
inherited create(nil);
FPop:=TPopupMenu.Create(nil);
FItem:=TMenuItem.Create(FPop);
FItem.Caption:='复制';
end;procedure TCNode.RButtonDown(var Message: TMessage);
begin
FPop.Popup(200,200);
end;end.
//添加到TreeView控件上是可以的,但是拦截鼠标右键按下弹出"复制"菜单没有效果
//再想想TTreeNode在使用的时候是不需要Create创建的,但我写的这个有Constuctor,
//单步调试时就没有执行Constuctor
//我想封装的实现,只能继承TTreeView来实现吗?
uses
ComCtrls,Menus,Controls,Messages;
type
TCNode=class(TTreeNode)
private
FPop:TPopupMenu;
FItem:TMenuItem;
procedure RButtonDown(var Message:TMessage);message WM_RBUTTONDOWN;
public
constructor create();
end;
implementation{ TCNode }constructor TCNode.create;
begin
inherited create(nil);
FPop:=TPopupMenu.Create(nil);
FItem:=TMenuItem.Create(FPop);
FItem.Caption:='复制';
end;procedure TCNode.RButtonDown(var Message: TMessage);
begin
FPop.Popup(200,200);
end;end.
//添加到TreeView控件上是可以的,但是拦截鼠标右键按下弹出"复制"菜单没有效果
//再想想TTreeNode在使用的时候是不需要Create创建的,但我写的这个有Constuctor,
//单步调试时就没有执行Constuctor
//我想封装的实现,只能继承TTreeView来实现吗?
事件可以满足你的要求,你只要如下就可以了把你的TCNode给创建好的TreeView:
procedure TForm1.TreeView1CreateNodeClass(Sender: TCustomTreeView;
var NodeClass: TTreeNodeClass);
begin
NodeClass := TCNode;
end;
虽然是回答问题,但是自己也学会了一招!爽!
至于自定义的TCNode还是能添加到TreeView上的,
你自己可以测试.
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, Menus;type
TForm3 = class(TForm)
NodeMenu: TPopupMenu;
TreeMenu: TPopupMenu;
ree1: TMenuItem;
Node1: TMenuItem;
TreeView1: TTreeView;
procedure TreeView1CreateNodeClass(Sender: TCustomTreeView;
var NodeClass: TTreeNodeClass);
procedure TreeView1ContextPopup(Sender: TObject; MousePos: TPoint;
var Handled: Boolean);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; TUserTreeNode = class(TTreeNode)
private
FPopupMenu: TPopupMenu;
public
property PopupMenu: TPopupMenu read FPopupMenu write FPopupMenu;
end;var
Form3: TForm3;implementation{$R *.dfm}procedure TForm3.FormCreate(Sender: TObject);
var
Node: TTreeNode;
I: Integer;
begin TreeView1.PopupMenu := TreeMenu; for I := 0 to TreeView1.Items.Count - 1 do
begin
Node := TreeView1.Items.Item[I];
if Node is TUserTreeNode then
TUserTreeNode(Node).PopupMenu := NodeMenu;
end;
end;procedure TForm3.TreeView1ContextPopup(Sender: TObject; MousePos: TPoint;
var Handled: Boolean);
var
Node: TTreeNode;
begin
//
Node := TreeView1.GetNodeAt(MousePos.X,MousePos.Y);
if Node = Nil then
Exit;
if Not (Node is TUserTreeNode) then
Exit; if TUserTreeNode(Node).PopupMenu = Nil then
Exit;
try
MousePos := TreeView1.ClientToScreen(MousePos);
TUserTreeNode(Node).PopupMenu.Popup(MousePos.X,MousePos.Y);
Except
Exit;
end;
Handled := True;
end;procedure TForm3.TreeView1CreateNodeClass(Sender: TCustomTreeView;
var NodeClass: TTreeNodeClass);
begin
NodeClass := TUserTreeNode;
end;end.
uses
menus,classes;
type
Ta=class
private
FPop:TPopupMenu;
FItem:TMenuItem;
FAOwner:TComponent;
protected public
sname:string;
procedure pop(x,y:integer);
constructor create(AOwner:TComponent);
end;
implementation{ Ta }constructor Ta.create(AOwner:TComponent);
begin
FAOwner:=AOwner;
FPop:=TPopupMenu.Create(AOwner);
FItem:=TMenuItem.Create(AOwner);
FItem.Caption:='复制';
FPop.Items.Add(FItem);
end;procedure Ta.pop(x, y: integer);
begin
FPop.Popup(x,y);
end;unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls,Unit2, StdCtrls;type
TForm1 = class(TForm)
TreeView1: TTreeView;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
a:Ta;
pt:TPoint;
begin
pt.X:=button1.Left;
pt.Y:=button1.Top;
pt:=ClientToScreen(pt);
a:=Ta.create(self);
a.pop(pt.X,pt.Y);
end;end.//关键的问题是消息处理,是不是TTreeNode不能处理消息?可能
为了挽回点颜面,说明一下:
1、构造函数constructor TCNode.create 没有执行没关系,就不用构造函数;你访问FPop时,可以判定是否为空,
为空你创建就可以了,建议封装成TCNode的属性PopupMenu
2、TTreeNode不是TWinControl,没有WM_RBUTTONDOWN消息截获的,所以你必须要继承TTreeView的,处理WM_RBUTTONDOWN
看当前的Selected节点是不是TCNode,是的话弹出TCNode.PopupMenu
你给TTreeView绑定一个PopupMenu;在PopupMenu的OnPopup事件里判断
TreeView1.Selected的类型,修改PopupMenu相应菜单项和事件应该就
可以了
你给TTreeView绑定一个PopupMenu;在PopupMenu的OnPopup事件里判断
TreeView1.Selected的节点类型,修改PopupMenu相应菜单项Caption和事件(OnClick)应该就
可以了