![]() |
Eigenes Handle finden
Hallo,
ich habe folgendes Problem: Ich habe eine Anwendung nonVCL geschrieben. Nun benötige ich u.a. für den Aufruf von GetWindow(); das Handle meines eigenen Programms. Wenn ich VCL benutze, dann nehme ich dort entweder Application.Handle oder abgeleitet vom Haupt-Formular self.Handle. Das geht hier leider nicht. Wie komme ich möglichst ohne großen Aufwand an mein Handle ran? Gruß, Alex P.S. Auch wenn die Lösung einfach sein sollte und schon 100fach im Forum steht, bitte nicht meckern. Ich habe schon mehrmals die Suche benutzt, aber nichts gefunden. U.U. liegt es auch an falschen/fehlenden Suchbegriffen. |
Re: Eigenes Handle finden
Wenn Du via
![]() |
Re: Eigenes Handle finden
Zitat:
Entschuldigung: Evtl. habe ich mich auch nicht vollständig/richtig ausgdrückt. Meine Anwendung hat kein(e) Fenster. Sie läuft einem Dienst ähnlich ohne Benutzerinteraktion im Hintergrund. Dabei ist es notwending, dass ich auf das Ende eines bestimmten Programms/Fensters warte (vgl. ![]()
Delphi-Quellcode:
Mit Einbindung der VCL klappt das wunderbar. Nur wie mache ich das ohne ein Fenster? Mit GetWindow(0, GW_HWNDFIRST); klappt es jedenfalls nicht.
function FindWindowByTitle(WindowTitle: string): Hwnd;
var NextHandle: Hwnd; NextTitle: array[0..255] of char; begin // Get the first window NextHandle := GetWindow(Application.Handle, GW_HWNDFIRST); while NextHandle > 0 do begin // retrieve its text GetWindowText(NextHandle, NextTitle, 255); if Pos(WindowTitle, StrPas(NextTitle)) <> 0 then begin Result := NextHandle; Exit; end else // Get the next window NextHandle := GetWindow(NextHandle, GW_HWNDNEXT); end; Result := 0; end; Gruß, Alex |
Re: Eigenes Handle finden
Warum so kompliziert. lass Windows doch die Arbeit für dich machen:
![]() |
Re: Eigenes Handle finden
Zitat:
Das bringt mich zu einem weiteren Problem: Mit der Function findet man ja allerhand Fenster, auch solche die nicht sichbar sind. Gibt es eine Möglichkeit gerade in MDI-Programmen auch die anderen Fenster im Programm selbst zu finden? Wenn ich z.B. Im FireFox mehrere Fenster geöffnet habe, dann zeigt er mir immer nur den Titel des aktuell angezeigten Fensters an. Dass es grundsätzlich möglich sein muss, sehe ich an ![]() Gruß, Alex |
Re: Eigenes Handle finden
Bei
![]()
Delphi-Quellcode:
Hier wird als HWND einfach ein Zeiger auf die Function selbst verwandt. Ich habe das in meiner o.g. Procedure probiert. Es sah auf den ersten Blick ganz verlocken aus. Aber ich hatte schon vermutet, dass es nicht gehen würde, denn Handle <> Pointer. Oder kann man das wider Erwarten zum Laufen bringen mit einem Compilter-Schalter?
function EnumWindowsProc(wHandle: HWND; lb: TListBox): Bool; stdcall; export;
var Title, ClassName: array[0..255] of char; begin Result := True; GetWindowText(wHandle, Title, 255); GetClassName(wHandle, ClassName, 255); if IsWindowVisible(wHandle) then lb.Items.Add(string(Title) + '-' + string(ClassName)); end; procedure TForm1.Button1Click(Sender: TObject); begin EnumWindows(@EnumWindowsProc, Integer(Listbox1)); end; Weiter unten auf ![]() Gruß, Alex |
Re: Eigenes Handle finden
Zitat:
Ist jetzt die Frage, wie erstellts du das Fenster ? |
Re: Eigenes Handle finden
Zitat:
Ich habe kein Fenster und ich erstelle auch keins. Deshalb kenne ich nicht "... das Handle deines Fensters." Wenn dem so wäre, gäbe es das Problem ja nicht. Ich habe eine Anwendung ohne die VCL und ohne jedes Fenster. Ich möchte nur die Namen der vorhandenen Fenster mit der unter ![]()
Delphi-Quellcode:
wieder, der eben ein Handle voraussetzt. Da ich weder ein TForm noch ein TApplication habe, kann ich self.Handle bzw. Application.Handle nicht als Parameter mitgeben. Ich weiß nicht, wie ich mein Problem noch schildern soll.
NextHandle := GetWindow(Application.Handle, GW_HWNDFIRST);
Was gebe ich ohne Fenster als hwnd mit? bzw. Was gibt es für Alternativen für die Funktion? Gruß, Alex |
Re: Eigenes Handle finden
|
Re: Eigenes Handle finden
Wenn Du kein Handle hast, dann kannst Du auch keines übergeben, versuchs an der Stelle mal mit nil oder so.
Sherlock |
Re: Eigenes Handle finden
Zitat:
Ich habe aber ![]() @Luckie Mit EnumWindows muss ich mich noch belesen. Die Frage war im Grunde nur am Rande und wird später noch gebraucht werden. Danke für den Tip. Gruß, Alex [EDIT]Also die Tests laufen Prima. :cheers: Mein Problem ist damit gelöst - die Ausgangsfrage von mir aber nicht: Denn ich kann jetzt zwar die Funktion erfolgreich aufrufen. Das Handle meiner nonVCL-Anwendung kenne ich aber immer noch nicht.[/EDIT] |
Re: Eigenes Handle finden
Wie ist denn deine App nun aufgebaut ?
Ein Handle bekommt diese erst wenn sie auf irgrnd eine Weise ein Fenster erstellt.
Delphi-Quellcode:
Hat zB. kein Handle, sondern nur eine Process ID.
programm Noppe;
uses Windows; begin while True do begin Time = GetTickCount; end; end. |
Re: Eigenes Handle finden
Zitat:
Zum Ablauf: Wenn der Benutzer eine Datei bearbeiten möchte, wird diese auf seinen Rechner in ein Temp-Verzeichnis kopiert. Dort mit dem in Win verknüpften Programm geöffnet. Das Programm wird überwacht (Fenstername und Lock-Datei). Für ersteres brauchte ich ein Handle. Wenn die Datei geschlossen wird, wird geprüft, ob es Änderungen gibt und die Datei dann zurückkopiert oder verworfen. Der Sinn ist es einem lahmen VPN auf die Sprünge zu helfen, kurzfristige Netzausfälle abzupuffern und die Anzahl der über das VPN offen gehaltenen Dateien möglichst auf Null zu reduzieren. Also müsste der Titel vom Thread wohl eher lauten: Eigenes Handle von fensterlosem Programm finden. Soll ich das - soweit noch möglich - ändern? Gruß, Alex |
Re: Eigenes Handle finden
Ohje, da läuft ja einiges an einander vorbei ...
Zuerst einmal Schwedenbitter ist es so, daß nonVCL von den meisten so aufgefasst wird, daß Du eine Anwendung mit Fenstern hast, bei der Du aber keine VCL Komponenten verwendest sondern direkt auf die Windows Fenster API zugreifst. Daher hat Dich auch jeder gefragt, wieso Du das Handle zu Deinem Fenster nicht hast, wenn Du es denn schon manuell erstellt hast. Da Du aber offensichtlich eine Anwendung hast, die keine Fenster anzeigt oder besitzt, ist die Frage recht simpel: Wenn Du kein Fenster erstellst, hast Du auch kein Fenster Handle. Willst Du ein eigenes Fenster Handle haben, musst Du eines erstellen. Ansonsten scheinst Du ja mit Hilfe des Fenster Handle überprüfen zu wollen, ob eine bestimmte Anwendung noch aktiv ist. Das ist um ehrlich zu sein weder sonderlich effektiv noch sicher. Aber wenn Du genau schilderst (am Besten mit exakten Anwendungsnamen) was Du möchtest, wird man Dir sicher nähere Informationen geben können. |
Re: Eigenes Handle finden
Zitat:
Zitat:
Zitat:
![]() Das Problem mit dem Handle hat sich sowieso relativiert: Ich habe jetzt ein paar Fehler provoziert und festgestellt, dass meine Fehlermeldungen nicht in den Vordergrund kommen / von anderen geöffneten Fenstern verdeckt sind. Das ist schlecht, weil sie so niemand sieht und ich musste nachhelfen. Hierzu brauchte ich wiederum das vor Erstellung meines ersten Fensters nicht existente Handle meines Programms. Also habe ich mir ein Message-Only-Window erstellt und kann so dessen Handle gleich verwenden. Wie gesagt: Ich bin für Tipps immer offen. 8) Gruß, Alex |
Re: Eigenes Handle finden
Zitat:
Mit ![]() Zitat:
Delphi-Quellcode:
Bei mir ergibt das folgenden Output:
program Project1;
{$APPTYPE CONSOLE} uses Windows; type TOpenOfficeWindow = record WindowHandle: THandle; WindowTitle: string; end; TOpenOfficeWindowArray = array of TOpenOfficeWindow; POpenOfficeWindowArray = ^TOpenOfficeWindowArray; function EnumWindowsCallback(hwnd: THandle; WindowArray: POpenOfficeWindowArray) : LongBool; stdcall; const WINDOW_TITLE_BUFFER_SIZE = 65 * 1024; OPENOFFICE_WINDOW_CLASSNAME = 'SALFRAME'; var WindowTitle: array [0 .. WINDOW_TITLE_BUFFER_SIZE] of WideChar; WindowClassName: array [0 .. WINDOW_TITLE_BUFFER_SIZE] of WideChar; begin Result := true; // Uns interessieren nur sichtbare Fenster if IsWindowVisible(hwnd) then begin // Wir holen uns den ClassName des Fensters FillChar(WindowClassName, SizeOf(WindowClassName), 0); if (GetClassName(hwnd, @WindowClassName, WINDOW_TITLE_BUFFER_SIZE) > 0) and (WindowClassName = OPENOFFICE_WINDOW_CLASSNAME) then begin // Wir ermitteln den Fenster Titel FillChar(WindowTitle, SizeOf(WindowTitle), 0); GetWindowText(hwnd, @WindowTitle, WINDOW_TITLE_BUFFER_SIZE); // Wir erweitern das übergebene WindowArray um 1 und füllen es mit den ermittelten Informationen SetLength(WindowArray^, Length(WindowArray^) + 1); WindowArray^[ High(WindowArray^)].WindowHandle := hwnd; WindowArray^[ High(WindowArray^)].WindowTitle := WindowTitle; end; end; end; function EraseAndFillWindowArray(var WindowArray: TOpenOfficeWindowArray) : Boolean; begin // Array löschen SetLength(WindowArray, 0); // Wir lassen uns alle Fenster zurückgeben die auf dem Desktop angezeigt werden EnumDesktopWindows(0, @EnumWindowsCallback, Cardinal(@WindowArray)); // Falls Einträge im WindowArray vorhanden sind, geben wir true, ansonsten false zurück Result := Length(WindowArray) <> 0; end; var WindowArray: TOpenOfficeWindowArray; i : Integer; begin writeln(EraseAndFillWindowArray(WindowArray)); writeln; for i := 0 to Length(WindowArray) - 1 do begin writeln('Fenster Handle: ', WindowArray[i].WindowHandle); writeln('Fenster Titel: ', WindowArray[i].WindowTitle); writeln; end; readln; end.
Code:
Jetzt könntest Du Dir noch aus dem Fenstertitel den Dateinamen herauspopeln und wüsstest damit sogar welches Fenster zu welcher Datei gehört (vorrausgesetzt die Dateinamen sind unterschiedlich).
TRUE
Fenster Handle: 196900 Fenster Titel: On-Access scanner design.docx - OpenOffice.org Writer Fenster Handle: 527992 Fenster Titel: onaccessscannerdesign.docx - OpenOffice.org Writer |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:24 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz