AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Alle Fenster jedes Threads einer Anwendung

Alle Fenster jedes Threads einer Anwendung

Ein Thema von TUX_der_Pinguin · begonnen am 22. Aug 2014 · letzter Beitrag vom 22. Aug 2014
Antwort Antwort
TUX_der_Pinguin

Registriert seit: 1. Jun 2005
Ort: Anholt (NRW)
603 Beiträge
 
Delphi 11 Alexandria
 
#1

Alle Fenster jedes Threads einer Anwendung

  Alt 22. Aug 2014, 09:32
Hallo DPler,

ich möchte in meiner Anwendung alle Fenster einer anderen Anwendung auflisten. Dazu habe ich u.a. hier im Forum gesucht und jemand schrieb man sollte erst alle Threads eines Prozesses auflisten um anschließend alle Fenster der einzelnen Threads zu bekommen.

Für den ersten Teil, Auflistung aller Threads habe ich hier folgenden Code gefunden. Wie mir scheint klappt das auflisten der Threads auch nur beim ermitteln der Fenster der jeweiligen Threads happert es noch gewaltig.
Delphi-Quellcode:
type
  TDWordList = array of DWord;


function GetThreadID(const FileName: String): TDWordList;
var
  ToolHnd, MToolHnd: THandle;
  PE32: TProcessEntry32;
  ME32: TModuleEntry32;
  TE32: TThreadEntry32;
  PIDArray, ThreadArray: TDWordList;
  a: Integer;
  PID: DWord;

begin
  //init
  PIDArray := nil;
  ThreadArray := nil;

  ToolHnd := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS or TH32CS_SNAPTHREAD, 0); //Handle auf Snapshot
  if ToolHnd = INVALID_HANDLE_VALUE then RaiseLastOSError;
  try
    PE32.dwSize := SizeOf(ProcessEntry32);
    if not Process32First(ToolHnd, PE32) then RaiseLastOSError; //erster Prozess
    repeat
      if CompareText(PE32.szExeFile, ExtractFileName(FileName)) = 0 then begin
        SetLength(PIDArray, Length(PIDArray) + 1);
        PIDArray[Length(PIDARRAY) - 1] := PE32.th32ProcessID;
      end;
    until not Process32Next(ToolHnd, PE32);

    { Jetzt sind alle PIDs der Prozesse, deren Dateinamen gleich dem gesuchten ist, gespeichert }
    { Jetzt wird für jeden Prozess anhand der Modulliste der vollständige Pfad ermittelt und so }
    { die endgültige, richtige ProcessID ermittelt.                                             }

    PID := 0;
    for a := 0 to Length(PIDArray) -1 do begin
      MToolHnd := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, PIDArray[a]); //Modulliste des gewählten Prozesses
      if MToolHnd = INVALID_HANDLE_VALUE then RaiseLastOSError;
      try
        ME32.dwSize := SizeOf(TModuleEntry32);
        if not Module32First(MToolhnd, ME32) then RaiseLastOSError;
        repeat
          if CompareText(ME32.szExePath, FileName) = 0 then begin
            PID := ME32.th32ProcessID;
            Break;
          end;
        until not Module32Next(MToolHnd, ME32);
      finally
        CloseHandle(MToolHnd);
      end;
      if PID <> 0 then Break;
    end;

    { Jetzt werden alle Threads des Prozesses ermittelt                                         }

    TE32.dwSize := SizeOf(ThreadEntry32);
    if not Thread32First(ToolHnd, TE32) then RaiseLastOSError;
    repeat
      if TE32.th32OwnerProcessID = PID then begin
        SetLength(ThreadArray, Length(ThreadArray) + 1);
        ThreadArray[Length(ThreadArray) - 1] := TE32.th32ThreadID;
      end;
    until not Thread32Next(ToolHnd, TE32);

  finally
    CloseHandle(ToolHnd);
  end;

  if Length(ThreadArray) > 0 then begin
    Result := ThreadArray;
  end
  else
    Result := nil;

end;
Lasse ich im ersten Schritt in der Schleife nur die Thread IDs ausgeben erhalte ich eine Liste von Nummern, will ich jetzt dazu die Fenster auflisten tritt nach der Ausgabe der ersten Thread ID ein Bereichsprüfungs Fehler auf.
Delphi-Quellcode:
unit uMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TfrmMain = class(TForm)
    Memo1: TMemo;
    Button3: TButton;
    procedure Button3Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

function EnumThreadWinProc(Wnd: HWND; LParam: LPARAM): Boolean;
var
  WinCaption: String;
  Len: Integer;

begin
  result := True;

  Len := GetWindowTextLength(Wnd);
  SetLength(WinCaption, Len);
  GetWindowText(Wnd, PChar(WinCaption), Len+1);
  if Trim(WinCaption) <> EmptyStr then
    TMemo(LParam).Lines.Add(' '+Trim(WinCaption));

end;

procedure TfrmMain.Button3Click(Sender: TObject);
var
  TL: TDWordList;
  Idx: Integer;

begin
  //Alle Threads einer Anwendung ermitteln
  TL := GetThreadID('c:\Programme\totalcmd\totalcmd.exe');

  //Alle Fenster jedes Threads einer Anwendung auflisten
  for Idx := 0 to High(TL) do begin
    Memo1.Lines.Add('Thread ID: '+IntToStr(TL[Idx])); //<-- Fehler in der Bereichsprüfung
    EnumThreadWindows(TL[Idx], @EnumThreadWinProc, Integer(Memo1));
  end;{for}

end;

end.
Ich habe keinen Schimmer wo der Fehler liegt.

Es geht mir ganz allgemein darum zu Prüfen ob zu einer Anwendung, ich kenne Name und Ort der Exe-Datei, noch Fenster geöffnet sind. Sind keine Fenster mehr geöffnet und nur noch der Prozess vorhanden könnte man annehmen beim Beenden der Anwendung sei etwas schief gegangen und der Prozess hängt.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#2

AW: Alle Fenster jedes Threads einer Anwendung

  Alt 22. Aug 2014, 09:58
EnumThreadWinProc ist falsch definiert, da fehlt ein stdcall
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
40.107 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Alle Fenster jedes Threads einer Anwendung

  Alt 22. Aug 2014, 10:01
[add, weil zu langsam]
Es wäre ja zu schön, wenn bei solchen Funktionen nicht nur Pointer, sondern die richtigen Typen deklariert wären, wenn würde der Compiler sowas gleich bemängeln .
Und ...
[/add]

TDWordList ist doch bestimmt als Pointer auf array[0..0] of DWord deklariert?
Wenn ja, dann gibt es natürlich ein Problem, wenn du auf Indize über 0 zugreifen willst, sobald die Beriechsprüfung aktiv ist.
(ich war zwar mal der Meinung, daß Delphi bei 0..0 die Bereichsprüfung für dieses Array als Sonderfall deaktiviert, aber das macht es leider doch nicht )

mögliche Lösungen:
- Bereichsprüfung für diese Prozedur deaktiveren (Compilerschalter)
- Bereichsprüfung global deaktivieren (Projektoptionen)
- Andere Typdefinition verwenden (z.B. Pointer auf array[0..($7fffffff - 2*SizeOf(NativeInt)) div SizeOf(DWORD) - 1] of DWORD aka array[0..$1ffffffa] of DWORD )
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014

Geändert von himitsu (22. Aug 2014 um 10:13 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.412 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Alle Fenster jedes Threads einer Anwendung

  Alt 22. Aug 2014, 10:03
Andere Möglichkeit: einfach mal den Code lesen
Zitat:
Delphi-Quellcode:
type
  TDWordList = array of DWord;
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
40.107 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Alle Fenster jedes Threads einer Anwendung

  Alt 22. Aug 2014, 10:15
Das war vorhin aber noch nicht da.

Hatte im Code die SetLength übersehn und das P in PIDArray:=nil; macht es einem nicht Einfacher und schwups, schon denkt man an Pointer.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
TUX_der_Pinguin

Registriert seit: 1. Jun 2005
Ort: Anholt (NRW)
603 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Alle Fenster jedes Threads einer Anwendung

  Alt 22. Aug 2014, 10:30
EnumThreadWinProc ist falsch definiert, da fehlt ein stdcall
Manchmal sind es wohl die kleinen Dinge im Leben

Und vielen Dank an alle natürlich

Geändert von TUX_der_Pinguin (22. Aug 2014 um 11:01 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:29 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf