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 :

[D7] [Win32] Utilisation de FindWindow


Sujet :

Delphi

  1. #1
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut [D7] [Win32] Utilisation de FindWindow
    Bonjour et bonne année à tous,

    j'ouvre NotePad avec un ShellExecute.

    le titre de la fenêtre de NotePad qui s'affiche est 'Impression.txt - Bloc-notes'

    j'essaye de trouver le Handle de la fenêtre de NotePad :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      Titre := 'Impression.txt - Bloc-notes' ;
      H := FindWindow('NotePad', Pchar(Titre));
      ShowMessage('Handle de '+Titre+ ' : '+IntToStr(H ) ) ;
    Ce code me renvoie toujours 0

    (par contre si je fais FindWindow('NotePad', nil) j'obtiens bien un Handle. Mais je voudrais être sûr d'obtenir le bon, celui que j'ai ouvert !)

    Est ce que j'utilise mal FindWindow ?

    Merci
    A+
    Charly

  2. #2
    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 128
    Points
    13 128
    Par défaut
    Non, c'est ton titre qui est faux

    C'est un espace insécable qui est ajouté à la suite du fichier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Titre := 'Impression.txt'#160'- Bloc-notes';

  3. #3
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Merci AndnotOr,

    tu es génial

    A+
    Charly

  4. #4
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut
    Attention, ton traitement n'est viable que sur un Windows français ! (et tant qu'ils ne changent pas la façon d'afficher le caption, et tant que ton utilisateur n'avait pas ouvert lui même de fichier qui s’appelle impression.txt )
    Peut-être que tu devrais remplacer ton ShellExecute par un CreateProcess, et récuperer le handle du process que tu viens de créer.

  5. #5
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Oui, c'est vrai.

    mais createProcess est un peu plus compliqué à utiliser que ShellExecute.

    Je vais faire un essai

    Merci
    Charly

  6. #6
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    A l'aide de la FAQ, j'ai bricolé ceci pour lancer Notepad en ouvrant un fichier texte :

    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
    { ====================================================================== }
    Function TF_Princ.LanceNotePad(Fichier : String): Hwnd ;
    var
      StartupInfo: TStartupInfo;
      ProcessInfo: TProcessInformation; 
      CommandLine: {$IFDEF UNICODE}WideString{$ELSE}string{$ENDIF}; 
    Begin
      Result := 0 ;
      If not FileExists(Fichier) Then
        Begin
          MessageDlg('Fichier '+Fichier+' introuvable' , mtError, [mbOk], 0) ;
          Exit ;
        End ;
      CommandLine := '"Notepad.exe" "'+Fichier+'"' ;
      ZeroMemory(@StartupInfo, SizeOf(StartupInfo)) ;
      StartupInfo.cb := SizeOf(StartupInfo) ;
      if CreateProcess(nil, PChar(CommandLine), nil, nil, FALSE, 0, nil, nil, StartupInfo, ProcessInfo) then
        Begin
          Result := ProcessInfo.hProcess ;
          CloseHandle(ProcessInfo.hProcess) ;
          CloseHandle(ProcessInfo.hThread) ;
        End ;
    End ;
    { ====================================================================== }
    Je l'utilise comme ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      HImp := LanceNotePad(FicImprime) ;
    j'affiche bien le fichier et je récupère bien le Handle dans HImp de type Hwnd. Mais lorsque que je veux fermer NotePad par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     If HImp <> 0 then SendMessage(HImp, WM_SYSCOMMAND, SC_CLOSE, 0);
    NotePad ne se ferme pas ? pourtant HImp a bien la bonne valeur dans ce code ...

    A+
    Charly

    PS : avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If HImp <> 0 then PostMessage(HImp,WM_CLOSE,0,0);
    ça ne marche pas non plus !

  7. #7
    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 128
    Points
    13 128
    Par défaut
    Citation Envoyé par Charly910 Voir le message
    NotePad ne se ferme pas ? pourtant HImp a bien la bonne valeur dans ce code ...
    Ben non, c'est n'est pas le handle d'une fenêtre que tu retournes mais celui d'un processus, il n'y a pas de menu associé.

    La méthode bourrin serait de faire un TerminateProcess sur ce handle mais une meilleure façon est de retourner le handle du thread principal (hThread) et de lui balancer un WM_QUIT par PostThreadMessage (WM_QUIT force la sortie de la boucle de messages créée par GetMessage de façon inconditionnelle).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    PostThreadMessage((GetThreadID(HImp), WM_QUIT, 0, 0);
    CloseHandle(HImp);
    Le code ci-dessus implique par contre que tu ne libères pas hThread juste après l'appel à CreateProcess mais uniquement lorsque tu n'en as plus besoin (pas de CloseHandle(ProcessInfo.hThread)). Le mieux serait donc que ta fonction retourne directement le ThreadID :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Function TF_Princ.LanceNotePad(Fichier : String): dword;
    begin
      ...
      if CreateProcess(nil, PChar(CommandLine), nil, nil, FALSE, 0, nil, nil, StartupInfo, ProcessInfo) then
        Begin
          Result := GetThreadID(ProcessInfo.hThread);
     
          CloseHandle(ProcessInfo.hProcess);
          CloseHandle(ProcessInfo.hThread);
        End;
    end;
    puis simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    var
      ImpID :dword;
     
    ImpID := LanceNotePad(...);
    ...
    PostThreadMessage(ImpID, WM_QUIT, 0, 0);
    Voili, voilou

  8. #8
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Merci je teste tout cela
    A+
    Charly

  9. #9
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Petit Couac : GetThreadId n'est pas trouvé :

    Identificateur non déclaré : "GetThreadId"
    j'ai pourtant la clause Uses Windows dans mon appli ? est ce à cause de D7 ? ou bien dans une autre unité ?

    Charly

  10. #10
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Bonjour,

    Après quelques recherches, j'ai trouvé ceci sur le net :

    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
    function GetThreadID(ProcessName : string ) : DWORD ;
    var
      Handle:tHandle;
      Process:tProcessEntry32;
      GotProcess:Boolean;
    begin
      Handle:=CreateToolHelp32SnapShot(TH32CS_SNAPALL,0) ;
      Process.dwSize:=SizeOf(Process);
      GotProcess := Process32First(Handle,Process);
    {$B-}
      if GotProcess and (Process.szExeFile<>ProcessName) then
          repeat
            GotProcess := Process32Next(Handle,Process);
          until (not GotProcess) or (Process.szExeFile=ProcessName);
    {$B+}
      if GotProcess then Result := Process.th32ProcessID
        else Result := 0;
            CloseHandle(Handle);
    end;
    mais cela ne compile pas sur D7.

    J'en déduis que j'ai un Delphi trop faiblard ! et je m'en tiens donc à ma solution initiale avec la première correction fournie par Andnotor.

    Merci à tous

    A+
    Charly

  11. #11
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 425
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 425
    Points : 1 326
    Points
    1 326
    Par défaut
    Bonjour à toutes et à tous,

    @ Charly910, à une époque j'utilisais ce code peut être qu'il y a quelque chose d'intéressant :

    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
     
    type 
      PFindWindowsStruct = ^TFindWindowsStruct; 
      TFindWindowsStruct = record 
        ProcessID: DWORD; 
        HandleList: TList; 
      end; 
     
    function EnumWindowsProc(hwnd: HWND; lParam: LPARAM): boolean; stdcall; 
    var 
      dwProcessId: DWORD; 
    begin 
      if lParam <> 0 then 
      begin 
        GetWindowThreadProcessId(hwnd, dwProcessId); 
        with PFindWindowsStruct(lParam)^ do 
          if dwProcessID = ProcessID then 
            HandleList.Add(Pointer(hwnd)); 
        result:= true; 
      end 
      else 
        result:= false; 
    end; 
     
    procedure FindProcessWindows(ProcessID: Integer; Handles: TList); 
    var 
      findWindowsStruct: TFindWindowsStruct; 
    begin 
      findWindowsStruct.ProcessID:= ProcessID; 
      findWindowsStruct.HandleList:= Handles; 
      EnumWindows(@EnumWindowsProc, Integer(@findWindowsStruct)); 
    end; 
     
    function NotepadPID: Cardinal; 
    var 
      StartInfo: TStartupInfo; 
      ProcessInfo: TProcessInformation; 
    begin 
      result:= 0; 
      { Mise à zéro de la structure StartInfo } 
      FillChar(StartInfo, SizeOf(StartInfo), #0); 
      { Seule la taille est renseignée, toutes les autres options } 
      { laissées à zéro prendront les valeurs par défaut } 
      StartInfo.cb:= SizeOf(StartInfo); 
     
      { Lancement de la ligne de commande } 
      if CreateProcess(nil, 'Notepad.exe', nil, nil, false, 
        0, nil, nil, StartInfo, ProcessInfo) then 
        result:= ProcessInfo.dwProcessId 
      else 
        RaiseLastOSError; 
    end; 
     
    function FindHandle(PID: Cardinal): HWND; 
    const 
      TIMEOUT = 5000; // 5 secs 
    var 
      handles: TList; 
      ticks: DWORD; 
    begin 
      handles:= TList.Create; 
      ticks:= GetTickCount; 
      try 
        while (handles.Count = 0) and (GetTickCount - ticks < TIMEOUT) do 
          FindProcessWindows(PID, handles); 
        if handles.Count > 0 then 
          result:= HWND(handles[0]) 
        else 
          result:= 0; 
      finally 
        handles.Free; 
      end; 
    end; 
     
    function StartNotepad: HWND; 
    var 
      pid: Cardinal; 
    begin 
      pid:= NotepadPID; 
      result:= FindHandle(pid); 
    end;
    Utilisation :

    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
     
    procedure TForm1.Button1Click(Sender: TObject); 
    var 
      h: HWND; 
    begin 
      h:= StartNotepad; 
      if h <> 0 then 
      begin 
        // On change la taille de la fenêtre 
        SetWindowPos(h, 0, 0, 0, 320, 200, 0); 
     
        // On change le parent de la fenêtre par notre panel (par exemple) 
        Windows.SetParent(h, panel1.Handle); 
      end; 
    end; 
     
    ou
     
    procedure TForm1.Button1Click(Sender: TObject); 
    var 
      h: HWND; 
    begin 
      h:= StartNotepad; 
      if h <> 0 then 
      begin 
        // On change la taille de la fenêtre 
        SetWindowPos(h, 0, 0, 0, panel1.Width, panel1.Height, 0); 
     
        // On change le parent de la fenêtre par notre panel (par exemple) 
        Windows.SetParent(h, panel1.Handle); 
      end; 
    end;
    @+,

    cincap

  12. #12
    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 128
    Points
    13 128
    Par défaut
    Ajoute simplement cette déclaration :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function GetThreadId(Thread: THandle): dword; stdcall; external 'Kernel32.dll';

  13. #13
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 345
    Points : 3 123
    Points
    3 123
    Par défaut
    Merci Andornot,
    ça marche nickel.

    je l'utilise comme cela :

    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 TF_Princ.LanceNotePad(Fichier : String): dword;
    // Lancement de Notepad avec CreateProcess
    //  renvoie le Handle du process
    //  il faut ajouter la déclaration :
    //      function GetThreadId(Thread: THandle): dword; stdcall; external 'Kernel32.dll';
    var
      StartupInfo: TStartupInfo;
      ProcessInfo: TProcessInformation;
      CommandLine: {$IFDEF UNICODE}WideString{$ELSE}string{$ENDIF};
    Begin
      Result := 0 ;
      If not FileExists(Fichier) Then
        Begin
          MessageDlg('Fichier '+Fichier+' introuvable' , mtError, [mbOk], 0) ;
          Exit ;
        End ;
      CommandLine := '"Notepad.exe" "'+Fichier+'"' ;
      ZeroMemory(@StartupInfo, SizeOf(StartupInfo)) ;
      StartupInfo.cb := SizeOf(StartupInfo) ;
      if CreateProcess(nil, PChar(CommandLine), nil, nil, FALSE, 0, nil, nil, StartupInfo, ProcessInfo) then
        Begin
          Result := GetThreadID(ProcessInfo.hThread);
          CloseHandle(ProcessInfo.hProcess);
          CloseHandle(ProcessInfo.hThread);
        End;
    End ;
    et pour tester :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    { ====================================================================== }
    Procedure TF_Princ.Ferme ;
    var
      ImpID :dword;
    Begin
      ImpID := LanceNotePad(FicImp);
      ShowMessage('Notepad ouvert') ;
      PostThreadMessage(ImpID, WM_QUIT, 0, 0);
    End ;
    { ====================================================================== }
    Cela me permet de fermer Notepad à la sortie de mon appli si jamais on ne l'a pas fait avant.

    merci encore

    A+
    Charly

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

Discussions similaires

  1. Utilisation de FindWindow
    Par Demon45 dans le forum Langage
    Réponses: 4
    Dernier message: 11/06/2011, 19h31
  2. [VBA] Utilisation API FindWindows
    Par idir.17 dans le forum Général VBA
    Réponses: 5
    Dernier message: 28/03/2007, 14h39
  3. Réponses: 1
    Dernier message: 12/02/2007, 10h19
  4. Quel format : coff ou win32 utiliser pour le .o
    Par Guillaume_2357 dans le forum x86 32-bits / 64-bits
    Réponses: 1
    Dernier message: 13/04/2005, 13h14
  5. [Win32] Utilisation de AddFontMemResourceEx
    Par Don ViP dans le forum MFC
    Réponses: 9
    Dernier message: 27/08/2004, 17h12

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