ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
al90
Beiträge: 1103
Registriert: 06.01.2005 23:15
Kontaktdaten:

ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)

Beitrag 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. :wink:

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. :allright:

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
Zuletzt geändert von al90 am 29.03.2010 22:17, insgesamt 2-mal geändert.
Benutzeravatar
milan1612
Beiträge: 810
Registriert: 15.04.2007 17:58

Re: ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)

Beitrag von milan1612 »

Sehr brauchbarer Code, danke schön :allright:
Funzt übrigens auch unter Win 7...
Bin nur noch sehr selten hier, bitte nur noch per PN kontaktieren
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Re: ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)

Beitrag 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
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)

Beitrag 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.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Re: ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)

Beitrag 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.
Benutzeravatar
al90
Beiträge: 1103
Registriert: 06.01.2005 23:15
Kontaktdaten:

Re: ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)

Beitrag von al90 »

milan1612 hat geschrieben:Funzt übrigens auch unter Win 7...
Schön zu wissen. :D

@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. :wink:

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. :wink:
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)

Beitrag 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. :wink:
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.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
al90
Beiträge: 1103
Registriert: 06.01.2005 23:15
Kontaktdaten:

Re: ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)

Beitrag 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 :wink:
Benutzeravatar
al90
Beiträge: 1103
Registriert: 06.01.2005 23:15
Kontaktdaten:

Re: ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)

Beitrag von al90 »

So hab den Code jetzt nochmal ein wenig überarbeitet. :wink:

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.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: ExecuteFile mit hWnd Rückgabewert (Fenster-Handle)

Beitrag 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
Antworten