Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.


Welcome, Guest
Guest Settings
Help

Thread: How to associate a file type with a FMX/OS X application??


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 9 - Last Post: Feb 21, 2018 2:39 PM Last Post By: Don Rowe Threads: [ Previous | Next ]
Marc Jansen

Posts: 3
Registered: 6/15/11
How to associate a file type with a FMX/OS X application??  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 11, 2015 12:15 PM
Know anybody, how to associate a file type with a FMX/OS X application? I try to translate the Delphi-Code in C++

[https://delphihaven.wordpress.com/2012/08/14/associating-a-file-type-on-osx-part3/]

but it does not work:

__interface INTERFACE_UUID("{BE9AEDB7-80AC-49B1-8921-F226CC9310F4}") NSApplicationDelegate2 : public System::IInterface
{
virtual bool __fastcall application(void *theApplication, CFStringRef openFile) = 0;
};
typedef System::DelphiInterface<NSApplicationDelegate2> _di_NSApplicationDelegate2;
typedef void (__closure *TOpenFileEvent) (UnicodeString FileName);

// Aggregatee
class TCppNSApplicationDelegate: public TCppAggregatedObject<NSApplicationDelegate2>
{
public:
TOpenFileEvent OnOpenFile;

__fastcall TCppNSApplicationDelegate(const _di_IInterface Controller) : TCppAggregatedObject<NSApplicationDelegate2>(Controller)
{}

bool __fastcall application(void *theApplication, CFStringRef openFile)
{
UnicodeString S;
unsigned short b[100];
CFRange Range;
if(OnOpenFile == NULL) return false;
Range.location = 0;
Range.length = CFStringGetLength(openFile);
CFStringGetCharacters(openFile, Range, b);

b[Range.length]='\0';
S = UTF8ToString((char*)b);

try {OnOpenFile(S);}
catch(...) {return false;}
return true;
}

void applicationDidFinishLaunching(void *Notification)
{}
void applicationWillTerminate(void *Notification)
{}
};

// Aggregator
class TCppClass : public TInterfacedObject
{
private:
TCppNSApplicationDelegate* obj;
NSApplicationDelegate2* FNSApplicationDelegate2;
protected:
void initAggregatee(const TOpenFileEvent OnOpenFile)
{
_di_IInterface punk;
GetInterface(punk);
_di_NSApplicationDelegate2 adder;
(obj = new TCppNSApplicationDelegate(punk))->GetInterface(adder);
obj->OnOpenFile = OnOpenFile;
FNSApplicationDelegate2 = adder;
}
public:
__fastcall TCppClass(const TOpenFileEvent OnOpenFile)
{
initAggregatee(OnOpenFile);
}
__fastcall ~TCppClass()
{
delete obj;
}
__property NSApplicationDelegate2* myNSApplicationDelegate = {read=FNSApplicationDelegate2, implements};
};

void InstallApplicationDelegate(const TOpenFileEvent OnOpenFile)
{
TCppClass* ptr;
_di_NSApplicationDelegate2 ia;

if (!((ptr = new TCppClass(OnOpenFile))->GetInterface(ia)))
{
delete ptr;
}
else
{
TNSApplication::Wrap(TNSApplication::OCClass->sharedApplication())->setDelegate(ia);
}
}

// At the Application....

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
InstallApplicationDelegate(OnOpenFile);
}

void TForm1::OnOpenFile(UnicodeString FileName)
{
// Do something with the File.
}
Remy Lebeau (Te...


Posts: 9,442
Registered: 12/23/01
Re: How to associate a file type with a FMX/OS X application??  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 11, 2015 7:16 PM   in response to: Marc Jansen in response to: Marc Jansen
Marc wrote:

Know anybody, how to associate a file type with a FMX/OS X
application? I try to translate the Delphi-Code in C++

[https://delphihaven.wordpress.com/2012/08/14/associating-a-file-type-on-osx-part3/]

but it does not work:

Define "does not work". Is there a compile-time error? A run-time error?

bool __fastcall application(void *theApplication, CFStringRef openFile)

You don't need the b[] array. The original Delphi code was not using such
an array, it was passing the UnicodeString's memory block directly to CFStringGetCharacters(),
eg:

bool __fastcall application(void *theApplication, CFStringRef openFile)
{
    if (OnOpenFile == NULL) return false;
    UnicodeString S;
    CFRange Range;
    Range.location = 0;
    Range.length = CFStringGetLength(openFile);
    S.SetLength(Range.length);
    CFStringGetCharacters(openFile, Range, S.c_str());
    try {
        OnOpenFile(S);
    }
    catch(...) {return false;}
    return true;
}


class TCppClass : public TInterfacedObject

Why do you need two aggregate classes? The original Delphi code only uses
1 class. You are doing a lot more work. Now, I am not an OSX developer,
or even an FMX developer, but it seems to me that you should be able to get
rid of TCppClass and use TCppNSApplicationDelegate by itself as the sharedApplication
delegate.

If nothing else, your initAggregatee() function looks broken to me.

You are creating an TCppNSApplicationDelegate object and assigning it to
the local _di_NSApplicationDelegate2 variable, thus increasing its reference
count to 1. Then you are assigning that _di_NSApplicationDelegate2 to your
NSApplicationDelegate2* member pointer. The reference count is not increased.
When initAggregatee() exits, the _di_NSApplicationDelegate2 variable goes
out of scope, decrementing the reference count to 0, thus freeing the object,
leaving both the TCppNSApplicationDelegate* and NSApplicationDelegate2* members
pointers pointing at invalid memory.

If you fix that so the TCppNSApplicationDelegate object is not freed prematurely,
then you have a new problem. TCppNSApplicationDelegate woud be holding a
reference-counted interface to the TCppObject object, and TCppObject would
be holding a reference-counted interface to the TCppNSApplicationDelegate
object, thus their respective reference counts would never fall to 0 and
both objects would be leaked.

I think you need to get rid of the 2-class approach and do something more
like the following, which is closer to what the original Delphi code was
doing:

#include <Macapi.ObjectiveC.hpp>
#include <Macapi.CoreFoundation.hpp>
#include <Macapi.CocoaTypes.hpp>
#include <Macapi.AppKit.hpp>
#include <FMX.Forms.hpp>
 
__interface INTERFACE_UUID("{BE9AEDB7-80AC-49B1-8921-F226CC9310F4}")
NSApplicationDelegate2 : public NSApplicationDelegate
{
    virtual bool __fastcall application(void *theApplication, CFStringRef 
openFile) = 0;
};
 
typedef System::DelphiInterface<NSApplicationDelegate2> _di_NSApplicationDelegate2;
typedef void __fastcall (__closure *TOpenFileEvent) (const String FileName);
 
class TNSApplicationDelegate2 : public TOCLocal, public NSApplicationDelegate2
{
private:
    TOpenFileEvent FOnOpenFile;
 
public:
    __fastcall TNSApplicationDelegate2(const TOpenFileEvent AOnOpenFile)
        : TOCLocal(), FOnOpenFile(AOnOpenFile)
    {
    }
 
    void __cdecl applicationDidFinishLaunching(void *Notification);
    {
      /* The default FMX delegate doesn't do anything here, so nor will we. 
*/
    }
 
    void _cdecl applicationWillTerminate(void *Notification)
    {
        delete Fmx::Forms::Application;
        Fmx::Forms::Application = NULL;
    }
 
    bool __cdecl application(void *theApplication, CFStringRef openFile)
    {
        if (!FOnOpenFile) return false;
 
        CFRange Range;
        Range.location = 0;
        Range.length = CFStringGetLength(openFile);
 
        String S;
        S.SetLength(Range.length);
        CFStringGetCharacters(openFile, Range, S.c_str());
 
        try
        {
            FOnOpenFile(S);
        }
        catch (const Exception &e)
        {
            Fmx::Forms::Application->HandleException(&e);
            return false;
        }
        return true;
    }
};
 
_di_NSApplicationDelegate2 Delegate;
 
void InstallApplicationDelegate2(const TOpenFileEvent AOnOpenFile)
{
    NSApplication *NSApp = TNSApplication::Wrap(TNSApplication::OCClass->sharedApplication());
    Delegate = (NSApplicationDelegate2*) new TNSApplicationDelegate2(AOnOpenFile);
    NSApp->setDelegate(Delegate);
}   
 
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    InstallApplicationDelegate(&OnOpenFile);
}
 
void __fastcall TForm1::OnOpenFile(const String FileName)
{
    // Do something with the File...
}


--
Remy Lebeau (TeamB)
Marc Jansen

Posts: 3
Registered: 6/15/11
Re: How to associate a file type with a FMX/OS X application??  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 15, 2015 6:27 AM   in response to: Marc Jansen in response to: Marc Jansen
I try the following code:

#include <MacAPI.ObjectiveC.hpp>
#include <MacAPI.AppKit.hpp>
#include <MacAPI.Foundation.hpp>
#include <MacAPI.CocoaTypes.hpp>
#include <MacAPI.Helpers.hpp>
#include <FMX.Helpers.Mac.hpp>
#include <FMX.Platform.Mac.hpp>
#include <Macapi.CoreFoundation.hpp>
#include <FMX.Forms.hpp>
 
 __interface INTERFACE_UUID("{BE9AEDB7-80AC-49B1-8921-F226CC9310F4}") NSApplicationDelegate2 : public NSApplicationDelegate
{
 virtual bool __fastcall application(void *theApplication, CFStringRef openFile) = 0;
};
 
typedef System::DelphiInterface<NSApplicationDelegate2> _di_NSApplicationDelegate2;
typedef void (__closure *TOpenFileEvent) (const String FileName);
 
class TNSApplicationDelegate2 : public TOCLocal, public NSApplicationDelegate2
{
 private:
  TOpenFileEvent FOnOpenFile;
 
 public:
  __fastcall TNSApplicationDelegate2(const TOpenFileEvent AOnOpenFile)
		: TOCLocal(), FOnOpenFile(AOnOpenFile)
   {
   }
 
  void __cdecl applicationDidFinishLaunching(_di_NSNotification Notification)
   {
   // The default FMX delegate doesn't do anything here, so nor will we.
   }
 
  NativeInt __cdecl applicationShouldTerminate(_di_NSNotification Notification)
   {
	return NSTerminateNow;
   }
 
  HRESULT __stdcall QueryInterface(const REFIID riid, void** ppv)
   {
	return TInterfacedObject::QueryInterface(riid, (void*)ppv);
   }
 
  ULONG __stdcall AddRef()
   {
	return 1; // increment reference count taken threading into account
   }
 
  ULONG __stdcall Release()
   {
	return 1;
   }
 
  _di_NSMenu __cdecl applicationDockMenu(_di_NSApplication sender)
   {
	return NULL;
   }
 
  void __cdecl applicationWillTerminate(_di_NSNotification Notification)
   {
	delete Fmx::Forms::Application;
	Fmx::Forms::Application = NULL;
   }
 
  bool __fastcall application(void *theApplication, CFStringRef openFile)
   {
	if (!FOnOpenFile) return false;
 
	CFRange Range;
	Range.location = 0;
	Range.length = CFStringGetLength(openFile);
 
	String S;
	S.SetLength(Range.length);
	CFStringGetCharacters(openFile, Range, (unsigned short*)S.c_str());
 
	try
	 {
	  FOnOpenFile(S);
	 }
	catch (const Exception &e)
	 {
	  Fmx::Forms::Application->HandleException(&e);
	  return false;
	 }
	 return true;
   }
};
 
_di_NSApplicationDelegate2 Delegate;
 
void InstallApplicationDelegate2(const TOpenFileEvent AOnOpenFile)
{
 NSApplication *NSApp = TNSApplication::Wrap(TNSApplication::OCClass->sharedApplication());
 Delegate = (NSApplicationDelegate2*) new TNSApplicationDelegate2(AOnOpenFile);
 NSApp->setDelegate(Delegate);
}


Call in the application:
 
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
 InstallApplicationDelegate2(&OnOpenFile);
}
 
void TForm1::OnOpenFile(const String FileName)
{
 // Do something with the File...
}


Compile works without error. But there are runntime error:

Exception: EObjectiveC with Message 'RTTI for Type NSApplicationDelegate2 not found. Possibly missing {$M+}?'.

at this line:

 
Delegate = (NSApplicationDelegate2*) new TNSApplicationDelegate2(AOnOpenFile);


I tried
 __declspec(delphirtti)
but still the same.
Remy Lebeau (Te...


Posts: 9,442
Registered: 12/23/01
Re: How to associate a file type with a FMX/OS X application??  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 15, 2015 11:03 AM   in response to: Marc Jansen in response to: Marc Jansen
Marc wrote:

ULONG __stdcall AddRef()
{
return 1; // increment reference count taken threading into account
}

ULONG __stdcall Release()
{
return 1;
}

Why are you disabling reference counting?

Compile works without error. But there are runntime error:

Exception: EObjectiveC with Message 'RTTI for Type NSApplicationDelegate2
not found. Possibly missing {$M+}?'.

at this line:

Delegate = (NSApplicationDelegate2*) new TNSApplicationDelegate2(AOnOpenFile);


I tried
 __declspec(delphirtti)
but still the same.

Where did you apply it exactly?

--
Remy Lebeau (TeamB)
Marc Jansen

Posts: 3
Registered: 6/15/11
Re: How to associate a file type with a FMX/OS X application??  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 4, 2015 1:03 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Unfortunately, the problem is still present. I will only write an Application, that shows a file, if I click one on the Finder...

Problem: "Exception: EObjectiveC with Message 'RTTI for Type NSApplicationDelegate2 not found. Possibly missing {$M+}?'."

I tried every combination from
__declspec(delphirtti)
,
#pragma explicit_rtti
or compiler settings.

#pragma explicit_rtti methods()
 
__declspec(delphirtti) __interface INTERFACE_UUID("{BE9AEDB7-80AC-49B1-8921-F226CC9310F4}") NSApplicationDelegate2 : public NSApplicationDelegate
{
 virtual bool __fastcall application(void *theApplication, CFStringRef openFile) = 0;
};
 
typedef __declspec(delphirtti) System::DelphiInterface<__declspec(delphirtti) NSApplicationDelegate2> __declspec(delphirtti) _di_NSApplicationDelegate2;
 
class __declspec(delphirtti) TNSApplicationDelegate2 : public TOCLocal, public NSApplicationDelegate2
{
 private:
  TOpenFileEvent FOnOpenFile;
 
 public:
  __fastcall TNSApplicationDelegate2(const TOpenFileEvent AOnOpenFile)
		: TOCLocal(), FOnOpenFile(AOnOpenFile)
   {
	FOnOpenFile = AOnOpenFile;
   }
 
  void __cdecl applicationDidFinishLaunching(_di_NSNotification Notification)
   {
   // The default FMX delegate doesn't do anything here, so nor will we.
   }
 
  NativeInt __cdecl applicationShouldTerminate(_di_NSNotification Notification)
   {
	return NSTerminateNow;
   }
 
  HRESULT __stdcall QueryInterface(const REFIID riid, void** ppv)
   {
	return TInterfacedObject::QueryInterface(riid, (void*)ppv);
   }
 
  ULONG __stdcall AddRef()
   {
	return 1; // increment reference count taken threading into account
   }
 
  ULONG __stdcall Release()
   {
	return 1;
   }
 
  _di_NSMenu __cdecl applicationDockMenu(_di_NSApplication sender)
   {
	return NULL;
   }
 
  void __cdecl applicationWillTerminate(_di_NSNotification Notification)
   {
	delete Fmx::Forms::Application;
	Fmx::Forms::Application = NULL;
   }
 
  bool __fastcall application(void *theApplication, CFStringRef openFile)
   {
	if (!FOnOpenFile) return false;
 
	CFRange Range;
	Range.location = 0;
	Range.length = CFStringGetLength(openFile);
 
	String S;
	S.SetLength(Range.length);
	CFStringGetCharacters(openFile, Range, (unsigned short*)S.c_str());
 
	try
	 {
	  FOnOpenFile(S);
	 }
	catch (const Exception &e)
	 {
	  Fmx::Forms::Application->HandleException(&e);
	  return false;
	 }
	 return true;
   }
};
 
__declspec(delphirtti) _di_NSApplicationDelegate2 Delegate;
 
void InstallApplicationDelegate2(const TOpenFileEvent AOnOpenFile)
{
 NSApplication *NSApp = TNSApplication::Wrap(TNSApplication::OCClass->sharedApplication());
 Delegate = dynamic_cast<NSApplicationDelegate2*>(new TNSApplicationDelegate2(AOnOpenFile));
 if(Delegate) NSApp->setDelegate(Delegate);
}
 
Remy Lebeau (Te...


Posts: 9,442
Registered: 12/23/01
Re: How to associate a file type with a FMX/OS X application??  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 4, 2015 6:05 PM   in response to: Marc Jansen in response to: Marc Jansen
Marc wrote:

Problem: "Exception: EObjectiveC with Message 'RTTI for Type
NSApplicationDelegate2 not found. Possibly missing {$M+}?'."

I tried every combination from
__declspec(delphirtti)
,
#pragma explicit_rtti
or compiler settings.

Then you will most likely need to write your TNSApplicationDelegate2 class
in Delphi (just like all of the examples show) instead of in C++. You can
add a Delphi .pas file to a C++Builder projct, and C++Builder's own Delphi
compiler will generate a C++ .hpp file that you can then #include in your
C++ code. For example:

MyAppDelegate.pas:

unit MyAppDelegate;
 
interface
 
uses
  Macapi.ObjectiveC,
  Macapi.CoreFoundation,
  Macapi.CocoaTypes,
  Macapi.AppKit;
 
type
  NSApplicationDelegate2 = interface(NSApplicationDelegate)
    ['{BE9AEDB7-80AC-49B1-8921-F226CC9310F4}']
    function application(theApplication: Pointer; openFile: CFStringRef): 
Boolean; cdecl;
  end;
 
  TOpenFileEvent = procedure(const AFileName: string) of object;
 
  TNSApplicationDelegate2 = class(TOCLocal, NSApplicationDelegate2)
  private
    FOnOpenFile: TOpenFileEvent;
  public
    constructor Create(const AOnOpenFile: TOpenFileEvent);
 
    procedure applicationDidFinishLaunching(Notification: NSNotification); 
cdecl;
    function applicationShouldTerminate(Notification: NSNotification): NativeInt; 
cdecl;
    function applicationDockMenu(sender: NSApplication): NSMenu; cdecl;
    procedure applicationWillTerminate(Notification: NSNotification); cdecl;
    function application(theApplication: Pointer; openFile: CFStringRef): 
Boolean; cdecl;
  end;
 
procedure InstallApplicationDelegate2(const AOnOpenFile: TOpenFileEvent);
 
implementation
 
uses
  FMX.Forms;
 
constructor TNSApplicationDelegate2.Create(const AOnOpenFile: TOpenFileEvent);
begin
  inherted Create;
  FOnOpenFile := AOnOpenFile;
end;
 
procedure TNSApplicationDelegate2.applicationDidFinishLaunching(Notification: 
NSNotification);
begin
  // The default FMX delegate doesn't do anything here, so nor will we.
end;
 
function TNSApplicationDelegate2.applicationShouldTerminate(Notification: 
NSNotification): NativeInt; cdecl;
begin
  Result := NSTerminateNow;
end;
 
function TNSApplicationDelegate2.applicationDockMenu(sender: NSApplication): 
NSMenu; cdecl;
begin
  Result := nil;
end;
 
procedure TNSApplicationDelegate2.applicationWillTerminate(Notification: 
NSNotification); cdecl;
begin
  FreeAndNil(FMX.Forms.Application);
end;
 
function TNSApplicationDelegate2.application(theApplication: Pointer; openFile: 
CFStringRef): Boolean; cdecl;
var
  Range: CFRange;
  S: String;
begin
  Result := Assigned(FOnOpenFile);
  if not Result then Exit;
  Range.location := 0;
  Range.length := CFStringGetLength(openFile);
  SetLength(S, Range.length);
  CFStringGetCharacters(openFile, Range, PChar(S));
  try
    FOnOpenFile(S);
  except
    on E: Exception do
    begin
      FMX.Forms.Application.HandleException(E);
      Result := False;
    end;
  end;
end;
 
var
  Delegate: NSApplicationDelegate2;
 
procedure InstallApplicationDelegate2(const AOnOpenFile: TOpenFileEvent);
var
  NSApp: NSApplication;
begin
  NSApp := TNSApplication.Wrap(TNSApplication.OCClass.sharedApplication);
  Delegate := TNSApplicationDelegate2.Create(AOnOpenFile);
  NSApp.setDelegate(Delegate);
end;
 
end.


#include "MyAppDelegate.hpp"
 
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    InstallApplicationDelegate(&OnOpenFile);
}
 
void _fastcall TForm1::OnOpenFile(const UnicodeString AFileName)
{
    // Do something with AFileName...
}


I would probably even take it a step further and move the delegate code inside
the Delphi unit's implementation so it is completely hidden from the generated
.hpp file:

unit MyAppDelegate;
 
interface
 
type
  TOpenFileEvent = procedure(const AFileName: string) of object;
 
procedure InstallApplicationDelegate2(const AOnOpenFile: TOpenFileEvent);
 
implementation
 
uses
  Macapi.ObjectiveC,
  Macapi.CoreFoundation,
  Macapi.CocoaTypes,
  Macapi.AppKit,
  FMX.Forms;
 
type
  NSApplicationDelegate2 = interface(NSApplicationDelegate)
    ['{BE9AEDB7-80AC-49B1-8921-F226CC9310F4}']
    function application(theApplication: Pointer; openFile: CFStringRef): 
Boolean; cdecl;
  end;
 
  TNSApplicationDelegate2 = class(TOCLocal, NSApplicationDelegate2)
  private
    FOnOpenFile: TOpenFileEvent;
  public
    constructor Create(const AOnOpenFile: TOpenFileEvent);
 
    procedure applicationDidFinishLaunching(Notification: NSNotification); 
cdecl;
    function applicationShouldTerminate(Notification: NSNotification): NativeInt; 
cdecl;
    function applicationDockMenu(sender: NSApplication): NSMenu; cdecl;
    procedure applicationWillTerminate(Notification: NSNotification); cdecl;
    function application(theApplication: Pointer; openFile: CFStringRef): 
Boolean; cdecl;
  end;
 
constructor TNSApplicationDelegate2.Create(const AOnOpenFile: TOpenFileEvent);
begin
  inherted Create;
  FOnOpenFile := AOnOpenFile;
end;
 
procedure TNSApplicationDelegate2.applicationDidFinishLaunching(Notification: 
NSNotification);
begin
  // The default FMX delegate doesn't do anything here, so nor will we.
end;
 
function TNSApplicationDelegate2.applicationShouldTerminate(Notification: 
NSNotification): NativeInt; cdecl;
begin
  Result := NSTerminateNow;
end;
 
function TNSApplicationDelegate2.applicationDockMenu(sender: NSApplication): 
NSMenu; cdecl;
begin
  Result := nil;
end;
 
procedure TNSApplicationDelegate2.applicationWillTerminate(Notification: 
NSNotification); cdecl;
begin
  FreeAndNil(FMX.Forms.Application);
end;
 
function TNSApplicationDelegate2.application(theApplication: Pointer; openFile: 
CFStringRef): Boolean; cdecl;
var
  Range: CFRange;
  S: String;
begin
  Result := Assigned(FOnOpenFile);
  if not Result then Exit;
  Range.location := 0;
  Range.length := CFStringGetLength(openFile);
  SetLength(S, Range.length);
  CFStringGetCharacters(openFile, Range, PChar(S));
  try
    FOnOpenFile(S);
  except
    on E: Exception do
    begin
      FMX.Forms.Application.HandleException(E);
      Result := False;
    end;
  end;
end;
 
var
  Delegate: NSApplicationDelegate2;
 
procedure InstallApplicationDelegate2(const AOnOpenFile: TOpenFileEvent);
var
  NSApp: NSApplication;
begin
  NSApp := TNSApplication.Wrap(TNSApplication.OCClass.sharedApplication);
  Delegate := TNSApplicationDelegate2.Create(AOnOpenFile);
  NSApp.setDelegate(Delegate);
end;
 
end.


--
Remy Lebeau (TeamB)
Victor Stoian

Posts: 9
Registered: 6/22/00
Re: How to associate a file type with a FMX/OS X application??  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 10, 2015 2:52 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi Remy,

i tried to implement your MyAppDelegate using your code above in Delphi X Seattle and at compiling i get the error message "Interface-method NSApplicationDelegate.applicationShouldTerminate missing.
Could you give me a hint to why?

Victor
Dmitry Kirkinsky

Posts: 10
Registered: 11/12/02
Re: How to associate a file type with a FMX/OS X application??  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 6, 2017 9:47 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hello

MyAppDelegate.pas:

The code works, but only if the application is already started. If the application is not started and you doubleclick the associated data file, the application starts but the TNSApplicationDelegate2.application method doesn't execute. Is this a bug? Any ideas how to resolve this? Berlin upd. 1.

-Dmitry
Don Rowe

Posts: 37
Registered: 7/1/11
Re: How to associate a file type with a FMX/OS X application??  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2018 2:39 PM   in response to: Dmitry Kirkinsky in response to: Dmitry Kirkinsky
Perhaps I'm beating a dead horse, but we're so close.

I'm using c++, Tokyo update 1. After a couple changes to the above Delphi code:
function applicationShouldTerminate(Notification: NSNotification): NSInteger; cdecl; // Replace return type
// Added these as compiler complained they were missing
procedure TNSApplicationDelegate2.applicationDidHide(Notification : NSNotification);
begin
end;
procedure TNSApplicationDelegate2.applicationDidUnhide(Notification : NSNotification);
begin
end;
procedure TNSApplicationDelegate2.applicationWillTerminate(Notification : NSNotification); cdecl;
begin
// FireMonkey handles all this later
// Anything here crashes on exit as Firemonkey tries to do the same
end;

When my program starts running, OSX calls TNSApplicationDelegate2.application() with an empty string, even if I launch by double-clicking an assigned file type.

Once my program is running, I can right-click an assigned file type and select "open with". OSX calls TNSApplicationDelegate2.application() with the correct filename and the new file loads as expected.

Has anyone solved this? It's really frustrating that something so fundamental takes so much work.

Dmitry Kirkinsky wrote:
Hello

MyAppDelegate.pas:

The code works, but only if the application is already started. If the application is not started and you doubleclick the associated data file, the application starts but the TNSApplicationDelegate2.application method doesn't execute. Is this a bug? Any ideas how to resolve this? Berlin upd. 1.

-Dmitry
Victor Stoian

Posts: 9
Registered: 6/22/00
Re: How to associate a file type with a FMX/OS X application??  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 15, 2016 7:37 AM   in response to: Marc Jansen in response to: Marc Jansen
bump
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02