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 Handle von Firefox bei ShellExecuteEx (https://www.delphipraxis.net/135329-handle-von-firefox-bei-shellexecuteex.html)

Aljoscha 9. Jun 2009 01:34


Handle von Firefox bei ShellExecuteEx
 
Hallo! :-)
Ich habe folgendes Problem, ich möchte gerne ein neues Fenster im Firefox öffnen und das dazugehörige Handle erhalten.
Das Ganze habe ich bis jetzt mit ShellExecuteEx realisiert:

Delphi-Quellcode:
ShExecInfo.cbSize := sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.lpVerb := nil;
ShExecInfo.lpFile := PChar(GetDefaultBrowser);
ShExecInfo.lpDirectory := PChar(ExtractFilePath(GetDefaultBrowser));
ShExecInfo.lpParameters := PChar('-new-window ' + pageurl);
ShExecInfo.nShow := SW_SHOWNORMAL;

ShellExecuteEx(@ShExecInfo);
Das funktioniert auch soweit ganz gut!
Allerdings erhalte ich in ShExecInfo.hProcess als Handle immer nur "1684", was aber leider falsch ist :s
Hat jemand von euch ein Idee wie ich an das Handle des neu geöffneten Fensters kommen kann?
Danke im vorraus für eure Hilfe :-)

Oldy 9. Jun 2009 03:18

Re: Handle von Firefox bei ShellExecuteEx
 
was ist denn dieses ShExecInfo ?

wenn cihdas ncih weiß kann ich da ehrlich egsagt auch ncih heflfen.
aber um auf den threadtitel hinzukommen:
Probiers mit FindWindow und FindWindowEx
Delphi-Quellcode:
var
   s:string;
hwnd:integer;
begin
s:='sitename'; // dass der gesamte Seitenname gefunden wird
hwnd:= FindWindow(nil,s+' - Mozilla Firefox';
//Um Noch die Editbox zu finden:
//hwnd:=FindWindowEx(hwnd, 0, 'Edit', nil);
Weiß nich, ob das das is was du suchst, verstehe deine Frage nich so :drunken: , weder is das mit dem kompletten fensternamen mit FF getestet.

jaenicke 9. Jun 2009 04:52

Re: Handle von Firefox bei ShellExecuteEx
 
Zitat:

Zitat von Oldy
was ist denn dieses ShExecInfo ?

Eine Variable vom Typ SHELLEXECUTEINFO sicherlich, was sonst? :gruebel:

Zitat:

Zitat von Aljoscha
Allerdings erhalte ich in ShExecInfo.hProcess als Handle immer nur "1684", was aber leider falsch ist :s

Das ist nicht falsch, das ist aber kein Fensterhandle, siehe Dokumentation.
Du müsstest jetzt in diesem Prozess nach Fenstern suchen. Allerdings ist EnumThreadWindows für Threads, d.h. du müsstest wohl erst den Hauptthread suchen.

Womit es aber direkt gehen sollte ist CreateProcess, denn das liefert dir ja direkt den Hauptthread mit zurück. Und den könntest du dann direkt für EnumThreadWindows nutzen.

Fridolin Walther 9. Jun 2009 13:48

Re: Handle von Firefox bei ShellExecuteEx
 
Zitat:

Zitat von jaenicke
... denn das liefert dir ja direkt den Hauptthread mit zurück.

Nur um das klar zu stellen: So etwas wie ein "Hauptthread" existiert nicht. Windows kennt zw. Threads keinerlei Unterschiede. Eine Anwendung bleibt ebenso solange aktiv bis alle Threads beendet sind oder explizit ExitProcess aufgerufen wird.

Ansonsten hat jaenicke recht. Du bekommst dort ein Prozesshandle und kein Fensterhandle. Um an das Fensterhandle zu gelangen musst Du FindWindow oder alternativ die Enum*Windows Funtkionen bemühen. Siehe dazu z.B. kurze Demo Anwendung:
Delphi-Quellcode:
program Project2;

{$APPTYPE CONSOLE}

uses
  windows, sysutils;

var
  HandleArray : array of THandle;

function EnumWindowsCallback(Handle : THandle; ProcessId : DWORD) : LongBool; stdcall;
var
  ProcessIdOfHandle : DWORD;
begin
  GetWindowThreadProcessID(Handle, ProcessIdOfHandle);
  if (ProcessIdOfHandle = ProcessId) and (IsWindowVisible(Handle)) then
    begin
      SetLength(HandleArray, Length(HandleArray) + 1);
      HandleArray[Length(HandleArray) - 1] := Handle;
    end;
  Result := true;
end;

function GetVisibleWindowsOfProcess(ProcessId : DWORD) : Boolean;
begin
  SetLength(HandleArray, 0);
  Result := EnumWindows(@EnumWindowsCallback, ProcessId) and (Length(HandleArray) > 0);
end;

var
  i : Integer;
begin
  if GetVisibleWindowsOfProcess(2112) then
    for i := 0 to Length(HandleArray) - 1 do
      begin
        writeln(HandleArray[i]);
      end;
  readln;
end.

jaenicke 9. Jun 2009 17:58

Re: Handle von Firefox bei ShellExecuteEx
 
Zitat:

Zitat von 0xF30FC7
Zitat:

Zitat von jaenicke
... denn das liefert dir ja direkt den Hauptthread mit zurück.

Nur um das klar zu stellen: So etwas wie ein "Hauptthread" existiert nicht.

Ja, ich weiß. Dann übersetze ich es eben wörtlich aus der Doku: "primärer Thread". Da der Firefox bisher nicht multithtreaded ist, wird das vermutlich der am Anfang gestartete Thread sein, der die Fenster steuert und damit für EnumThreadWindows gebraucht wird. Ausprobiert habe ich es nicht.

Aljoscha 9. Jun 2009 20:57

Re: Handle von Firefox bei ShellExecuteEx
 
Vielen Dank für die Hilfe und das Beispiel erstmal!
Wenn ich es aber wie beschrieben aufrufe wird mir kein einziges Fensterhandle ausgegeben :-(
if GetVisibleWindowsOfProcess(xxx) ist immer false.
Gibt es eine andere Möglichkeit testweise das Handle zu ermitteln?
Mit WinSpy bin ich leider nicht weiter gekommen.

Fridolin Walther 9. Jun 2009 23:57

Re: Handle von Firefox bei ShellExecuteEx
 
Zitat:

Zitat von Aljoscha
Vielen Dank für die Hilfe und das Beispiel erstmal!
Wenn ich es aber wie beschrieben aufrufe wird mir kein einziges Fensterhandle ausgegeben :-(
if GetVisibleWindowsOfProcess(xxx) ist immer false.
Gibt es eine andere Möglichkeit testweise das Handle zu ermitteln?
Mit WinSpy bin ich leider nicht weiter gekommen.

1. Wenn Du die Funktion direkt nach dem ShellExecute aufrufst, sind unter Umständen die Fenster noch gar nicht erstellt.
2. Du übergibst hoffentlich eine Process ID und kein Handle.

Aljoscha 10. Jun 2009 14:12

Re: Handle von Firefox bei ShellExecuteEx
 
Hallo!
Ja daran habe ich gedacht.
Ich habe eben gemerkt das es einwandfrei funktioniert, wenn noch kein Firefox Fenster geöffnet war!
Also wenn ich firefox komplett beende und meinen Code ausführe klappt alles wunderbar.
Aber wenn schon ein Fenster geöffnet ist und ich mit meinem Code ein weiteres öffne, dann klappt das leider nicht :(
Ich hole mir die PID mit
Delphi-Quellcode:
GetProcessId(ShExecInfo.hProcess)
aus der uallcollection.
Die PID die ich allerdings immer mit meinem Handle erhalte ist nicht die selbe wie wenn ich die PID von Firefox manuell per
Delphi-Quellcode:
uallProcess.FindProcess(PChar('firefox'))
ermittle.
Leider kann ich auch nicht einfach immer auf dem funktionierenden Weg die pid von firefox ermitteln, da dies doch zu bugs führen würde wenn mehr als ein prozess firefox.exe läuft.
Oder habe ich da jetzt einen Denkfehler?

jaenicke 10. Jun 2009 14:15

Re: Handle von Firefox bei ShellExecuteEx
 
Naja, aber Moment mal FindProcess wird einfach die alte Instanz und damit einen anderen Wert finden.

Zudem habe ich bereits auf CreateProcess hingewiesen, damit bekommst du direkt das Prozesshandle und die Prozess-ID.

Aljoscha 10. Jun 2009 14:41

Re: Handle von Firefox bei ShellExecuteEx
 
CreateProcess wollte ich vermeiden, weil ich gelesen habe das es da wohl Probleme mit Vista gibt.
Und es gibt ja eigentlich nur eine Instanz von Firefox, das ist ja das Merkwürdige.
Und selbst wenn es zwei Instanzen gäbe und der Code die ältere findet, sollte er ja trotzdem ein passendes Fensterhandle ausgeben, weil diese Instanz ja auch ein sichtbares Fenster hat.
Ich bin irgendwie im Moment ein wenig verwirrt :P


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:38 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