Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi GetWindowHandleByExeName funktioniert erst beim 2. / 3. mal (https://www.delphipraxis.net/106282-getwindowhandlebyexename-funktioniert-erst-beim-2-3-mal.html)

Schubi 8. Jan 2008 14:47


GetWindowHandleByExeName funktioniert erst beim 2. / 3. mal
 
Hallo!

Ich versuche eine fremde Anwendung sauber zu beenden.
Sagen wir einfach "notepad.exe".
Ich nutze GetWindowHandleByExeName um an das Handle zu kommen und sende dann ein WM_CLOSE an das Fenster
Delphi-Quellcode:
PostMessage(GetWindowHandleByExeName('notepad.exe'), WM_CLOSE, 0, 0);
Das jedoch funktioniert erst beim zweiten oder dritten mal.
Die ersten male kommt ein anderes Handle raus.
Wie kann das sein?

Hier der Code zu "GetWindowHandleByExeName":
Delphi-Quellcode:
var
  WindowHandle: THandle;
  h: HWND;

[...]

function MyEnumWindowProc(AHandle: THandle; LParam: LongWord): boolean;
stdcall;
var
  ProcessID: THandle;
begin
  ProcessID := 0;
  GetWindowThreadProcessID(AHandle, ProcessID);
  Result := not (ProcessID = LParam);
  if not Result then
    WindowHandle := AHandle;
end;

function GetWindowHandleByExeName(const AExeName: string): THandle;
var
  SnapShot: THandle;
  p: TProcessEntry32;
  ProcessHandle: THandle;
begin
  Result := 0;
  WindowHandle := 0;
  ProcessHandle := 0;
  p.dwSize := SizeOf(p);
  SnapShot := CreateToolhelp32Snapshot(TH32CS_SnapProcess, 0);
  try
    if Process32First(SnapShot, p) then
      repeat
      if AnsiLowerCase(AExeName) = AnsiLowerCase(p.szExeFile) then
        ProcessHandle := p.th32ProcessID;
      until (ProcessHandle <> 0) or not Process32Next(SnapShot, p);
    EnumWindows(@MyEnumWindowProc, ProcessHandle);
    Result := WindowHandle;
  finally
    CloseHandle(SnapShot);
  end;
end;

sirius 8. Jan 2008 14:54

Re: GetWindowHandleByExeName funktioniert erst beim 2. / 3.
 
NotePad hat mehrere Fenster (wi alle anderen Programme auch) und wann ein Programm beendet wird, bestimmt letztenendes der Programmierer (hier: von Notepad). Bei Delphi-Programmen ist dies i.A., wenn die MainForm geschlossen wird. Das ist allerdings VCL-spezifisch und kann man auch anders machen.
Zurück zu "GetWindowHandleByExeName". Es gibt dir das erste gefundene Fenster zurück. Mehr nicht. Das kann ein Button sein, oder das Editorfenster,...
Ich vermute, du bist zufrieden, wenn du das große Fenster erwwischt und geschlossen hast. Wie gesagt, dass muss nicht das erste sein und es muss auch nicht dafür sorgen, das Notepad geschlossen wird (ist aber meist so; allerdings habe ich da bei MS-Word schonmal Probleme gehabt).

Schubi 8. Jan 2008 15:20

Re: GetWindowHandleByExeName funktioniert erst beim 2. / 3.
 
EnumWindows gibt alle top-level-windows zurück. Somit sollten Anwendungen wie Notepad doch nur einmal auftauchen!?

sirius 8. Jan 2008 15:22

Re: GetWindowHandleByExeName funktioniert erst beim 2. / 3.
 
Ein Anwendung kann auch mehrere davon besitzen. Zähl doch mal in Enumwindows.

Schubi 8. Jan 2008 15:27

Re: GetWindowHandleByExeName funktioniert erst beim 2. / 3.
 
Wenn ich folgendes mache...
Delphi-Quellcode:
GetWindowThreadProcessID(AHandle, ProcessID);
  Result := not (ProcessID = LParam);
  if not Result then begin
    WindowHandle := AHandle;
    Form3.Memo1.Lines.Add(inttostr(ahandle));
  end;
Kommt nur ein Handle bei raus.

Finde auch kein anderes was zu Notepad gehört.

--EDIT--

OK, habs gefunden. EnumWindows bricht bei Result = False ab. Dadurch hab ich nur das erste gesehen.
Danke für die Hilfe!


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:14 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz