Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 如何在OSX上的应用程序名称下创建子项菜单?_Macos_Delphi_Menuitem_Delphi Xe2_Firemonkey - Fatal编程技术网

Macos 如何在OSX上的应用程序名称下创建子项菜单?

Macos 如何在OSX上的应用程序名称下创建子项菜单?,macos,delphi,menuitem,delphi-xe2,firemonkey,Macos,Delphi,Menuitem,Delphi Xe2,Firemonkey,如何在项目1及以上添加TMenuItem在下面的屏幕截图上退出 我已经创建了一个选中属性UseOSMenu的TMenuBar。 我添加的第一个TMenuItem是主栏中的第二个…我创建了一个单元来尝试管理我想要的。。。 有了它,我可以使用一个特定的项目。。。并将其子项移动到应用程序子菜单中。。。(我仍然不知道如何从头开始添加一个…) 我还使用来自的答案来管理分离器 unit uMenu; interface uses FMX.Dialogs, System.SysUtils, FMX.

如何在项目1及以上添加TMenuItem在下面的屏幕截图上退出

我已经创建了一个选中属性UseOSMenu的TMenuBar。
我添加的第一个TMenuItem是主栏中的第二个…

我创建了一个单元来尝试管理我想要的。。。 有了它,我可以使用一个特定的项目。。。并将其子项移动到应用程序子菜单中。。。(我仍然不知道如何从头开始添加一个…)

我还使用来自的答案来管理分离器

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.

但现在,我在Windows上遇到了一个问题,因为无论我尝试什么,我仍然会在Windows下显示我为Mac添加的菜单;o(

您可以通过将IItemsContainer实现类的TMenuBar分配给Application.ApplicationMenuItems属性来完成此操作

例如:

如果表单上有一个名为MenuBar1的菜单栏组件,那么您只需在表单构造函数(或OnCreate)中调用以下内容

Application.ApplicationMenuItems:=Menubar1;

然后,您可以使用第二个TMenuBar组件来定义其他菜单项

我想让您指向ApplicationMenuItems属性上的wiki主题,但它没有其他帮助


从Delphi XE7开始,
Application.ApplicationMenuItems
属性不再存在


您现在必须创建一个
TMainMenu
项才能获得预期的结果,无需分配它。只需将一个
TMainMenu
放到主窗体上并添加您的项,它们就会出现在OSX应用程序菜单中。

额外的ifdef应该会处理that@Johan:在什么地方(我发现的唯一方法是仅在osx上创建菜单项…但是,这意味着在源代码中而不是dfm中动态创建菜单项…这不太方便用户…这是您的意思还是您有其他想法?我的想法是为osx和Windows定义一个单独的源代码。两个完全不同的树。请注意,更改Windows中的ystemmenu是一个非常罕见的东西,根本不推荐使用,因此通常您会在
文件
菜单下使用。嗯..我明白了..我可以为每个平台创建两个不同的数据模块..一个用于每个平台,一个用于ifdef…好主意,谢谢!在XE7中,此属性不存在,在
TApplication
.也许是搬到别处去了?
procedure TfrmMain.FormActivate(Sender: TObject);
begin
  if not bAlreadyActivated then
  begin
    bAlreadyActivated := True;
    ManageMenu.FixSeparatorItemsForMac;
    ManageMenu.MoveItemsToMacApplicationMenu(0, MainMenu1);
  end;
end;