Remus Rigo
Remus Rigo

Reputation: 1464

how to open additional files into an already running application

I am writing a MDI Text Editor and I was wondering how can I open all text files with my app. (If I associate te *.txt to my app I want that each time someone double-clicks on a txt file to open it in my app, in a new child window)

thanks

Upvotes: 2

Views: 1867

Answers (4)

Jeremy Mullin
Jeremy Mullin

Reputation: 4240

Check out the Windows DDE documentation. I modify the DDEExec options in the registry, so the shell correctly directs the opened file to my existing application instance. The following code makes the registry changes necessary. Replace "AppName" with your application name (and remove the brackets).

     // add the ddeexec key
     if not reg.OpenKey( '\Software\Classes\<AppName>.file\shell\open\ddeexec', true ) then
        raise Exception.Create( 'Error setting ddeexec key' );

     try
        reg.WriteString( '', 'FileOpen("""%1""")' );
     finally
        reg.CloseKey;
     end;

     // modify the command key to not include the parameter, as we don't use it
     if not reg.OpenKey( '\Software\Classes\<AppName>.file\shell\Open\command', true ) then
        raise Exception.Create( 'Error opening command key.' );

     try
        strTemp := reg.ReadString( '' );

        strTemp := StringReplace( strTemp, '"%1"', '', [] );
        reg.WriteString( '', strTemp );

     finally
        reg.CloseKey;
     end;

Upvotes: 1

zz1433
zz1433

Reputation: 3586

I Currently have the following implementation for this :

The .dpr file

var
  PrevWindow : HWND;
  S : string;
  CData : TCopyDataStruct;

begin
  PrevWindow := 0;
  if OpenMutex(MUTEX_ALL_ACCESS, False, 'YourUniqueStringHere') <> 0 then
    begin
      PrevWindow:=FindWindow('TYourMainFormClassName', nil);

      if IsWindow(PrevWindow) then
      begin
        SendMessage(PrevWindow, WM_SYSCOMMAND, SC_RESTORE, 0);
        BringWindowToTop(PrevWindow);
        SetForegroundWindow(PrevWindow);

        if FileExists(ParamStr(1)) then
        begin
          S:=ParamStr(1);
          CData.dwData:=0;
          CData.lpData:=PChar(S);
          CData.cbData:=1+Length(S);

          SendMessage(PrevWindow, WM_COPYDATA, 0, DWORD(@CData) );
        end;
      end;
    end
  else
    CreateMutex(nil, False, 'YourUniqueStringHere');

in the main unit we process the WM_COPYDATA message :

we declare the message handler

procedure ReceiveData_Handler ( var msg : TWMCopyData ) ; message WM_COPYDATA;


procedure TForm1.ReceiveData_Handler(var msg: TWMCopyData);
begin
  // Your file name is in the msg.CopyDataStruct.lpData
  // Cast it to PChar();
end;

Hope it works for you.

Upvotes: 2

skamradt
skamradt

Reputation: 15538

The solution to this is also the solution to not allowing more than one application to run at the same time. What you want to do is first detect that the program is already running, then pass a parameter to the running application and shut down.

There are several methods to determine if your application is already running. Once you pick one that fits your programming preferences, the next step is to feed the file to open to your running program. This can be done via named pipes, messages (although messages do fail on Vista/Win7 if your app is running in another security context), or any other method of IPC.

Upvotes: 4

Nathan Campos
Nathan Campos

Reputation: 29497

I don't know the version of Delphi that you're using, but in Delphi 7 at the examples folder you will see a MDI Text Editor example.

Upvotes: 0

Related Questions