Introduction
If you have a menu whose content is determined at run time, the best course
is to dynamically create the menu entries for the submenu, usually in the menu
OnPopup handler. The following is an example...
The Menu
The menu contains a placeholder for the submenu to be added - this greatly
simplifies dynamically adding items. The placeholder item has Visible = false
so it is never seen by the user, but it is visible to the programmer at design
time.
Indeed, the placeholder can be used as the vehicle for providing the event
handler to be used by the other items. Typically, all items in a dynamically
created menu share the same event handler, and use the menu caption or a tag
on the menu item to determine any specialization of the handler behavior.
The following is the menu for the example (which can be copied and pasted to
a form)...
object SamplePopup: TPopupMenu
object SomeEntry
Caption = 'Some Entry'
end
object PlaceholderForInsert: TMenuItem
Caption = 'Placeholder'
object SubmenuPlaceholder: TMenuItem
Caption = 'SubmenuPlaceholder'
Visible = False
OnClick = SubmenuPlaceholderClick
end
end
end
Adding The Submenu Entries
This part is now quite easy... Note that this example uses a table (definition
not shown) for menu item captions, and it is reloaded each time the popup menu
is popped up (so that changes to the table are instantly reflected).
void __fastcall TForm1::DynamicallyAddEntriesToMenu(TMenuItem *theSubmenuParent,TNotifyEvent
theClickHandler)
{
for (int Index = theSubmenuParent->Count-1; Index >
0; Index--) // Deletes old entries - leaves the invisible placeholder
{
theSubmenuParent->Delete(Index);
};
MenuItemTable->First();
while (!MenuItemTable->Eof)
{
TMenuItem *NewMenuItem =
new TMenuItem(this); // Owned by form, destroyed by form, or by this function
NewMenuItem->Caption = MenuItemTable->FieldByName("Caption")->AsString;
NewMenuItem->OnClick = theClickHandler;
theSubmenuParent->Add(NewMenuItem);
MenuItemTable->Next();
};
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SamplePopupPopup(TObject *Sender)
{
DynamicallyAddEntriesToMenu(SubmenuPlaceholder->Parent,SubmenuPlaceholder->OnClick);
}
Conclusion
Dynamically adding and deleting submenu entries is easy - and with the use
of the invisible placeholder item, it is even easier.
|