1

I am trying to add NSStatusItem in a Delphi application for OSX. Searched for sample code to help me with that but got stuck when defining an interface:

Here is the code:

// Source: https://forums.embarcadero.com/thread.jspa?threadID=108449

unit Unit2;

interface

uses Macapi.ObjectiveC, Macapi.CocoaTypes, Macapi.Foundation, Macapi.AppKit,
Macapi.Helpers, Macapi.ObjcRuntime, System.TypInfo, FMX.Platform, FMX.Platform.Mac;

type
TFMXTrayItem = class(TOCLocal)
private
NSStatItem : NSStatusItem;
public
constructor Create;
destructor Destroy; override;
function GetObjectiveCClass: PTypeInfo; override;
procedure call_mymethod; cdecl;
end;

implementation

constructor TFMXTrayItem.Create;
var
NSContMenu : NSMenu;
NSContItem : NSMenuItem;
NSStatBar : NSStatusBar;
NSImg : NSImage;
AppBundle : NSBundle;
NSpImg: Pointer;
Path: String;
begin
inherited Create;

NSStatBar := TNSStatusBar.Create;
NSStatBar := TNSStatusBar.Wrap(TNSStatusBar.OCClass.systemStatusBar);
NSStatItem:= NSStatBar.statusItemWithLength(NSVariableStatusItemLength);
NSStatItem.setTarget(GetObjectID);

// Create context menu
NSContMenu := TNSMenu.Create;
NSContMenu := TNSMenu.Wrap(NSContMenu.initWithTitle(StrToNSStr('The caption')));

NSContItem:=TNSMenuItem.Create;
NSContItem:=TNSMenuItem.Wrap(NSContItem.initWithTitle(StrToNSStr('1. menuitem'),sel_getUid(PAnsiChar('call_mymethod')),StrToNSStr('')));
NSContItem.setTarget(GetObjectID);
NSContMenu.addItem(NSContItem);
NSContItem.release;


// Add menu
NSStatItem.retain;
NSStatItem.setHighlightMode(true);
NSStatItem.setMenu(NSContMenu);
NSContMenu.release;

// Get path to dir
AppBundle := TNSBundle.Wrap(TNSBundle.OCClass.mainBundle);
Path:=AppBundle.bundlePath.UTF8String+'/Contents/yourimage16x16.png';
NSpImg := TNSImage.Alloc.initWithContentsOfFile(StrToNSStr(Path));
// Create Icon
NSImg := TNSImage.Create;
NSImg := TNSImage.Wrap(NSpImg);
NSStatItem.setImage(NSImg);
NSImg.release;
end;

destructor TFMXTrayItem.Destroy;
begin
NSStatItem.release;
inherited;
end;

function TFMXTrayItem.GetObjectiveCClass: PTypeInfo;
begin
Result :=TypeInfo(IFMXTrayItem);
end;

procedure TFMXTrayItem.call_properties;
begin
// your event code of the menu item
end;

end.

Does anyone have any idea on how to declare the IFMXTrayItem interface?

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Jamie
  • 657
  • 7
  • 18
  • So, what is IFMXTrayItem? – David Heffernan Mar 06 '15 at 12:44
  • Found a sample of deriving from a Cocoa class: http://stackoverflow.com/a/26408689 I believe IFMXTrayItem is similar to the MyNSWindow interface defined in that sample but I am not sure what it would inherit from. – Jamie Mar 06 '15 at 12:56
  • Is it possible the author meant TFMXTrayItem – David Heffernan Mar 06 '15 at 13:00
  • That also went through my mind but most of the samples I find pass an interface when returning from GetObjectiveCClass . Here is another one: http://www.verydemo.com/demo_c134_i32581.html – Jamie Mar 06 '15 at 13:18

1 Answers1

2

Got it to work like this:

type

IFMXTrayItem = interface(NSObject)
['{7d2e4b38-61d9-4cf4-b78b-5f7c4188e9c0}']
  procedure call_mymethod; cdecl;
end;

later edit:

Added a GUID to the interface after reading this:

This GUID is used by the compiler to identify uniquely this interface. Strictly speaking, you can use an interface without the GUID, but you can’t get very far using them as much of the RTL and most frameworks that take advantage of interfaces will require that they have a GUID.

So that is a random GUID I generated but if you use this in your code you should generate your own GUID.

Jamie
  • 657
  • 7
  • 18