Whiler
Whiler

Reputation: 8086

Only one application instance with FireMonkey

With FireMonkey and a multi-platform application (Windows + Mac OS X), how to have only one instance of an application running at the same time?

If a previous instance is already running, how to set it as the desktop foreground window?

Upvotes: 2

Views: 2663

Answers (1)

mehmed.ali
mehmed.ali

Reputation: 362

Both for Windows and OSX you can get the list of running applications and check if yours is in the list before you close with a message. In OSX you can get the list with lauchedApplications method of NSWorkspace, and in Windows you can use the toolhelp32 library for same purpose. Here are the related codes from TPlatformExtensions class which I have blogged in my website.

For OSX:

uses Macapi.AppKit, Macapi.Foundation;

class procedure TPlatformExtensionsMac.GetRunningApplications(
  Applist: TStringlist);
var
  fWorkSpace:NSWorkSpace;
  list:NSArray;
  i: Integer;
  lItem:NSDictionary;
  key,value: NSString;
begin
  fWorkSpace := TNsWorkspace.Wrap(TNsWorkSpace.OCClass.sharedWorkspace);
  list := fWorkspace.launchedApplications;
  if (List <> nil) and (List.count > 0) then
  begin
    for i := 0 to list.count-1 do
    begin
      lItem := TNSDictionary.Wrap(List.objectAtIndex(i));
      key := NSSTR(String(PAnsiChar(UTF8Encode('NSApplicationBundleIdentifier'))));
      // You can also use NSApplicationPath or NSApplicationName
      value := TNSString.Wrap(lItem.valueForKey(key));
      Applist.Add(String(value.UTF8String));
    end;
  end;
end; 

For Windows:

uses Winapi.TlHelp32, Winapi.Windows;

class procedure TPlatformExtensionsWin.GetRunningApplications(
  Applist: TStringlist);
var
 PE: TProcessEntry32;
 Snap: THandle;
 fName: String;
begin
  pe.dwsize:=sizeof(PE);
  Snap:= CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if Snap <> 0 then
  begin
    if Process32First(Snap, PE) then
    begin
     fName := String(PE.szExeFile);
     Applist.Add(fName);
     while Process32Next(Snap, PE) do
     begin
       fName := String(PE.szExeFile);
       Applist.Add(fName);
     end;
    end;
    CloseHandle(Snap);
  end;
end; 

If you need further information about the subject you can read my article on the subject.

Upvotes: 5

Related Questions