Link to home
Start Free TrialLog in
Avatar of efz
efzFlag for United States of America

asked on

FireMonkey - Adding Menu Items At Run Time

Hello Valued Experts,

For years I’ve used a few lines of code to maintain a history list at the bottom of the file menu of the last few files opened. I’m converting a Delphi program to FireMonkey and I’m discovering that the File menu’s InsertObject method causes a “List index out of bounds” error.

This is the line:

mnuFile.InsertObject(Idx1,Item);

Idx1 is 4 and there are 6 items in the File menu, so it wouldn’t seem the Idx1 variable is out of bounds.

If I change the Idx1 value to 1 I don’t get the error, but neither does the newly created menu item show up on the File menu.

Experimenting, I tried using AddObject(Item) and while I don’t get the error, the menu item doesn’t appear at the bottom of the File menu either.

I’m stuck. Any insight would be greatly appreciated.

Thanks in advance.
Avatar of Ferruccio Accalai
Ferruccio Accalai
Flag of Italy image

For what you're saying I guess that you have an index value different than the real one, like if you're considering some items that are not already inserted (but you are instead sure of yes). How do you retrieve your idx1 value?
Avatar of efz

ASKER

Thanks Ferruccio68,

The entire section of code is not that long. Here it is. I included some comments after the code to better explain what’s happening.

Idx1 := N1.Index+1;
If History.Count > 0 then
  begin
  For Pos := 0 to History.Count - 1 do
    begin
    Item := TMenuItem.Create(mnuFile);
    Item.Text := IntToStr(Pos + 1) + ' ' + History[Pos];
    Item.OnClick := ReOpenClick;
    mnuFile.InsertObject(Idx1,Item);
    end;
  end;

Open in new window

1. N1 is a TMenuItem that is a bar separator; Idx1 is an integer.  N1 is used to mark the dividing line between the File menu and the history list. Idx1 is supposed to be the zero-based position of the bar separator in the File menu. The File menu looks like this:

    New
    Open
    Save
    Save As
    Print
    -
    Exit

The value of N1.Index at run time is 5 which seems correct.

2. If there are history items (a TStringList of previously Opened files), then insert the file names as menu items.

3. The InsertObject line is the one that craps out as explained in the original question.
Your code seems right. Have you tested the mnuFile items count to see if it's ok in that moment? There are a bit of bugs about the InsertObject method that are under investigation on Embarcadero QualityCentral.
Maybe this is another one of those.
Avatar of efz

ASKER

That’s where I’m running into a little trouble. Delphi menus had arrays of items. A menu had an Insert method and you could ask for an Item.Count to determine the size of the array. FireMonkey menus are different. There is no array of Items and there is no Insert method. Instead FireMonkey menus have InsertObject and AddObject, but these commands don’t seem to have anything to do with manipulating the subitems in the menu. That’s another thing, when I ask for the ChildrenCount of the TMenuItem in question (File) it gives a value of 2 when in fact there are 7 items in the menu. Evidently the menu’s subitems (New, Open, etc.) are not considered children of the File menu, although this contrary to what you see in the Structure view where New, Open etc. are shown as children of File. Of course, that accounts for the out of bounds error because I’m trying to InsertObject at position 6 but the ChildrenCount is 2. I can’t make sense of this, can you?
The structure is different from the knowed Windows , maybe because the cross platform capability and compatibility.
Anyway it seems that any Top MenuItem is considered like a TMainMenu's child and maybe any of these children are called subitems or something else, as I'd expect.

So, saying that a File menu could be the first TMenuItem of a TMainMenu and for this have a Child index = 0, from my head, I should try mnuFile.Child[0].InsertObject(Idx1,Item)
( or maybe mnuFile.Children[0].InsertObject(Idx1,Item), I don't know about the FireMonkey syntax)

It's just I guess, I don't have FireMonkey
ASKER CERTIFIED SOLUTION
Avatar of efz
efz
Flag of United States of America image

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
Wow, I was quite next to the solution!

From your link:

uses
  Fmx.Platform;
 
mnuFile.Children[0].InsertObject(Idx1,Item);
if IsHandleValid(mnuFile.Handle) then
  Platform.UpdateMenuItem(mnuFile);


My guess

try mnuFile.Child[0].InsertObject(Idx1,Item)
( or maybe mnuFile.Children[0].InsertObject(Idx1,Item),


Lol, I'm ready to start with FireMonkey :)
Avatar of efz

ASKER

A final point of clarification. After further discussion with an Embarcadero team member, it would seem that the InsertObject and AddObject methods do not work in the context of FireMonkey's TMenuBar, although they do when used with TMainMenu.
Avatar of efz

ASKER

I received the correct answer from an Embarcadero technician/team member who has first hand knowledge of this issue and was able to test his solution.