Seite 1 von 2
ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)
Verfasst: 13.10.2009 18:28
von al90
Hi All,
Da ich Gestern selbst mächtig probleme damit hatte, eine Routine zu finden die mir den hWnd-Handle
nach dem Ausführen einer Datei zurückliefert und ich dieses Problem aber inzwichen Lösen konnte,
möchte ich die Routine mal hier bekannt geben, damit sich andere nicht auch noch damit rumplagen müssen.
Also der Code ist recht Simpel. Er Startet eine Datei (mit Win+GUI) und liefert dabei statt der ProcessID den Fenster-Handle. (hWnd)
Ich denke mal der eine oder andere wird es sicherlich noch gebrauchen können.
Code: Alles auswählen
Procedure.i EnumWindowsCallBack(hwnd.i, Handle.i)
Protected Title$ = Space(1024), ProcessID.i, st.i = #True
GetWindowText_(hwnd, @Title$, Len(Title$))
GetWindowThreadProcessId_(hwnd, @ProcessID)
If Title$<>"" And IsWindowVisible_(hwnd)
If ProcessID = PeekI(Handle)
PokeI(Handle, hwnd)
st = #False
EndIf
EndIf
ProcedureReturn st
EndProcedure
Procedure.i Execute_WindowFile(Filename$, Parameter$, WorkDir$)
Protected st.i, Handle.i, Check.i
If FileSize(Filename$) > 0
st = RunProgram(Filename$, Parameter$, WorkDir$, #PB_Program_Open)
Else
ProcedureReturn #Null
EndIf
Handle = ProgramID(st) : Check = Handle
Repeat
Delay(10)
EnumWindows_(@EnumWindowsCallBack(), @Handle)
Until Handle <> Check And IsWindow_(Handle) <> #Null
CloseProgram(st)
ProcedureReturn Handle
EndProcedure
file$ = GetEnvironmentVariable("SystemRoot") + "\System32\calc.exe"
hwnd = Execute_WindowFile(file$, "", "")
Delay(500)
CloseWindow_(hwnd)
Delay(500)
OpenIcon_(hwnd)
Delay(1500)
SendMessage_(hwnd, #WM_CLOSE, 0, 0)
Debug "Window-Handle ( hWnd.l ) = " + Str(hwnd)
Getestet unter Vista & 7
Re: ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)
Verfasst: 13.10.2009 21:01
von milan1612
Sehr brauchbarer Code, danke schön
Funzt übrigens auch unter Win 7...
Re: ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)
Verfasst: 13.10.2009 21:20
von edel
milan1612 hat geschrieben:Funzt übrigens auch unter Win 7...
Fragt sich nur wie lange.
Der Callback ist falsch, siehe hier :
http://msdn.microsoft.com/en-us/library/ms633498.aspx
Re: ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)
Verfasst: 13.10.2009 21:27
von Thorium
Du solltest auch Integer verwenden anstatt Long. Unter x64 sind alle ID's und Handle Quads. So ist der Code nicht sicher lauffähig unter x64.
Re: ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)
Verfasst: 13.10.2009 22:04
von edel
Der Code ist auch sonst etwas komisch, z.b. :
- "While WindowHandle = #Null", startest du ein Programm das versteckt oder gar kein Fenster hat, laeuft es sich tot.
- "IsWindowVisible_(hwnd) And Title$<>""" ist eher suboptimal, es gibt auch Fenster da steht nüscht drin und sichtbar muss sich auch nicht sein. In diesem Fall laeuft sich das Programm wieder einen Wolf.
- Wenn das Fenster gefunden wurde, waere ein vorzeitiger Abbruch auch nicht verkehrt.
- die Globalen Variablen wuerde ich entfernen und lieber eine Variable mit Struktur nehmen, diese wird dann bei EnumWindows als Parameter uebergeben, so kann man das auch in einem anderen Thread laufen lassen.
Re: ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)
Verfasst: 13.10.2009 22:24
von al90
milan1612 hat geschrieben:Funzt übrigens auch unter Win 7...
Schön zu wissen.
@Thorium & @edel
Ja ich weis das der code noch ausbaufähig ist und einiges geändert werden muss/sollte.
Hab ihn mal auf die schnelle zusammengeschustert, mit Teilweise schnippseln hier vom Board.
Werde es mal noch abändern. Ansonsten steht es ja jedem frei den Code selbst nach seinem
Geschmack anzupassen.
Was die Fenster betrifft; Das war auch so beabsichtigt. Es sollen damit in erster Linie Windowed-
Fenster-Apps geladen werden. Deshalb auch die Bezeichnung
Execute_WindowFile() für die proc.

Re: ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)
Verfasst: 13.10.2009 22:39
von Thorium
al90 hat geschrieben:
@Thorium & @edel
Ja ich weis das der code noch ausbaufähig ist und einiges geändert werden muss/sollte.
Hab ihn mal auf die schnelle zusammengeschustert, mit Teilweise schnippseln hier vom Board.
Werde es mal noch abändern. Ansonsten steht es ja jedem frei den Code selbst nach seinem
Geschmack anzupassen.
War auch nur als konstruktive Kritik gemeint. Generell lohnt es sich sich anzugewöhnen Integer statt Long und Quad zu verwenden. Erspart einem die Umstellung und damit verbundene Fehlersuche, wenn man mal auf x64 umsteigt, was früher oder später sowieso zum muss wird.
Long und Quad machen nurnoch Sinn wenn diese Datentypen explicit erforderlich sind. Z.B. bei Dateiheadern und anderen Strukturen oder Quad auch wenn man mit großen Zahlen hantieren muss. Für alles andere Integer.
Re: ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)
Verfasst: 14.10.2009 00:41
von al90
Thorium hat geschrieben:War auch nur als konstruktive Kritik gemeint.
Kein problem. Kritik gehört eben mal dazu. Egal ob gut oder schlecht

Re: ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)
Verfasst: 14.10.2009 23:50
von al90
So hab den Code jetzt nochmal ein wenig überarbeitet.
Folgende Änderungen:
1) Fehler in der CallbackProc behoben.
2) Die ProgramID von RunProgram() wird jetzt direkt an der CallbackProc übergeben.
3) Die CallbackProc wird nun vorzeitig verlassen, sobald der Handle ermittelt wurde.
4) Wenn die Datei nicht gefunden wurde, wird jetzt '0' zurückgegeben, statt in einer EndlosSchleife hängen zu bleiben.
Code: Alles auswählen
Procedure.l EnumWindowsCallBack(hwnd, ProgramID.l)
Protected Title$ = Space(1024), ProcessID.l, st.l = #True
Shared WindowHandle.l
GetWindowText_(hwnd, @Title$, Len(Title$))
GetWindowThreadProcessId_(hwnd, @ProcessID)
If IsWindowVisible_(hwnd) And Title$<>""
If ProcessID = ProgramID
WindowHandle = hwnd
st = #False
EndIf
EndIf
ProcedureReturn st
EndProcedure
Procedure.l Execute_WindowFile(Filename$, Parameter$, WorkDir$)
Protected st
Shared WindowHandle.l
If FileSize(Filename$) > 0
st = RunProgram(Filename$, Parameter$, WorkDir$, #PB_Program_Open)
Else
ProcedureReturn 0
EndIf
While WindowHandle = #Null
Delay(10)
EnumWindows_(@EnumWindowsCallBack(), ProgramID(st))
Wend
CloseProgram(st)
ProcedureReturn WindowHandle
EndProcedure
file$ = GetEnvironmentVariable("SystemRoot") + "\System32\calc.exe"
hwnd = Execute_WindowFile(file$, "", "")
Delay(500)
CloseWindow_(hwnd)
Delay(500)
OpenIcon_(hwnd)
Debug "Window-Handle ( hWnd.l ) = " + Str(hwnd)
BTW: Integer habe ich erstmal weggelassen, da ich eh kein 64bit System zum Testen habe.
Re: ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)
Verfasst: 14.10.2009 23:59
von ts-soft
al90 hat geschrieben:
BTW: Integer habe ich erstmal weggelassen, da ich eh kein 64bit System zum Testen habe.
Was willste da Testen? Defaultvariable ist nicht mehr long sondern integer, immer.
Du brauchst da nichts testen und ich brauch mir nichts anpassen
Gruß
Thomas