如何在下面的屏幕截图中的 Project1 以及退出上添加TMenuItem?
我创建了一个带有UseOSMenu属性的TMenuBar。 我添加的第一个TMenuItem是主栏中的第二个......
答案 0 :(得分:4)
您可以通过将IItemsContainer实现类的TMenuBar分配给Application.ApplicationMenuItems属性来实现此目的。
示例:
如果表单上有一个名为MenuBar1的菜单栏组件,那么您只需在表单构造函数(或OnCreate)中调用以下内容。
Application.ApplicationMenuItems := Menubar1;
然后,您可以使用第二个TMenuBar组件来定义其他菜单项。
我会指出您在ApplicationMenuItems属性上的wiki主题,但它没有其他帮助......
http://docwiki.embarcadero.com/VCL/XE2/en/FMX.Forms.TApplication.ApplicationMenuItems
答案 1 :(得分:2)
我创建了一个单元来试图管理我想要的东西...... 有了它,我可以使用特定的TMenuItem ...并移动它的子项目到应用程序子菜单...(我仍然不知道如何从头开始添加...)
我还使用Mehmed Ali的答案来管理分隔符......
unit uMenu;
interface
uses
FMX.Dialogs, System.SysUtils,
FMX.Menus
{$IFDEF MACOS}
,Macapi.ObjectiveC,MacApi.AppKit,MacApi.Foundation,FMX.Platform.Mac
{$ENDIF}
;
type
ManageMenu = class
private
{$IFDEF MACOS}
class procedure FixSeparatorItemsForMenuItem (MenuItem: NSMenuItem);
class procedure MoveItemsToMacApplicationMenu(source, target: NSMenuItem); overload;
class procedure MoveItemsToMacApplicationMenu(index: Integer); overload;
{$ENDIF}
public
class procedure FixSeparatorItemsForMac;
class procedure MoveItemsToMacApplicationMenu(index: Integer; menu: TMainMenu); overload;
class procedure MoveItemsToMacApplicationMenu(index: Integer; menu: TMenuBar); overload;
end;
implementation
{ ManageMenu }
{$IFDEF MACOS}
class procedure ManageMenu.FixSeparatorItemsForMenuItem(MenuItem:NSMenuItem);
var
i : Integer;
subItem: NSMenuItem;
begin
if (MenuItem.hasSubmenu = False) then exit;
for i := 0 to Pred(MenuItem.submenu.itemArray.count) do
begin
subItem := MenuItem.submenu.itemAtIndex(i);
if (subItem.title.isEqualToString(NSSTR('-'))= True) then
begin
MenuItem.submenu.removeItemAtIndex(i);
MenuItem.submenu.insertItem(TNSMenuItem.Wrap(TNSMenuItem.OCClass.separatorItem), i);
end
else
begin
FixSeparatorItemsForMenuItem(subItem);
end;
end;
end;
{$ENDIF}
class procedure ManageMenu.FixSeparatorItemsForMac;
{$IFDEF MACOS}
var
NSApp : NSApplication;
MainMenu: NSMenu;
AppItem : NSMenuItem;
i : Integer;
{$ENDIF}
begin
{$IFDEF MACOS}
NSApp := TNSApplication.Wrap(TNSApplication.OCClass.sharedApplication);
MainMenu := NSApp.mainMenu;
if (MainMenu <> nil) then
begin
for i := 0 to Pred(MainMenu.itemArray.Count) do
begin
AppItem := mainMenu.itemAtIndex(i);
FixSeparatorItemsForMenuItem(AppItem);
end;
end;
{$ENDIF}
end;
{$IFDEF MACOS}
class procedure ManageMenu.MoveItemsToMacApplicationMenu(source, target: NSMenuItem);
var
iLoop, iMax: Integer;
subItem : NSMenuItem;
begin
if (source.hasSubmenu = False) then exit;
iMax := Pred(source.submenu.itemArray.count);
for iLoop := iMax downto 0 do
begin
subItem := source.submenu.itemAtIndex(iLoop);
source.submenu.removeItemAtIndex(iLoop);
target.submenu.insertItem(subItem, 0);
end;
// Hide the parent
source.setHidden(True);
end;
{$ENDIF}
{$IFDEF MACOS}
class procedure ManageMenu.MoveItemsToMacApplicationMenu(index: Integer);
var
NSApp : NSApplication;
MainMenu: NSMenu;
source : NSMenuItem;
target : NSMenuItem;
begin
NSApp := TNSApplication.Wrap(TNSApplication.OCClass.sharedApplication);
MainMenu := NSApp.mainMenu;
if (MainMenu <> nil) then
begin
begin
if (MainMenu.itemArray.count > 1) then
begin
source := mainMenu.itemAtIndex(Succ(index));
target := mainMenu.itemAtIndex(0);
MoveItemsToMacApplicationMenu(source, target);
end;
end;
end;
end;
{$ENDIF}
class procedure ManageMenu.MoveItemsToMacApplicationMenu(index: Integer; menu: TMainMenu);
begin
{$IFDEF MACOS}
MoveItemsToMacApplicationMenu(index);
{$ELSE}
// (menu.Children[Succ(index)] as TMenuItem).Visible := False;
// menu.RemoveObject(...);
// ... I don't knwo how to remove items on Windows ;o(((
{$ENDIF}
end;
class procedure ManageMenu.MoveItemsToMacApplicationMenu(index: Integer; menu: TMenuBar);
begin
{$IFDEF MACOS}
MoveItemsToMacApplicationMenu(index);
{$ELSE}
if (menu.ChildrenCount > Succ(index)) and (menu.Children[Succ(index)] is TMenuItem) then
begin
// (menu.Children[Succ(index)] as TMenuItem).Visible := False;
// menu.RemoveObject(...);
// ... I don't knwo how to remove items on Windows ;o(((
// menu.BeginUpdate;
// menu.RemoveObject((menu.Children[Succ(index)] as TMenuItem));
// menu.RemoveFreeNotify((menu.Children[Succ(index)] as TMenuItem));
// menu.DeleteChildren;
// (menu.Children[Succ(index)] as TMenuItem).View.Visible := False;
// .Free;
// (menu.Children[Succ(index)] as TMenuItem).Destroy;
// menu.EndUpdate;
end;
{$ENDIF}
end;
end.
它按预期工作,这是我想要的OSX ...
procedure TfrmMain.FormActivate(Sender: TObject);
begin
if not bAlreadyActivated then
begin
bAlreadyActivated := True;
ManageMenu.FixSeparatorItemsForMac;
ManageMenu.MoveItemsToMacApplicationMenu(0, MainMenu1);
end;
end;
但现在,我在Windows上遇到了一个问题,因为无论我尝试什么,我仍然在Windows下显示我为Mac添加的菜单...; o(
答案 2 :(得分:1)
从Delphi XE7开始,Application.ApplicationMenuItems
属性不再存在。
您现在必须创建一个TMainMenu
项才能获得预期结果,无需分配。只需将TMainMenu
放到主表单上并添加项目,它们就会显示在OSX应用程序菜单中。