How to add menu items separators which work as expected on OSX?

On Windows platform, with the VCL , when we want to add a separator in a menu, we add a TMenuItem with a Caption := '-' ;

With FireMonkey , we add a TMenuItem with a Text := '-' ;

It works as expected on Windows platform, the item with the Text='-' is displayed as a separator.

But, when I run the same application on OSX , I have the minus sign visible...

I haven't found any property on the TMenuItem to specify it is a separator ...

I have tried with a TMainMenu and a TMenuBar ( UseOSMenu := True|False; ) and I still have this issue.

Any idea to create a real separator? (otherwise, I will check the OS and remove it if OSX...)


This is a bug in FireMonkey. I am sure they will solve it. But meanwhile you can use the below code. Call the procedure FixSeparatorItemsForMac in the OnActivate event of your main form.

Dont forget mac specific files in the uses list.

uses
...
  {$IFDEF MACOS}
  ,Macapi.ObjectiveC,MacApi.AppKit,MacApi.Foundation,FMX.Platform.Mac
  {$ENDIF}

{$IFDEF MACOS}

Procedure FixSeparatorItemsForMenuItem(MenuItem:NSMenuItem);
var i:Integer;
    subItem:NSMenuItem;
begin
  if (MenuItem.hasSubmenu = false) then exit;
  for i := 0 to MenuItem.submenu.itemArray.count -1 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;

Procedure FixSeparatorItemsForMac;
var NSApp:NSApplication;
    MainMenu:NSMenu;
    AppItem: NSMenuItem;
    i: Integer;
begin
  NSApp := TNSApplication.Wrap(TNSApplication.OCClass.sharedApplication);
  MainMenu := NSApp.mainMenu;
  if (MainMenu <> nil) then
  begin
    for i := 0 to MainMenu.itemArray.count -1 do
    begin
      AppItem := mainMenu.itemAtIndex(i);
      FixSeparatorItemsForMenuItem(AppItem);
    end;

  end;
end;
{$ENDIF}

I never programmed for the Mac, and I don't eveb have a Mac but out of curiosity I found some Apple Documentation about it.

The Menu Separator item is a disabled blank menu item, maybe you can fake with that:

separatorItem

Returns a menu item that is used to separate logical groups of menu commands. + (NSMenuItem *)separatorItem Return Value

A menu item that is used to separate logical groups of menu commands.

Discussion

This menu item is disabled. The default separator item is blank space.

(From: http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSMenuItem_Class/Reference/Reference.html#//apple_ref/doc/c_ref/NSMenuItem)


I don't have the facilities to test this, but it's worth a try.

By default, FireMonkey creates it's own fully styled menus, but set the TMenuBar.UseOSMenu property to true and it uses OS calls to create the menus.

You can then combine this with the advice for creating Cocoa menus already discussed.

From http://docwiki.embarcadero.com/RADStudio/en/FireMonkey_Application_Design#Menus :

"Setting the TMenuBar.UseOSMenu property to True causes FireMonkey to create the menu tree with OS calls, resulting in a native menu. On Windows, this menu is at the top of the parent form, and displayed using the current Appearance theme. On Mac OS X, the menu is displayed in the global menu bar on top of the main screen whenever the application has focus."

链接地址: http://www.djcxy.com/p/91070.html

上一篇: 引用在运行时创建的组件

下一篇: 如何添加在OSX上按预期工作的菜单项分隔符?