Results 1 to 3 of 3

Thread: Tweede instantie applicatie

  1. #1
    Senior Member PsychoMark's Avatar
    Join Date
    Nov 2001
    Location
    Raamsdonksveer
    Posts
    10,269

    Tweede instantie applicatie

    Opmerking

    Gebaseerd op deze code heb ik een unit geschreven die het makkelijk maakt om deze code te hergebruiken, en tevens de parameters van de 2e instantie door te geven aan de 1e. Zie deze post voor de uitleg en een link naar de unit...


    Omschrijving

    Het gebeurt vaak dat je een applicatie maar eenmalig wilt draaien, en zodra de applicatie een tweede keer wordt opgestart dat de vorige instantie dan naar de voorgrond komt.

    Er zijn vele oplossingen, zoals FindWindow of een Mutex. Bij FindWindow is het probleem dat het te makkelijk is om conflicten te krijgen, en alhoewel ik een tijd een fan ben geweest van een Mutex zit de broadcast message die er vaak mee gepaard gaat me toch niet lekker. In plaats daarvan heb ik voor Pegasus gekozen voor een Memory Mapped File. Bij het aanmaken kan je controleren of de MMF al bestaat, je kan er data in opslaan (in dit geval de window handle van het form) en mocht je applicatie crashen dan zal Windows de MMF samen met je proces toch netjes afsluiten. Geen RegisterWindowMessage of een broadcast meer nodig, alleen jouw venster zal het doelwit worden van de message.



    Code

    Allereerst, ga naar Project -> View Source en knutsel erin totdat het er zo uit ziet (met hooguit een andere naam voor je main form uiteraard):


    Code:
    uses
      Windows,
      Forms,
      FMain in 'Forms\FMain.pas';
    
    
    const
      // Zorg dat deze uniek is! Het maakt niet uit hoe je 'm noemt, maar
      // als 2 applicaties dezelfde naam gebruiken kan er maar 1 tegelijk
      // van starten... kies 'm dus zorgvuldig!
      CFileMapping  = 'MyApp.Instance';
    
    var
      hMapping:     THandle;
      wMap:         ^THandle;
    
    begin
      // Controleer of er al een instantie van de applicatie draait
      hMapping  := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
                                     SizeOf(THandle), CFileMapping);
      if GetLastError() = ERROR_ALREADY_EXISTS then begin
        wMap  := MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
    
        if wMap^ <> 0 then
          PostMessage(wMap^, WM_INSTANCE, 0, 0);
    
        UnmapViewOfFile(wMap);
        CloseHandle(hMapping);
        exit;
      end else
        wMap  := MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0);
    
    
      Application.Initialize;
      Application.CreateForm(TfrmMain, frmMain);
    
      // Doe dit na het creeren van het form en voor Application.Run
      wMap^ := frmMain.Handle;
    
      Application.Run;
    
      // Sluit alles netjes af
      UnmapViewOfFile(wMap);
      CloseHandle(hMapping);
    end;

    Als laatste stap gaan we sleutelen aan het form welke de message binnen krijgt:



    Code:
    interface
    uses
      Messages,
      Forms;
    
    const
      // Ervan uitgaande dat WM_USER + $1111 nog geen waarde heeft binnen
      // je applicatie, hier kan je uiteraard elke waarde boven WM_USER van maken.
      // Eronder is sterk afgeraden, daar zitten al standaard Windows messages.
      WM_INSTANCE = WM_USER + $1111;
    
    type
      TfrmMain = class(TForm)
      protected
        procedure WMInstance(var Msg: TMessage); message WM_INSTANCE;
      end;
    
    
    implementation
    
    procedure TfrmMain.WMInstance;
    begin
      // Hier kan je elke code uitvoeren die je wilt, in dit geval halen we
      // de applicatie naar de voorgrond...
      Application.Restore();
      Application.BringToFront();
    end;


    En dat was 't!
    Last edited by PsychoMark; 13-Nov-04 at 14:25.
    Qui custodiet ipsos custodes

  2. #2
    Senior Member PsychoMark's Avatar
    Join Date
    Nov 2001
    Location
    Raamsdonksveer
    Posts
    10,269
    Tip van GolezTrol: als je een unieke naam wilt gebruiken voor CFileMapping kan je ook een GUID gebruiken. Als je de IDE ingesteld hebt op de standaard toetsen dan kan je met Ctrl-Shift-G zo'n GUID invoegen.
    Qui custodiet ipsos custodes

  3. #3
    Senior Member PsychoMark's Avatar
    Join Date
    Nov 2001
    Location
    Raamsdonksveer
    Posts
    10,269
    Tip van micha: about.com heeft een mooi artikel waarin een filemapping gebruikt wordt om het aantal instanties te limiteren, niet beperkt tot slechts één dus...
    Qui custodiet ipsos custodes

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Replies: 12
    Last Post: 28-Jul-04, 14:35
  2. 1 instantie van je Applicatie
    By mvanrijnen in forum Algemeen
    Replies: 6
    Last Post: 10-Dec-01, 10:47

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •