Link to home
Start Free TrialLog in
Avatar of skynergy
skynergy

asked on

Remove parent TMenuItem in a TPopupMenu or recursively add items from PopupMenu1 into PopupMenu2 without the parent TMenuItem

Question A:
I have a TPopupMenu that have the following TMenuItems in each tier:
Tier1     Tier2    Tier3
-----      -----      -----
parent  child_1  sub_item_a
                            sub_item_b
            child_2  sub_item_c
                            sub_item_d
            child_3   sub_item_e
                            sub_item_f
                 
How do I remove the 1st TMenuItem (called 'parent' in this example) from the TPopupMenu, so it that the TMenuItems that remain will show as follows:
Tier1     Tier2    
-----       -----
child_1  sub_item_a
               sub_item_b
child_2  sub_item_c
               sub_item_d
child_3  sub_item_e
               sub_item_f                
         
Question B:        
If one cannot remove the first tier's TMenuItem, how do I recursuvely go through TPopupMenu1 and add all the TMenuItems from TPopupMenu1, except for the parent TMenuItem, to TPopupMenu2?
ASKER CERTIFIED SOLUTION
Avatar of skynergy
skynergy

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
If this is a simple switch of menus (as opposed to a more dynamic restructuring)... I.E. there will only ever be the two possibilities, then you can simply use two popup menus and switch which one the form is using by setting the form's popup menu property to popupmenu1 or popupmenu2.
Avatar of Ephraim Wangoya
If we are just removing the first tier, a simple nested loop should be sufficient

procedure RemoveFirstTier(APopupMenu: TPopupMenu);
var
  Item, ParentItem: TMenuItem;
  I: Integer;
  List: TList;
begin
  List := TList.Create;  //just maintain a list of the parent items
  try
    for I := 0 to APopupMenu.Items.Count -1 do
    begin
      ParentItem := APopupMenu.Items[I];
      while ParentItem.Count > 0 do
      begin
        Item := ParentItem.Items[0];
        ParentItem.Remove(Item);
        APopupMenu.Items.Add(Item);
      end;
      List.Add(ParentItem);
    end;

    for I := List.Count -1 downto 0 do
      APopupMenu.Items.Remove(TMenuItem(List[I]));
  finally
    FreeAndNil(List)
  end;
end;
My previous solution will remove all the first level menu items, You can change it to

procedure TForm1RemoveFirstTier(APopupMenu: TPopupMenu);
var
  Item, ParentItem: TMenuItem;
  I: Integer;
  List: TList;
begin
  List := TList.Create;  //just maintain a list of the parent items
  try
    for I := 0 to APopupMenu.Items.Count -1 do
    begin
      ParentItem := APopupMenu.Items[I];
      if ParentItem.Count > 0 then
      begin
        while ParentItem.Count > 0 do
        begin
          Item := ParentItem.Items[0];
          ParentItem.Remove(Item);
          APopupMenu.Items.Add(Item);
        end;
        List.Add(ParentItem);
     end;
    end;

    for I := List.Count -1 downto 0 do
    begin
      Item := TMenuItem(List[I])
      APopupMenu.Items.Remove(Item);
      Item.Free;
    end;
  finally
    FreeAndNil(List)
  end;
end;

Or if you just want to remove from one known parent menu then you can pass it to the procedure as follows and make it even simpler

procedure TForm1.RemoveParentItem(APopupMenu: TPopupMenu; AParentItem: TMenuItem);
var
  Item: TMenuItem;
begin
  while AParentItem.Count > 0 do
  begin
    Item := AParentItem.Items[0];
    AParentItem.Remove(Item);
    APopupMenu.Items.Add(Item);
  end;

  APopupMenu.Items.Remove(AParentItem);
  AParentItem.Free;
end;
Avatar of Mike McCracken
Mike McCracken

This question has been classified as abandoned and is being closed as part of the Cleanup Program.  See my comment at the end of the question for more details.