如何在Delphi XE2中将菜单项添加到Mac OS Finder [英] Howto add menu item to Mac OS Finder in Delphi XE2

查看:177
本文介绍了如何在Delphi XE2中将菜单项添加到Mac OS Finder的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用针对Mac OS和Windows的Delphi XE2应用程序。而且我想要集成到上下文菜单中。对于windows这个简单的任务。但是对于Mac OS,我不知道该怎么做。



我已经阅读了提供服务文档,并在Delphi中尝试了类似的代码,但没有运气。



查看Finder集成测试的简单代码。



App.dpr

 程序应用程序; 
使用
SysUtils,
{$ IFDEF MACOS}
AppKit,CocoaTypes,CoreFoundation,
CoreServices,Foundation,Mach,ObjCRuntime,
ObjectiveC,OCMarshal, OpenGL,QuartzCore,Security,
SystemConfiguration,
{$ ENDIF}
MessageProvider;
{$ IFDEF MACOS}
var
app:NSApplication;
提供者:TMessageProvider;
{$ ENDIF}

begin
Application.Initialize;

{$ IFDEF MACOS}
provider:= TMessageProvider.Create();

app:= TNSApplication.Alloc();
app.setServicesProvider(provider);
{$ ENDIF}

Application.CreateForm(TFormOSVersion,FormOSVersion);
Application.Run;
结束。

MessageProvider.pas

  unit MessageProvider; 

接口

使用
FMX.Dialogs
{$ IFDEF MACOS}
,AppKit,CocoaTypes,CoreFoundation,
CoreServices ,Foundation,Mach,ObjCRuntime,
ObjectiveC,OCMarshal,OpenGL,QuartzCore,Security,
SystemConfiguration
{$ ENDIF}
;

type
TMessageProvider = class
public
procedure simpleMessage(var userData:string; var error:string);
结束

实现

过程TMessageProvider.simpleMessage(var userData:string; var error:string);
begin
ShowMessage('来自服务的简单消息。
error:='';
结束

结束。

向info.plist添加配置

 < key> NSServices< / key> 
< array>
< dict>
< key> NSKeyEquivalent< / key>
< dict>
< key> default< / key>
< string> e< / string>
< / dict>
< key> NSMenuItem< / key>
< dict>
< key> default< / key>
< string> App / Message< / string>
< / dict>
< key> NSMessage< / key>
< string> simpleMesage< / string>
< key> NSPortName< / key>
< string> App< / string>
< / dict>
< / array>

在Mac OS应用程序上运行时挂起,有时会出现总线错误异常。 >

有人可以帮助解决这个问题吗?



或者Delphi XE2不支持这种功能?

解决方案

最后,我回到这个项目,成功注册了服务提供商并处理了服务请求。



首先我试图使用NSRegisterServicesProvider方法,但Macapi源码中没有这样的方法,所以我搜索了applicationDidFinishLaunching委托。使用它我注册了我的服务提供商:

  procedure TApplicationDelegate.applicationDidFinishLaunching(Notification:Pointer); 
var
autoReleasePool:NSAutoreleasePool;
app:NSApplication;
提供者:TMessageProvider;
begin
autoReleasePool:= TNSAutoreleasePool.Create;
try
autoReleasePool.init();

app:= TNSApplication.Wrap(TNSApplication.OCClass.sharedApplication);

provider:= TMessageProvider.Create();
app.setServicesProvider(provider.ObjId);
finally
autoReleasePool.release();
结束
结束

此外,我已经为服务提供商创建了界面(我认为这是ObjectiveC-Delphi桥梁工作所必需的) :

  IMessageProvider = interface(IObjectiveC)['{1EA9319A-8F99-4445-B435-48D5E73876FA}'] 
procedure simpleMessage(pBoard:Pointer; userData:Pointer; error:PPointer); cdecl;
结束

并从此界面和TOCLocal类继承了TMessageProvider。



此后,我的应用程序可以从上下文菜单中对服务请求做出反应。



我已经共享了我的项目来源。 这里他们是。


I'm working on Delphi XE2 application targetting Mac OS and Windows. And I want to have integration into context menu. For windows this is simple task. But for Mac OS I dont know how to do this.

I've read Providing a Service documentation and tried similar code in Delphi but with no luck.

Look at simple code for Finder integration trials.

App.dpr

program App;
uses
   SysUtils,
{$IFDEF MACOS}
  AppKit, CocoaTypes, CoreFoundation,
  CoreServices, Foundation, Mach, ObjCRuntime,
  ObjectiveC, OCMarshal, OpenGL, QuartzCore, Security,
  SystemConfiguration,
{$ENDIF}
  MessageProvider;
{$IFDEF MACOS}
var
  app: NSApplication;
  provider: TMessageProvider;
{$ENDIF}

begin
  Application.Initialize;

{$IFDEF MACOS}
  provider := TMessageProvider.Create();

  app := TNSApplication.Alloc();
  app.setServicesProvider(provider);
{$ENDIF}

  Application.CreateForm(TFormOSVersion, FormOSVersion);
  Application.Run;
end.

MessageProvider.pas

unit MessageProvider;

interface

uses
  FMX.Dialogs
{$IFDEF MACOS}
  , AppKit, CocoaTypes, CoreFoundation,
  CoreServices, Foundation, Mach, ObjCRuntime,
  ObjectiveC, OCMarshal, OpenGL, QuartzCore, Security,
  SystemConfiguration
{$ENDIF}
  ;

type
  TMessageProvider = class
  public
    procedure simpleMessage(var userData: string; var error: string);
  end;

implementation

procedure TMessageProvider.simpleMessage(var userData: string; var error: string);
begin
  ShowMessage('Simple message from service.');
  error := '';
end;

end.

Added configuration to info.plist

<key>NSServices</key>
<array>
  <dict>
     <key>NSKeyEquivalent</key>
     <dict>
         <key>default</key>
         <string>e</string>
     </dict>
     <key>NSMenuItem</key>
     <dict>
         <key>default</key>
         <string>App/Message</string>
     </dict>
     <key>NSMessage</key>
     <string>simpleMesage</string>
     <key>NSPortName</key>
     <string>App</string>            
  </dict>
</array>

When run this on Mac OS application hungs and sometimes crashes with 'Bus error' exception.

Can anybody help with this problem?

Or maybe Delphi XE2 doesnt support this kind of functionality?

解决方案

Finally, I returned to this project and successfully registered service provider and handled service request.

First of all I tried to use NSRegisterServicesProvider method, but there is no such method in Macapi sources, so I searched for applicationDidFinishLaunching delegate. Using it I registered my service provider:

procedure TApplicationDelegate.applicationDidFinishLaunching(Notification: Pointer);
var
  autoReleasePool: NSAutoreleasePool;
  app: NSApplication;
  provider: TMessageProvider;
begin
  autoReleasePool := TNSAutoreleasePool.Create;
  try
    autoReleasePool.init();

    app := TNSApplication.Wrap(TNSApplication.OCClass.sharedApplication);

    provider := TMessageProvider.Create();
    app.setServicesProvider(provider.ObjId);
  finally
    autoReleasePool.release();
  end;
end;

Also I have created interface for service provider (I think it is required for ObjectiveC-Delphi bridge work):

IMessageProvider = interface(IObjectiveC)['{1EA9319A-8F99-4445-B435-48D5E73876FA}']
    procedure simpleMessage(pBoard: Pointer; userData: Pointer; error: PPointer); cdecl;
end;

and inherited TMessageProvider from this interface and TOCLocal class.

After this my app can react to service request from context menu.

I've shared sources of my project. Here they are.

这篇关于如何在Delphi XE2中将菜单项添加到Mac OS Finder的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆