IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Delphi Discussion :

Programme qui se ferme si une autre instance est déjà démarrée


Sujet :

Delphi

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    322
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2009
    Messages : 322
    Points : 310
    Points
    310
    Par défaut Programme qui se ferme si une autre instance est déjà démarrée
    Bonjour à tous

    J'ai trouvé comment vérifier si une application tourne avant de la lancer...

    J'aimerais plutôt que l'application se ferme d'elle-même si une autre instance tourne déjà.

    Merci d'avance.

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 458
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 458
    Points : 24 871
    Points
    24 871
    Par défaut
    Utilise des MUTEX comme dans la Comment n'instancier qu'une seule fois un programme ?

    Un vieux code de 2002 (il peut être même plus vieux, c'est inspiré d'un exemple de Phidels) qui en plus met la fenêtre de la précédente instance au premier plan
    Avec les Delphi gère différemment la MainForm cela peut ne pas fonctionner (MainFormOnTaskbar à False)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    unit Unique_Instance;
     
    {
     dans la projet :
     
    Application.Initialize;
    Application.Title := 'Titre du Programme';
    if not UniqueInstance(Application.Title) then Exit;
    Application.CreateForm(TMenuFrm, MenuFrm);
    Application.Run;
     }
     
     
    interface
     
    uses
        forms,windows,sysutils;
     
    type
      PFindWindowStruct = ^TFindWindowStruct;
      TFindWindowStruct = record
        Caption: string;
        ClassName: string;
        WindowHandle: THandle;
      end;
     
    function UniqueInstance(Nom: String): boolean;
    procedure GoMainApp(Nom: String);
    function FindAWindow(ACaption: string): THandle;
    function EnumWindowsProc(hWindow: hWnd;lParam : LongInt): Boolean; stdcall;
     
    implementation
     
    function UniqueInstance(Nom: String): boolean;
    begin
      CreateMutex(nil, False, PChar(Nom));
      Result := GetLastError <> ERROR_ALREADY_EXISTS;
      if not Result then GoMainApp(Application.Title);
    end;
     
     
     
    procedure GoMainApp(Nom: String);
    var
      ActifHnd: THandle;
    begin
         ActifHnd:= FindAWindow(Nom);
         if ActifHnd <> 0 then begin
           ShowWindow(ActifHnd, SW_NORMAL);
           SetForegroundWindow(ActifHnd);
         end;
    end;
     
    function FindAWindow(ACaption: string): THandle;
    var
      WindowInfo: TFindWindowStruct;
    begin
         with WindowInfo do begin
              Caption:= ACaption;
              ClassName:= '';
              WindowHandle:= 0;
              EnumWindows(@EnumWindowsProc, LongInt(@WindowInfo));
              result:= WindowHandle;
              //showmessage(IntTostr(result));
     
         end;
    end;
     
    function EnumWindowsProc(hWindow: hWnd;lParam : LongInt): Boolean; stdcall;
    var
      lpBuffer: PChar;
      WindowCaptionFound: bool;
      ClassNameFound: bool;
     
    begin
         GetMem(lpBuffer, 255);
         Result:= True;
         WindowCaptionFound:= False;
         ClassNameFound:= False;
         try
            if GetWindowText(hWindow, lpBuffer, 255) > 0 then
               if Pos(PFindWindowStruct(lParam).Caption, StrPas(lpBuffer)) = 1 then begin
                  WindowCaptionFound:= true;
                  if PFindWindowStruct(lParam).ClassName = '' then
                ClassNameFound:= True
             else if GetClassName(hWindow, lpBuffer, 255) > 0 then
                  if Pos(PFindWindowStruct(lParam).ClassName, StrPas(lpBuffer)) > 0 then
                     ClassNameFound:= True;
          end;
        if (WindowCaptionFound and ClassNameFound) then begin
          PFindWindowStruct(lParam).WindowHandle:= hWindow;
          Result:= False;
        end;
     
      finally
        FreeMem(lpBuffer, sizeof(lpBuffer^));
      end;
    end;
     
    end.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    322
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2009
    Messages : 322
    Points : 310
    Points
    310
    Par défaut
    Merci Shai

    T'es vraiment top. Merci beaucoup.

    Je me demande bien comment je pourrai te rendre la pareille.

    Pour des algos, des simplications laisse moi savoir

    Merci encore

    A+

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 356
    Points : 133
    Points
    133
    Par défaut
    moi, j'utilise le composant JvAppInstances que se trouve dans la bibliothèque Jedi - JVCL au cas ou tu aurais cette bibliothèque ...

  5. #5
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 693
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 126
    Points
    13 126
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    function EnumWindowsProc(hWindow: hWnd;lParam : LongInt): Boolean; stdcall;
    var
      lpBuffer: PChar;
      WindowCaptionFound: bool;
      ClassNameFound: bool;
     
    begin
         GetMem(lpBuffer, 255);
         Result:= True;
         WindowCaptionFound:= False;
         ClassNameFound:= False;
         try
            if GetWindowText(hWindow, lpBuffer, 255) > 0 then
               if Pos(PFindWindowStruct(lParam).Caption, StrPas(lpBuffer)) = 1 then begin
                  WindowCaptionFound:= true;
                  if PFindWindowStruct(lParam).ClassName = '' then
                ClassNameFound:= True
             else if GetClassName(hWindow, lpBuffer, 255) > 0 then
                  if Pos(PFindWindowStruct(lParam).ClassName, StrPas(lpBuffer)) > 0 then
                     ClassNameFound:= True;
          end;
        if (WindowCaptionFound and ClassNameFound) then begin
          PFindWindowStruct(lParam).WindowHandle:= hWindow;
          Result:= False;
        end;
     
      finally
        FreeMem(lpBuffer, sizeof(lpBuffer^));
      end;
    end;
     
    end.
    J'invoquais dernièrement SetProp/GetProp et c'est typiquement un cas où je l'utiliserais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      SetProp(Handle, 'MonAppIdentifier', 1);
    end;
     
    function EnumWindowsProc(hWindow: hWnd;lParam : LongInt): Boolean; stdcall;
    begin
      Result := GetProp(hWindow, 'MonAppIdentifier') = 1;
    end;
    Plus léger non
    De plus, ça fonctionne même si le titre de la fenêtre est sujet à variation

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 458
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 458
    Points : 24 871
    Points
    24 871
    Par défaut
    l'API SetProp est très intéressante !
    Je ne connaissais pas !

    Si un jour j'ai l'occasion de mettre un UniqueInstance dans une application ce que je n'ai pas fait depuis des années, j'utiliserais ton astuce !

    J'y vois aussi un intérêt pour ma classe d'échange de données inter-process !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Ou alors on crée son mutex non pas avec le nom de l'application mais avec un GUID (ex: b6993aa9-fa94-41fc-ac7e-d495786added) (il y a des générateurs en ligne)

  8. #8
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 693
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 126
    Points
    13 126
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    J'y vois aussi un intérêt pour ma classe d'échange de données inter-process !
    Bien sûr et même des chaînes ou petites structures en passant par la table atom-ique (GlobalAddAtom, GlobalGetAtomName)

    Citation Envoyé par foetus Voir le message
    Ou alors on crée son mutex non pas avec le nom de l'application mais avec un GUID (ex: b6993aa9-fa94-41fc-ac7e-d495786added) (il y a des générateurs en ligne)
    Ctrl+Shift+G pour générer un GUID depuis l'EDI

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 27/08/2011, 01h02
  2. [HTML] click lien sur une cellule et page qui s'ouvre dans une autre cellule
    Par mariogarcia dans le forum Balisage (X)HTML et validation W3C
    Réponses: 26
    Dernier message: 24/05/2006, 14h37
  3. galerie d'image qui s'ouvre dans une autre fenêtre
    Par crampouz dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 17/02/2006, 14h17
  4. Acceder à un object qui se trouve dans une autre classe
    Par ceres02 dans le forum AWT/Swing
    Réponses: 8
    Dernier message: 08/02/2006, 13h29
  5. fonction qui en fait planter une autre
    Par ickis dans le forum C
    Réponses: 5
    Dernier message: 18/08/2003, 21h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo