Link to home
Start Free TrialLog in
Avatar of GTwoD
GTwoDFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Creating a Single instance of an Application

Hi

Up until now I have been using the following code to create a single instnce of my apps, but for some unknown reason it does not seem to work:-s. I will stop a second instnce from beeing created but will not bring the from forward. can anyone tell me what I am do wrong?

program PGLIWMan;

uses
  Forms,windows,
  VTDevManFM in 'VTDevManFM.pas' {ManFRM},
  VTGUITypes in '..\VTGUITypes.pas',
  TDeviceManager in '..\TDeviceManager.pas',
  CommonRoutines in 'G:\MyDocs\Delphi Source\Useful\CommonRoutines.pas';

{$R *.RES}

var
  Hmutex:Thandle;

begin
  HMutex:= CreateMutex(nil,false,'ManFRM');
  if WaitForSingleObject(hmutex,0) <> wait_TimeOut then
  begin
    Application.Initialize;
    Application.Title := 'VT Manager';
    Application.CreateForm(TManFRM,ManFRM);
    Application.Run;
  end
  else
  begin
    setForegroundWindow(Hmutex);
  end;
end.

I am using Delphi 5, drop me a line if you want more info
Avatar of esoftbg
esoftbg
Flag of Bulgaria image

ASKER CERTIFIED SOLUTION
Avatar of Wim ten Brink
Wim ten Brink
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
program PGLIWMan;

uses
  Forms,
  SysUtils,
  Windows,
  Messages,
  VTDevManFM in 'VTDevManFM.pas' {ManFRM};

{$R *.res}

var
  hFileMap, Handle:    Cardinal;
  FMapPt:              Pointer;

begin
  hFileMap := CreateFileMapping($FFFFFFFF,     // $FFFFFFFF get's memory file
                                nil,           // no security attributes
                                PAGE_READWRITE,// read/write access
                                0,             // size: high 32-bits
                                2048,          // size: low 32-bits
                                'Q_21080749'); // name of map object
  if (GetLastError = ERROR_ALREADY_EXISTS) then
  begin
    if (ParamCount > 0) then
    begin
      FMapPt := MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);
      if FMapPt <> nil then
      begin
        Handle := Cardinal(FMapPt^);
        if FileExists(ParamStr(1)) then
        StrCopy(Pointer(Integer(FMapPt)+4), PChar(ParamStr(1)));
        UnmapViewOfFile(FMapPt);
        SendMessage(Handle, WM_USER+432, 0, 0);
      end;
    end;
    CloseHandle(hFileMap);
    Exit;
  end;

  Application.Initialize;
  Application.Title := 'Single Instance Application';
  Application.CreateForm(TManFRM, ManFRM);
  Application.Run;
  CloseHandle(hFileMap);
end.

//........

unit VTDevManFM;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TManFRM = class(TForm)
    Edit1: TEdit;
  private   { Private declarations }
    procedure GetFileName(var Msg : TMessage); message WM_USER + 432;
  public    { Public declarations }
  end;

var
  ManFRM: TManFRM;

implementation

{$R *.dfm}

procedure TManFRM.GetFileName(var Msg : TMessage);
var
  hFileMap: Cardinal;
  FMapPt: Pointer;
  AryChar2: Array[0..2043] of Char;
begin
  hFileMap := OpenFileMapping(FILE_MAP_WRITE, False, 'Q_21080749');
  FMapPt := MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);
    if (FMapPt <> nil) then
    begin
      StrCopy(@AryChar2[0],Pointer(Integer(FMapPt)+4));
//      OpenFile(AryChar2);  {OpenFile is your apps procedure to open files}
      UnmapViewOfFile(FMapPt);
    end;
  CloseHandle(hFileMap);
end;

end.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of GTwoD

ASKER

Hi thanks for the responses

Workshop_alex do you have example of the code what you taled about?

Avatar of GTwoD

ASKER

Another point the code for bring the window forward has worked before in other apps, but not now any ideas?
 
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of GTwoD

ASKER

Hi all realised with a couple of yours help what I did wrong the

I like the look of Hotrod's suggestion it is simple and effective, but it did not stop muliple instances

but it did inspire me write my own...


var
  Hmutex:Thandle;
  HWindow:Thandle;

begin
  HMutex:= CreateMutex(nil,false,'ManFRM');
  HWindow:= FindWindow('TManFrm');
  if WaitForSingleObject(hmutex,0) <> wait_TimeOut then
  begin
    Application.Initialize;
    Application.Title := 'VT Manager';
    Application.CreateForm(TManFRM,ManFRM);
    Application.Run;
  end
  else
  begin
    setForegroundWindow(HWindow);
  end;
end.


So I have split the point to those who has suggested FindWindow.
Avatar of GTwoD

ASKER

Repost...(Sorry)

var
  Hmutex:Thandle;
  HWindow:Thandle;

begin
  HMutex:= CreateMutex(nil,false,'ManFRM');
  //forgot to add nil as paramtre
  HWindow:= FindWindow('TManFrm',nil);
  if WaitForSingleObject(hmutex,0) <> wait_TimeOut then
  begin
    Application.Initialize;
    Application.Title := 'VT Manager';
    Application.CreateForm(TManFRM,ManFRM);
    Application.Run;
  end
  else
  begin
    setForegroundWindow(HWindow);
  end;
end.
Avatar of bpana
bpana

a better approach would be:

  // Will try to create a named mutex
  CreateMutex(nil, false, ManFRM);
  // if it failed then there is another instance running
  if GetLastError = ERROR_ALREADY_EXISTS then begin
    // There is an error, so it exist another ManFRM instance running
    // Send all windows our custom message - only our other
    // instance will recognise it, and restore itself
    SendMessage(HWND_BROADCAST, RegisterWindowMessage('ManFRM'), 0, 0);
    Halt(0);
  end;

  Application.Initialize;
  Application.Title := 'VT Manager';
  Application.CreateForm(TManFRM,ManFRM);
  Application.Run;