因为我的菜单是动态生成的..
所以的它事件也是动态生成的...
用的是循环....生成事件..........
所以的它事件也是动态生成的...
用的是循环....生成事件..........
解决方案 »
- 有用过Delphi Encryption Compendium组件的吗?
- 如何把TXMLDocument的内容转化为String
- 为什么在使用treeview的时候,每次在imagelist中将图标的大小属性改了后,在treeview中就显示不了图标了?
- 那里有《深入核心——VCL架构剖析》电子版下载。
- 请问如何判断一个edit框里填写的内容是不是date类型?
- 如何在程序中检测对方摘机。
- 有两个问题想请教?
- 怎样用SQL语句实现对表的翻页功能?解决送高分! (欢迎参与)
- 用 在F1book控件基础上开发的崭新F1bookDraw控件全面解决Delphi下各种复杂报表的制作,预览,列宽调整,保存为Excel文件问题.此控件方便的管
- Delphi生成的EXE,求按钮正确使用方式
- 事务问题
- 救命啊!!!关于对系统的加密问题。在线等待大侠们的赐教。
N1.OnClick := N1Click;
只要两个的参数是一样就行了
如:procedure myclick(sender:Tobject);
begin
showmessage('scuess!');
end;
在菜单生成后:
N1.onclick:=myclick(sender);
begin
case TMenuItem(Sender).Tag of
0://打开出库单
1://打开入库单
end;
end;
var
mnuTemp : TCustomMenuItem;
begin
mnuTemp := Sender as TCustomMenuItem;
if mnuTemp.RoleID <> '' then
DistributeIt(mnuTemp.RoleID, mnuTemp.RoleKey, nil);
end;
问题是我的菜单是一个菜单数组。
我想循环为它付上事件。
怎么办?
for j:=0 to book.q3.Recordcount-1 do
begin
childitems[j]:=tmenuitem.Create(items[i]);
childitems[j].Caption:=trim(book.q3.fieldbyname('memu').asstring);
items[i].Add(childitems[j]);
//childitems[j].OnClick=//怎么办?;
end;
book.q3.next;
var
MenuItem: TMenuItem;
ParentMenu: TComponent;
i: Integer;
comp: TComponent; procedure updateMenuItem(index: integer; pMenuItem: TMenuItem);
begin
with pMenuItem do
begin
{1=Name,Parent,Caption,Hint,Shortcut,ID,WindowName,ExeName}
Name := UserTitle(AddonMenu[index], ',', 1);
if CaptionHandler1.LangChanger.LanguageMode = lmEnglish then
begin
Caption := UserTitle(AddonMenu[index], ',', 3);
Hint := UserTitle(AddonMenu[index], ',', 4);
end
else
begin
Caption := UserTitle(AddonMenu[index], ',', 9);
Hint := UserTitle(AddonMenu[index], ',', 10);
end;
if UserTitle(AddonMenu[index], ',', 5) <> EmptyStr then
Shortcut := TextToShortCut(UserTitle(AddonMenu[index], ',', 5));
end;
end;
begin
for i := 0 to AddonMenu.Count - 1 do
begin
// by rex on 2 mar 2001
comp := Self.FindComponent(UserTitle(AddonMenu[i], ',', 1));
if Assigned(comp) then begin
TComponent(MenuItem) := comp;
updateMenuItem(i, MenuItem);
continue;
end
else begin
MenuItem := TMenuItem.Create(Self); {create an item on the fly}
updateMenuItem(i, MenuItem);
end;
// by rex on 2 mar 2001 end with MenuItem do
begin
Enabled := True;
Visible := True;
Tag := i;
OnClick := MenuOnClick; {assign OnClick event}
if UserTitle(AddonMenu[i], ',', 2) = EmptyStr then
ParentMenu := nil
else
ParentMenu := Self.FindComponent(UserTitle(AddonMenu[i], ',', 2));
end;
if ParentMenu = nil then
mnuMain.Items.Add(MenuItem)
else
begin
if ParentMenu is TMainMenu then
TMainMenu(ParentMenu).Items.Add(MenuItem)
else if ParentMenu is TPopupMenu then
TPopupMenu(ParentMenu).Items.Add(MenuItem)
else
TMenuItem(ParentMenu).Add(MenuItem);
end;
end;
end;
那么多菜单项你都要设置不同的事件吗? 能否设置一个公用事件, 再根据具体情况加以区别处理呢? 如果真的差别很大, 能否确定Recordcount呢? 如果不能就不好办了. 事件无论如何是要提前编好的, 只是动态分配给相应的对象罢了, 不能动态生成的, 除非是个编程软件...
在公用事件里面利用sender的tag属性区分就好了
菜单也是动态生成的,
事件处理也是动态处理的,
我是用一个ID号来关联的。
用了NAME和TAG属性。如果菜单动态成,而事件又要固定每项一个,
那你应该重新考虑一下你的设计了。
建议集中处理。
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Menus;type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure mypopuphandler(sender:tobject); //定义菜单命令处理过程
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure show(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
myMainMenu: TMainMenu;
myPopupMenu: TPopupMenu;
mysubitems:array[0..3] of tmenuitem;
mypopupitems:array[0..3] of tmenuitem;
i:integer;
y:integer;
implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
myitem:array[0..2] of tmenuitem;
begin
//创建主菜单
mymainmenu:=tmainmenu.create(self);
//创建三个子菜单
for i:=0 to 2 do begin
myitem[i]:=tmenuitem.Create(self);
myitem[i].Caption:='子菜单'+inttostr(i)+'(&'+inttostr(i+1)+')';
mymainmenu.items.add(myitem[i]);
end;
//创建主菜单中第一个子菜单的下拉菜单
for i:=0 to 3 do begin
mysubitems[i]:=tmenuitem.Create(self);
mysubitems[i].Caption :='主菜单项'+inttostr(i)+'(&'+inttostr(i+1)+')';
mymainmenu.items[0].add(mysubitems[i]);
//调用mypopuphandler事件
mysubitems[i].OnClick:=mypopuphandler;
end;
//第二个菜单设为分隔符
mysubitems[1].Caption :='-';
//第三个菜单设置竖向分隔条
mysubitems[3].Break :=mbbarbreak;
end;
procedure tform1.mypopuphandler(sender:tobject);
begin
with sender as tmenuitem do
begin
showmessage(caption);
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
y:=1;
mypopupmenu:=tpopupmenu.create(self);
//创建弹出式菜单
for i:=0 to 3 do begin
mypopupitems[i]:=tmenuitem.Create(self);
mypopupitems[i].Caption :='弹出式菜单项'+inttostr(i)+'(&'+inttostr(i+1)+')';
mypopupmenu.items.add(mypopupitems[i]);
mypopupitems[i].OnClick :=mypopuphandler;
end;
end;procedure TForm1.Button3Click(Sender: TObject);
begin
if y=0 then exit;
//定点击活popupmenu
mypopupmenu.popup(form1.Left +60,form1.Top +60);
end;procedure TForm1.show(Sender: TObject);
begin
y:=0;
end;end.
看来现在只好写一个公共函数了...
不知那个公共函数...怎么写...
是不是这样写..
if (serner with tmemuitem).name(或caption)='菜单名' then
(semder as tmemuitme).onclick=某个事件
else if...
..................................
unit DataTree;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, ComCtrls, StdCtrls, Buttons;type
PNode = ^TNode;
TNode = record
FID:integer; // 记录的ID号
FBM:TBookMark; // 定位记录的指针(书签)
end;type
TDataTreeForm = class(TForm)
ADOConnection1: TADOConnection;
TreeView1: TTreeView;
BitBtn1: TBitBtn;
ADODataSet1: TADODataSet;
Button1: TButton;
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
DataTreeForm: TDataTreeForm;function BuildTree(DataSet: TADODataSet; TV: TTreeView;
SelfField,SelfName,ParentField:String):boolean;implementation{$R *.dfm}function BuildTree(DataSet: TADODataSet; TV: TTreeView;
SelfField,SelfName,ParentField:String):boolean;
{ 以下子函数为在表中查找第一个PNode=AIndex的记录}
function FindKey(AIndex: integer; FFirst:boolean): boolean;
begin
Result:=DataSet.Locate(ParentField,AIndex,[loCaseInsensitive]);
end;
{ 以下函数在FindKey的基础上找出下一个符合的记录}
function FindNext(AIndex: integer): boolean;
begin
DataSet.Next;
if DataSet.Eof then
Result:=false
else
Result:=DataSet.FieldValues[ParentField]=AIndex;
if not Result then DataSet.Prior;
end;
{ 以下函数据构造当前结点的一级子树 }
function GetChildNode(index: integer; ANode: TTreeNode):integer;
var
MyNode:PNode;
Node:TTreeNode;
begin
if FindKey(index,true) then
begin
new(MyNode);
with DataSet do
begin
MyNode^.FID :=FieldValues[SelfField];
MyNode^.FBM :=GetBook;
end;
Node:=TV.Items.AddChild(ANode,DataSet.FieldValues[SelfName]);
Node.Data:=MyNode;
Result:=1;
while FindNext(index) do
begin
new(MyNode);
with DataSet do
begin
MyNode^.FID :=FieldValues[SelfField];
MyNode^.FBM :=GetBook;
end;
Node:=TV.Items.AddChild(ANode,DataSet.FieldValues[SelfName]);
Node.Data:=MyNode;
Result:=Result+1;
end;
end
else
Result:=0;
end;
{ 以下函数据以ANode 为结当,构造一棵属于自己的子树}
procedure BuildMe(AIndex: integer; ANode: TTreeNode);
var
NodeNum:integer;
Node:TTreeNode;
i:integer;
begin
NodeNum:=GetChildNode(AIndex,ANode);
if NodeNum>0 then
begin
if ANode=nil then Node:=TV.Items.GetFirstNode
else
Node:=ANode.getFirstChild;
for i:=1 to NodeNum do
begin
BuildMe(PNode(Node.Data)^.FID,Node);
Node:=ANode.GetNextChild(Node);
end;
end;
end;
// 组合部份
begin
if (DataSet=nil) or (DataSet.Active =false) then
Result:=false
else if (TV=nil) then
Result:=false
else begin
TV.Items.Clear;
BuildMe(0,nil);
Result:=true;
end;
end;procedure TDataTreeForm.BitBtn1Click(Sender: TObject);
begin
BuildTree(ADODataSet1, TreeView1, 'F_NodeID', 'F_NodeName', 'F_ParentNodeID');
end;end.