sara_gijs
asked on
Dynamic PopupMenu Generation
Hello. I'm a beginning Delphi programmer, but I'm doing the best I can.
I'm trying to make a dynamic generated PopupMenu, with data from the windows registry. I have a tree-structure in my registry, and I want this to be extracted by my program, and put into a PopupMenu; including the subdirs. It is not sure how many levels deep the tree-structure is.
This brings 2 problems:
1> I managed to create the menuItems, but I don't know how to add a sub-item to a dynamic generated Item.
2> Making a recursive function to walk trough the registry. I know how it works in theory, but I can't get it working in delphi
I hope my question is clear.
I'm trying to make a dynamic generated PopupMenu, with data from the windows registry. I have a tree-structure in my registry, and I want this to be extracted by my program, and put into a PopupMenu; including the subdirs. It is not sure how many levels deep the tree-structure is.
This brings 2 problems:
1> I managed to create the menuItems, but I don't know how to add a sub-item to a dynamic generated Item.
2> Making a recursive function to walk trough the registry. I know how it works in theory, but I can't get it working in delphi
I hope my question is clear.
by the way, some registry keys are so full of subkeys that there won't be space for all the menu items on the screen.
Furthermore, since registry is huge, you might want to fill submenus with items as the owner item is clicked, instead of initializing the whole menu at once. That is my advice unless you have a good reason for the recursion approach... (such as learning about recursion in delphi)
regards
classmate.
Furthermore, since registry is huge, you might want to fill submenus with items as the owner item is clicked, instead of initializing the whole menu at once. That is my advice unless you have a good reason for the recursion approach... (such as learning about recursion in delphi)
regards
classmate.
ASKER
Okay; I managed to come that far too. But how do I add a subitem to an item if I don't know the name of the Item?
For example I have this treestructure:
+ car
| |
| + opel
| + fort
|
+bike
|
+ fast bike
+ slow bike
I already created a Menupopup with an Item 'Sessions1' in it. I Use this code to generate the list:
procedure TFormConf.MakeMenu();
var
Reg: TRegistry;
DirList: TStrings;
Teller: integer;
Item: TMenuItem;
Hostname: String;
begin
Reg := TRegistry.Create;
Reg.OpenKey('\\Software\\S ARA\\SARAw rap\\Sessi ons', False);
DirList := TStringList.Create;
Reg.GetKeyNames(DirList);
Sessions1.Clear;
for Teller := 0 to Dirlist.Count -1 do
begin
Hostname := DirList[teller];
Item := TMenuItem.Create(FormConf) ;
Item.Caption := Hostname;
Item.OnClick := FakeMenuClick;
Sessions1.Add(Item);
end;
end;
But How do I at an subitem to 'cars', if I don't know the name (this is different every time)
For example I have this treestructure:
+ car
| |
| + opel
| + fort
|
+bike
|
+ fast bike
+ slow bike
I already created a Menupopup with an Item 'Sessions1' in it. I Use this code to generate the list:
procedure TFormConf.MakeMenu();
var
Reg: TRegistry;
DirList: TStrings;
Teller: integer;
Item: TMenuItem;
Hostname: String;
begin
Reg := TRegistry.Create;
Reg.OpenKey('\\Software\\S
DirList := TStringList.Create;
Reg.GetKeyNames(DirList);
Sessions1.Clear;
for Teller := 0 to Dirlist.Count -1 do
begin
Hostname := DirList[teller];
Item := TMenuItem.Create(FormConf)
Item.Caption := Hostname;
Item.OnClick := FakeMenuClick;
Sessions1.Add(Item);
end;
end;
But How do I at an subitem to 'cars', if I don't know the name (this is different every time)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Oh yeah,
the line
Memo1.Lines :=DirList;
was for debugging only. you can delete it :)
Evarest
the line
Memo1.Lines :=DirList;
was for debugging only. you can delete it :)
Evarest
Here is my recursion routine. It's like you've done it, with a slight modification...
procedure TForm16.FormContextPopup(S ender: TObject; MousePos: TPoint;
var Handled: Boolean);
procedure fillmenu (OwnerItem : TMenuItem; Reg : TRegistry; Key : String);
var
Teller: integer;
DirList: TStrings;
Hostname: String;
Item : TMenuItem;
begin
Reg.OpenKey(Key, False);
DirList := TStringList.Create;
Reg.GetKeyNames(DirList);
for Teller := 0 to Dirlist.Count -1 do
begin
Hostname := DirList[teller];
Item := TMenuItem.Create(OwnerItem );
Item.Caption := Hostname;
// Item.OnClick := FakeMenuClick;nb
OwnerItem.Add(Item);
FillMenu (Item, Reg, Key + '\' + Hostname);
end;
DirList.Free;
end;
var
pm : TPopupMenu;
Reg: TRegistry;
begin
Reg := TRegistry.Create;
Reg.RootKey := HKEY_LOCAL_MACHINE;
pm := TPopupMenu.create(nil);
FillMenu (pm.Items, Reg, '\Software\borland');
windows.clienttoscreen (handle, MousePos);
with mousepos do
pm.Popup(x, y);
pm.free;
reg.free;
handled := true;
end;
procedure TForm16.FormContextPopup(S
var Handled: Boolean);
procedure fillmenu (OwnerItem : TMenuItem; Reg : TRegistry; Key : String);
var
Teller: integer;
DirList: TStrings;
Hostname: String;
Item : TMenuItem;
begin
Reg.OpenKey(Key, False);
DirList := TStringList.Create;
Reg.GetKeyNames(DirList);
for Teller := 0 to Dirlist.Count -1 do
begin
Hostname := DirList[teller];
Item := TMenuItem.Create(OwnerItem
Item.Caption := Hostname;
// Item.OnClick := FakeMenuClick;nb
OwnerItem.Add(Item);
FillMenu (Item, Reg, Key + '\' + Hostname);
end;
DirList.Free;
end;
var
pm : TPopupMenu;
Reg: TRegistry;
begin
Reg := TRegistry.Create;
Reg.RootKey := HKEY_LOCAL_MACHINE;
pm := TPopupMenu.create(nil);
FillMenu (pm.Items, Reg, '\Software\borland');
windows.clienttoscreen (handle, MousePos);
with mousepos do
pm.Popup(x, y);
pm.free;
reg.free;
handled := true;
end;
For the example i used the local key to borland software, so that the example should be working at any location with delphi installed.
regards
classmate
regards
classmate
Evarest, your solution might work but it is many lines too long ;-)
Hi, sara_gijs :-)
Why did not I get the points ?? As far as I can see, my solution is the best one.
Why did not I get the points ?? As far as I can see, my solution is the best one.
ASKER
Well; my excuses for that. Evarest gave me the first good working example.
I had to give someone the points so I gave it to him. Is there a possebility that I can give you points too?
This is my first question here, so it is all new to me.
But now I'm out of point. Maybe I should go help some people with unix/linux-networking problems :)
I had to give someone the points so I gave it to him. Is there a possebility that I can give you points too?
This is my first question here, so it is all new to me.
But now I'm out of point. Maybe I should go help some people with unix/linux-networking problems :)
ASKER
You are right. Your code is better.
You modified my source to my needs, and it works. And it is smaller.
Still Evarest did a good job too.
Don't know what to do now.... :)
You modified my source to my needs, and it works. And it is smaller.
Still Evarest did a good job too.
Don't know what to do now.... :)
hehe, no big deal.
You seem to be scandinavian, as i too am (why else should a loop variable be called "teller").
You are hereby excused =)
-Jeg trenger vel neppe poengene, men er ganske pirkete på programmeringsteknikk.
Så jeg syntes det var litt småkjipt at en annen stakk av med respekten jeg skulle ha hatt...
Men nå har du sagt unnskyld, så da skal jeg ikke være sur lenger =)
classmate
You seem to be scandinavian, as i too am (why else should a loop variable be called "teller").
You are hereby excused =)
-Jeg trenger vel neppe poengene, men er ganske pirkete på programmeringsteknikk.
Så jeg syntes det var litt småkjipt at en annen stakk av med respekten jeg skulle ha hatt...
Men nå har du sagt unnskyld, så da skal jeg ikke være sur lenger =)
classmate
ASKER
no dutch :P
Ik snap dus geen hol van wat je zei
Ik snap dus geen hol van wat je zei
ASKER
Ey uhh but I have one little problem left.
I added 'item.onclick := fakemenuclick' to the loop, but now ALL the Items get that....
So the menu is right, only when I click a menu to see the submenu's; Fakemenuclick begins to do it work.
How do I escape from this?
I added 'item.onclick := fakemenuclick' to the loop, but now ALL the Items get that....
So the menu is right, only when I click a menu to see the submenu's; Fakemenuclick begins to do it work.
How do I escape from this?
It depends on what the event handler is supposed to do...
if you are in a infinite loop, press ctrl + F2 in delphi. This should halt your application.
if you are in a infinite loop, press ctrl + F2 in delphi. This should halt your application.
Ik snap er ook niks van van wat classmate zei :) Maar over de code: snel geschreven en diende nog heel wat opgemaakt te worden. Het leek me het best dat je dat zelf probeerde daarom mijn "If you want something else explained about this code, let me know!". Ik heb Delphi ook door voorbeelden geleerd, en geloof me daarvan leer je het meest.
Translation:
About my code: quickly written and in need of improvement. However i thought this was an interesting exercise for the sara_gijs.
Anyway, thanx for the points ;)
Evarest
Translation:
About my code: quickly written and in need of improvement. However i thought this was an interesting exercise for the sara_gijs.
Anyway, thanx for the points ;)
Evarest
procedure TForm16.FormContextPopup(S
var Handled: Boolean);
var
pm : TPopupMenu;
mi, mi1, mi2, mi11, mi21, mi22, mi221 : TMenuItem;
begin
pm := TPopupMenu.create(nil);
try
mi := pm.items;
mi1 := TMenuItem.Create(mi); // you also should add appropriate .caption properties...
mi11 := TMenuItem.Create(mi1);
mi2 := TMenuItem.Create(mi);
mi21 := TMenuItem.Create(mi2);
mi22 := TMenuItem.Create(mi2);
mi221 := TMenuItem.Create(mi22);
mi.Add ([mi1, mi2]);
mi1.Add (mi11);
mi2.Add ([mi21, mi22]);
mi22.Add (mi221);
windows.clienttoscreen (handle, MousePos);
with MousePos do
pm.Popup(x,y);
except
// implement as needed
end;
pm.free;
handled := true;
end;
i'll come back with a solution for 2>
classmate.