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

Langage Delphi Discussion :

Terminer une application externe.


Sujet :

Langage Delphi

  1. #1
    Membre régulier
    Inscrit en
    Mars 2007
    Messages
    202
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 202
    Points : 91
    Points
    91
    Par défaut Terminer une application externe.
    Bonjour,

    On veut (par exemple) ouvrir mspaint.exe en cliquant sur un bouton et ultérieurement, le fermer et quitter mspaint après un temps déterminé par un timer, sans être obligé d'intervenir manuellement.
    Pour l'ouverture, pas de problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ShellExecute(0,'OPEN','mspaint.exe',Nil, Nil, SW_SHOW)
    ça marche.
    Mais pour fermer et quitter par programme (sans cliquer sur le bouton "Fermer" de la barre de titre de mspaint), je n'ai rien trouvé qui marche.
    Merci pour vos conseils.

    Remarque : on pourrait commander la fermeture en programmant Alt+F4 avec keybd_event , mais ça ne marche pas car mspaint pose alors des questions du genre "voulez-vous enregistrer avant de quitter?" etc. et il ne se termine donc pas sans intervention manuelle.

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 740
    Points : 13 285
    Points
    13 285
    Par défaut
    CreateProcess et TerminateProcess.

  3. #3
    Membre régulier
    Inscrit en
    Mars 2007
    Messages
    202
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 202
    Points : 91
    Points
    91
    Par défaut
    OK d'accord, mais...
    citation : << Attention, TerminateProcess(), c'est gore >> : c'est pas moi qui l'ai dit !
    M'enfin si c'est pas possible autrement, on fera avec. Ou plus exactement, on essaiera.
    Merci pour la réponse.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2009
    Messages : 69
    Points : 57
    Points
    57
    Par défaut
    Je sais pas si ca peut t'aider mais moi je quitte une application externe autrement.
    Regardes du coter de findwindow pour récupérer un handle de la fenêtre et ce code ci qui quitte l'appli en question.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    var
      monhandle : THandle;
    Begin
      //Le second paramètre de FindWindow est le titre de la fenêtre!
      monhandle := FindWindow(nil,'Calculatrice');
      SendMessage(monhandle,WM_CLOSE,0,0);
    end;

    nb: c'était déjà écrit dans la faq
    http://delphi.developpez.com/faq/?pa...merapplication

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 740
    Points : 13 285
    Points
    13 285
    Par défaut
    @JJJJ:
    Faut savoir ce que tu veux . Un timer qui kill l'application sans qu'elle ait eu le temps de dire "Oui, mais..." ou des confirmations utilisateur...

    @Fenix01:
    Ca marche avec la calcularice parce que le titre de la fiche principale ne change pas ! Celui de MSPaint s'adapte en fonction du nom du fichier.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2009
    Messages : 69
    Points : 57
    Points
    57
    Par défaut
    Oui mais au lieu de passer le nom de la fenêtre on peut passer le classname.

  7. #7
    Membre régulier
    Inscrit en
    Mars 2007
    Messages
    202
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 202
    Points : 91
    Points
    91
    Par défaut
    Bonjour,
    Faut savoir ce que tu veux . Un timer qui kill l'application sans qu'elle ait eu le temps de dire "Oui, mais..." ou des confirmations utilisateur...
    En effet, je veux la terminer sans qu'elle proteste en quoi que ce soit !
    Parmi les différents essais que j'avais fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SendMessage(monhandle,WM_CLOSE,0,0);
    je crois me souvenir que ça ne marchait pas avec mspaint.
    En fait, j'ai une solution, pas très satisfaisante, mais qui marche pour mspaint : La programmation de commandes keybd successives Alt+F4 , -> , Return termine bien mspaint sans enregistrement.
    Mais c'est strictement applicable à mspaint. Je profitais de l'occasion pour poser la question d'une façon plus générale, afin apprendre à le faire "proprement" pour d'autres logiciels.
    Les réponses que vous m'avez fournies me suffisent pour apprécier le problème.

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2009
    Messages : 69
    Points : 57
    Points
    57
    Par défaut
    Si, si ca fonctionne parfaitement je t'envoie le code.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
    paint:THandle;
    begin
      paint := FindWindow('MSPaintApp',nil); //MSPaintApp est le nom de classe
      PostMessage(paint,WM_CLOSE,0,0); // ferme la fenêtre
    end;
    Par contre mon code fonctionne si tu ne modifies pas l'image avec les outils de paint. Sinon il te demandera de sauvegarder les changements et il faudra envoyer de nouvelle commande.

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 740
    Points : 13 285
    Points
    13 285
    Par défaut
    Avec Alt+F4, il faudrait encore s'assurer que c'est bien MSPaint qui est au premier plan .
    FindWindow sur MSPaintApp renvoi la première fenêtre trouvée. Si plusieurs instances de MSPaint sont en cours, pas sûr que tu récupères la bonne .

  10. #10
    Membre régulier
    Inscrit en
    Mars 2007
    Messages
    202
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 202
    Points : 91
    Points
    91
    Par défaut
    Fenix01:
    Par contre mon code fonctionne si tu ne modifies pas l'image avec les outils de paint. Sinon il te demandera de sauvegarder les changements et il faudra envoyer de nouvelle commande.
    On est bien d'accord. Ca ne suffit pas car, après l'ouverture de Paint, l'image est modifiée. C'était bien mon problème.
    La "peu satisfaisante" méthode répond à cette difficulté en envoyant par keybd -> (un déplacement à droite du curseur), puis Return, ce qui est équivalent à cliquer sur le bouton "NON" de la fenêtre "Enregistrer les modifications".

    Andnotor :

    Avec Alt+F4, il faudrait encore s'assurer que c'est bien MSPaint qui est au premier plan
    Tout à fait ! J'ai un BringWindowToTop (en ayant auparavant récupéré le handle). Il faut même mettre un timer pour donner le temps que cela se fasse, si non le Alt+F4 part dans vide si l'ordinateur est trop chargé.

  11. #11
    Membre régulier
    Inscrit en
    Mars 2007
    Messages
    202
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 202
    Points : 91
    Points
    91
    Par défaut
    Bien que ce ne soit sûrement pas une méthode à conseiller, voilà le code :
    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
    procedure TForm1.StopPaintClick(Sender: TObject);
    begin
         ImageHandle := FindWindow(nil,'Sans titre - paint');  { ou un autre titre s'il a été changé }
         BringWindowToTop(ImageHandle);
         keybd_event(27, 0, 0, 0);    {Echap} { pour restaurer si Paint est en attente d'une réponse externe}
         keybd_event(27, 0, 2, 0);
                                         { si on veut récupérer l'image dans le clipboard : }
         keybd_event(17, 0, 0, 0);     {Ctrl}   {d'abord "Sélectionner tout" }
         keybd_event(65, 0, 0, 0);     {A}
         keybd_event(17, 0, 2, 0);
         keybd_event(65, 0, 2, 0);
     
         keybd_event(17, 0, 0, 0);     {Ctrl}   { puis "Copier" }
         keybd_event(67, 0, 0, 0);     {C}
         keybd_event(17, 0, 2, 0);
         keybd_event(67, 0, 2, 0);
     
         timer4.enabled:=true;
    end;
     
    procedure TForm1.Timer4Timer(Sender: TObject);
    begin
         timer4.enabled:=false;
     
         keybd_event(164, 0, 0, 0);    {Alt}   { "Quiter" }
         keybd_event(115, 0, 0, 0);    {F4}
         keybd_event(164, 0, 2, 0);
         keybd_event(115, 0, 2, 0);
     
         keybd_event(39, 0, 0, 0);      {->}   { passe le focus sur le bouton NON }
         keybd_event(39, 0, 2, 0);
         keybd_event(13, 0, 0, 0);      {Return}  { équivaut à cliquer sur le bouton }
         keybd_event(13, 0, 2, 0);
     
    end;

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2009
    Messages : 69
    Points : 57
    Points
    57
    Par défaut
    Je procederai pas comme ca moi.
    J'utiliserai postmessage et wm_close pour envoyer la commande de fermeture.

    Et ensuite je récuperai avec findwindowex l'handle du bouton "non" et j'enverrai a ce composant un message avec postmessage.
    C'est plus propre à mon goût.

  13. #13
    Membre régulier
    Inscrit en
    Mars 2007
    Messages
    202
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 202
    Points : 91
    Points
    91
    Par défaut
    J'approuve : ce serait plus propre.
    Le hic, c'est que je ne sais pas trop comment récupérer l'handle d'un bouton appartenant à un logiciel tel que mspaint : Certes, son "caption" est NON pour l'usage en français, mais quel est son "name" ?

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2009
    Messages : 69
    Points : 57
    Points
    57
    Par défaut
    Je vais te proposer une méthode qui va t'éviter de rechercher le bouton. C'est à mon avis le plus pénible. Il y a dans ce programme une fonction qui permet de recréer l'arborescence de l'objet sous lequel est la souris.

    Télécharges le logiciel super macro (c'est un programme en delphi pour créer des macros). Mais on va se servir uniquement d'une fonction bien sympathique.

    Quand tu ouvriras le programme tu auras une liste de commande à gauche.
    Trouves l'outils 'Objet'. Et double click dessus.
    Dans cette fenêtre tu auras une petite main que tu peux attraper et déplacer sur l'écran. Elle est a droite.
    Lorsque tu relâches cette main le programme te retournes l'arborescence de l'objet sous lequel était la main.

    A partir de là on peut commencer à écrire le code avec findwindow et findwindowex. Il suffit juste de partir de findwindow et d'utiliser findwindowex sur l'arborescence que t'a retourné Super Macro.

    Voici un exemple qui montre comment écrire dans notepad depuis une delphi. Il y a juste un parent et un enfant dans l'arborescence.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var
    notepad,edit:THandle;
    begin
      notepad := FindWindow('notepad',nil); // récupère le handle de notepad avec le classname
      if notepad <> 0 then // On a trouvé la fenêtre
      begin
        edit := FindWindowEx(notepad,0,'edit',nil); // on récupère l'handle de l'enfant à partir de son classname edit
        if edit <> 0 then
          SendMessage(edit,WM_SETTEXT,0,Integer(PChar('envoie de commande')));
      end;
    end;

  15. #15
    Membre régulier
    Inscrit en
    Mars 2007
    Messages
    202
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 202
    Points : 91
    Points
    91
    Par défaut
    Bon, merci Fenix01.
    Ca ne semble pas évident à mettre au point dans le cas de mspaint. Il faudra prévoir d'y passer pas mal de temps. Mais ce devait être un exercice instructif.
    Au vu de tout cela, la méthode proposée par d'Andnotor avec TerminateProcess n'est pas à dédaigner.

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

Discussions similaires

  1. Réponses: 12
    Dernier message: 23/01/2008, 09h17
  2. Fermer une application externe
    Par jean tof dans le forum C++Builder
    Réponses: 2
    Dernier message: 02/05/2006, 16h18
  3. Réponses: 6
    Dernier message: 07/09/2005, 20h31
  4. [Excel] Utiliser une application externe par une macro
    Par thierry2.dlp dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 09/08/2005, 22h07
  5. [Netbeans] terminer une application
    Par vasilov dans le forum NetBeans
    Réponses: 3
    Dernier message: 14/07/2005, 08h41

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