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 :

Fermeture d'une appli externe par WM_CLOSE


Sujet :

Langage Delphi

  1. #1
    Membre du Club
    Inscrit en
    Novembre 2004
    Messages
    82
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 82
    Points : 40
    Points
    40
    Par défaut Fermeture d'une appli externe par WM_CLOSE
    Bonjour,

    J'essaie de fermer une application externe par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    handle:=FindWindow(nil,'monappli');//monappli:titre de l'application
    PostMessage(handle,WM_CLOSE,0,0);
    Ca marche en général sauf pour quelques applications persos qui refusent de se fermer et je me triture les neurones depuis 48h sans comprendre.
    Le handle récupéré est correct. Le PostMessage se passe bien (pas d'erreur retournée, opération réussie) mais ma fenètre d'application refuse de se fermer.
    Si je ferme mon application par le gestionnaire de tâches de Windows, pas de problème.
    Avec SendMessage, même anomalie.
    Qu'est-ce qui peut bien dans WinXP empècher une tâche de traiter le WM_CLOSE ? Y a t'il dans TApplication une propriété qui bloque cette fermeture ?
    Merci pour l'aide
    Gabriel

  2. #2
    Membre éprouvé Avatar de defluc
    Homme Profil pro
    Architecte
    Inscrit en
    Mai 2002
    Messages
    1 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 383
    Points : 1 199
    Points
    1 199
    Par défaut
    Essaies
    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
    function KillProcess(const ProcessName : string) : boolean;
    var
        ProcessEntry32 : TProcessEntry32;
        HSnapShot : THandle;
        HProcess : THandle;
    begin
      Result := False;
      HSnapShot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
      if HSnapShot = 0 then exit;
      ProcessEntry32.dwSize := sizeof(ProcessEntry32);
      if Process32First(HSnapShot, ProcessEntry32) then
      repeat
        if CompareText(ProcessEntry32.szExeFile, ProcessName) = 0 then
        begin
          HProcess := OpenProcess(PROCESS_TERMINATE, False, ProcessEntry32.th32ProcessID);
          if HProcess <> 0 then
          begin
            Result := TerminateProcess(HProcess, 0);
            CloseHandle(HProcess);
          end;
          Break;
        end;
      until not Process32Next(HSnapShot, ProcessEntry32);
      CloseHandle(HSnapshot);
    end;

  3. #3
    Membre du Club
    Inscrit en
    Novembre 2004
    Messages
    82
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 82
    Points : 40
    Points
    40
    Par défaut WM_CLOSE
    Merci beaucoup pour la réponse.
    La petite fonction fonctionne sur toutes mes applications.
    (Après avoir déclaré la TlHelp32 en uses et remplacement le titre de la tâche par le nom de l'éxécutable ....)
    Juste une petite question. Cette fonction ne fonctionne que dans un environnement 32 bits (WinNT, XP etc). Est-ce que la même chose serait faisable sous Win98 ?
    Merci encore pour l'aide.
    Gabriel

  4. #4
    Membre éprouvé Avatar de defluc
    Homme Profil pro
    Architecte
    Inscrit en
    Mai 2002
    Messages
    1 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 383
    Points : 1 199
    Points
    1 199
    Par défaut
    Rien n'interdit d'essayer sous Win 98.

    Mais si cela ne marche pas, cela vaut-il la peine de se creuser pour trouver une solution équivalente alors que Windows 98 est devenu vraiment antédiluvien ?

  5. #5
    Membre du Club
    Inscrit en
    Novembre 2004
    Messages
    82
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 82
    Points : 40
    Points
    40
    Par défaut WM_CLOSE
    Re Bonsoir
    J'avais été un peu vite en disant que ça ne fonctionnait pas sous Win98.
    Ca fonctionne aussi mais le nom du process est différent :
    Sous WinXP, c'est le nom de l'exe (monappli.exe) qui est récupéré.
    Sous Win98, c'est le chemin complet du process en majuscules (C:\REP1\REP2\MONAPPLI.EXE) qui est récupéré par la librairie d'outils d'aide.
    Le test est un peu différent suivant le cas !
    Merci encore pour l'aide apportée.
    Ca ne me dit toujours pas pourquoi je n'arrive pas fermer certaines de mes applis avec WM_CLOSE mais ça me va comme ça !
    Bonne soirée
    Gabriel

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 712
    Points : 13 176
    Points
    13 176
    Par défaut
    Je n'ai jamais eu de problème à fermer une application par WM_CLOSE. Mais j'envoi toujours le message à la fenêtre principale (Form1.Caption) et non à l'application (Application.Title).

    Une remarque cependant. FindWindow ne va renvoyer qu'UNE fenêtre contenant le titre spécifié. Si plusieurs fenêtres ont le même titre, seule la première sera fermée.

    Par exemple une application et son fichier d'aide ouvert et c'est l'aide qui se ferme .
    On peut rencontrer le même phénomène simplement si la fiche est ouverte dans l'IDE Delphi .

    Spécifier la class sur FindWindow résout déjà pas mal de problème. (Et faire un essai en quittant Delphi)

    Quant au gestionnaire de tâches, il passe lui uniquement par un TerminateProcess. (C'est la moindre des choses )

  7. #7
    Membre éprouvé Avatar de defluc
    Homme Profil pro
    Architecte
    Inscrit en
    Mai 2002
    Messages
    1 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Belgique

    Informations professionnelles :
    Activité : Architecte

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 383
    Points : 1 199
    Points
    1 199
    Par défaut
    Sous WinXP, c'est le nom de l'exe (monappli.exe) qui est récupéré.
    Sous Win98, c'est le chemin complet du process en majuscules (C:\REP1\REP2\MONAPPLI.EXE) qui est récupéré par la librairie d'outils d'aide.
    Le test est un peu différent suivant le cas !
    Pour être universelle, la fonction pourrait inclure un test identifiant la version de Windows d ugenre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ...
    Uses
    ..., Windows;
     if Win32PlatForm = VER_PLATFORM_WIN32_WINDOWS Then
    begin
       ...
       ...
    end
                                                   else
    begin
       ...
       ...
    end;

  8. #8
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 770
    Points
    2 770
    PAS DE DESTIN, C'EST CE QUE NOUS FAISONS

  9. #9
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 988
    Points
    988
    Par défaut
    Pour avoir cherché une solution à ce problème, je me permet de donner quelques informations : le message WM_CLOSE doit être accompagné d'un handle de fenêtre, et a pour conséquence de fermer la fenêtre concernée.

    Or, une application ne se ferme pas simplement parce qu'on ferme une de ses fenêtres, sauf si c'est la fenêtre principale. Malheureusement, l'API de Windows ne fournit aucune fonction permettant de récupérer le handle de la fenêtre principale d'une application (j'ai cherché pour vous...). Donc WM_CLOSE n'est pas utilisable.

    Pour ton problème de Windows 98, j'ai créé et utilise l'adaptation suivante, qui a été testée sous Windows 95, 98, 98SE, Me, 2000, XP et Vista.

    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
    Function  DTKillAllTasks(const AFileName : string) : Integer;
    var
      ExeFileName     : string;
      ContinueLoop    : BOOL;
      FSnapshotHandle : THandle;
      FProcessEntry32 : TProcessEntry32;
    begin
      Result := 0;
      ExeFileName := UpperCase(AFileName);
      FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
      FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
      ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
     
      while Integer(ContinueLoop) <> 0 do
      begin
        if ( ( UpperCase(ExtractFileName(FProcessEntry32.szExeFile) ) = ExeFileName )
         or  ( UpperCase(FProcessEntry32.szExeFile) = ExeFileName ) ) then
          Result := Integer(TerminateProcess(
                            OpenProcess(PROCESS_TERMINATE,
                                        BOOL(0),
                                        FProcessEntry32.th32ProcessID),
                                        0));
         ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
      end;
     
      CloseHandle(FSnapshotHandle);
    end;

Discussions similaires

  1. [DELPHI 5] Minimiser une appli externe
    Par VincentB dans le forum Delphi
    Réponses: 2
    Dernier message: 15/05/2006, 15h54
  2. [Système][Runtime]J'arrive pas à lancer une appli externe !?!
    Par polnioumane dans le forum Général Java
    Réponses: 6
    Dernier message: 16/11/2005, 18h55
  3. Réponses: 3
    Dernier message: 26/09/2005, 10h41
  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. Récupérer le Handle d'une Appli externe
    Par luxprog dans le forum Windows
    Réponses: 15
    Dernier message: 29/04/2004, 13h47

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