VB 5/6-Tipp 0333: Fensterhandle des mittels Shell gestarteten Programmes erfahren
von Elmar Leinen
Beschreibung
Beim Aufruf eines Programms mit dem Shell-Befehl, wird eine sogenannte ProcessID zurückgegeben, mit der man erstmal recht wenig anfangen kann. Um anhand dieser ID z.B. ein Fensterhandle zu erhalten, ist es notwendig durch alle derzeit vorhandenen Fenster zu iterieren, um deren ProcessID mit der vorgegebenen vergleichen zu können.
Schwierigkeitsgrad: | Verwendete API-Aufrufe: FindWindowA (FindWindow), GetParent, GetWindow, GetWindowThreadProcessId | Download: |
'Dieser Quellcode stammt von http://www.activevb.de 'und kann frei verwendet werden. Für eventuelle Schäden 'wird nicht gehaftet. 'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum. 'Ansonsten viel Spaß und Erfolg mit diesem Source! '------------- Anfang Projektdatei Project1.vbp ------------- '--------- Anfang Formular "Form1" alias Form1.frm --------- ' Steuerelement: Schaltfläche "Command1" ' Steuerelement: Beschriftungsfeld "Label2" ' Steuerelement: Beschriftungsfeld "Label1" 'Autor: Elmar Leinen 'E-Mail: elmarleinen@gmx.net Option Explicit Private Declare Function GetWindowThreadProcessId Lib "user32" _ (ByVal hwnd As Long, lpdwProcessId As Long) As Long Private Declare Function FindWindow Lib "user32" Alias _ "FindWindowA" (ByVal lpClassName As String, ByVal _ lpWindowName As String) As Long Private Declare Function GetWindow Lib "user32" (ByVal hwnd As _ Long, ByVal wCmd As Long) As Long Private Declare Function GetParent Lib "user32" (ByVal hwnd As _ Long) As Long Private Const GW_HWNDNEXT As Long = 2& Private Retval As Long Private Sub Command1_Click() Dim NotePadhWnd As Long NotePadhWnd = ShellTohWnd("c:\windows\notepad.exe", vbNormalNoFocus) Label2.Caption = NotePadhWnd End Sub Private Function ShellTohWnd(ByVal hhwPfad As String, Optional Mode As VbAppWinStyle) Dim ProcHWND As Long, ProcHWN As Long ProcHWND = Shell(hhwPfad, Mode) Retval = FindWindow(vbNullString, vbNullString) Do While Retval <> 0 If GetParent(Retval) = 0 Then Call GetWindowThreadProcessId(Retval, ProcHWN) If ProcHWN = ProcHWND Then ShellTohWnd = Retval Exit Do End If End If Retval = GetWindow(Retval, GW_HWNDNEXT) Loop End Function '---------- Ende Formular "Form1" alias Form1.frm ---------- '-------------- Ende Projektdatei Project1.vbp --------------
Tipp-Kompatibilität:
Windows/VB-Version | Win32s | Win95 | Win98 | WinME | WinNT4 | Win2000 | WinXP |
VB4 | |||||||
VB5 | |||||||
VB6 |
Ihre Meinung
Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.
Archivierte Nutzerkommentare
Klicken Sie diesen Text an, wenn Sie die 9 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.
Kommentar von Horst Brand am 21.04.2008 um 17:19
Hallo,
habe die Prozeß-ID des Brother-ControlCenter2.
Diese wird in der WHILE-Schleife nie erreicht, obwohl das Fenster geöffnet ist. Liegt es daran, dass Brother-ControlCenter2 kein MS-Programm ist, wie unten angedeutet wird?
Gruß
Horst Brand
Kommentar von 6for9 GrafiX am 09.08.2006 um 14:30
Hi ICh hab hier mal den Code angehängt womit es auch bei vb.net (2005) geht ;)
Habs auch so umgebaut das es mit Fenster geht die nicht von MS sind :D :)
Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Integer, ByVal hWndNewParent As Integer) As Integer
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
Private Declare Function MoveWindow Lib "user32" (ByVal hwnd As Integer, ByVal X As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal bRepaint As Integer) As Integer
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Integer, ByVal nCmdShow As Integer) As Integer
Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As Integer, ByVal lpString As String) As Integer
Private Declare Function GetDeskTopWindow Lib "user32" Alias "GetDesktopWindow" () As Integer
Private lhwnd As Integer
Private ret As Integer
Private Sub Command1_Click()
Dim Command2 As Object
Dim Command1 As Object
Dim ltop As Integer
Dim lleft As Integer
Dim lwidth As Integer
Dim lheight As Integer
' Notepad starten
Dim p = Shell(My.Application.Info.DirectoryPath & "\app.exe", AppWinStyle.Hide)
' Warten bis vollstaendig geladen
' Handle des neuen Notepad-Fensters feststellen
lhwnd = FindWindow(vbNullString, "app Title")
If lhwnd <> 0 Then
'UPGRADE_WARNING: Couldn't resolve default property of object Command1.Enabled. Click for more: 'ms-help://MS.VSExpressCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
' Jetzt wird das Fenster geklaut
'UPGRADE_WARNING: Couldn't resolve default property of object Me.hwnd. Click for more: 'ms-help://MS.VSExpressCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
Call SetParent(lhwnd, Me.Handle)
' Ausmasse festlegen (Scalemode von Form1 muss Pixel sein)
'UPGRADE_WARNING: Couldn't resolve default property of object Command1.Height. Click for more: 'ms-help://MS.VSExpressCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
'UPGRADE_WARNING: Couldn't resolve default property of object Command1.Top. Click for more: 'ms-help://MS.VSExpressCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
lleft = 0
'UPGRADE_WARNING: Couldn't resolve default property of object Me.ScaleWidth. Click for more: 'ms-help://MS.VSExpressCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
lwidth = Me.Width
'UPGRADE_WARNING: Couldn't resolve default property of object Me.ScaleHeight. Click for more: 'ms-help://MS.VSExpressCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
lheight = Me.Height - ltop
' Neue Ausmasse setzen
Call MoveWindow(lhwnd, lleft, ltop, lwidth, lheight, 1)
' Caption zuweisen
ret = SetWindowText(lhwnd, "Kidnapped Notepad")
' Sichtbar machen
ret = ShowWindow(lhwnd, 1)
End If
End Sub
Private Sub Command2_Click()
Dim Command2 As Object
Dim Command1 As Object
Dim dh As Integer
' Handle des Desktop bestimmen
dh = GetDeskTopWindow()
' Programm wieder in den Desktop setzen.
Call SetParent(lhwnd, dh)
'UPGRADE_WARNING: Couldn't resolve default property of object Command1.Enabled. Click for more: 'ms-help://MS.VSExpressCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
Command1.Enabled = True
'UPGRADE_WARNING: Couldn't resolve default property of object Command2.Enabled. Click for more: 'ms-help://MS.VSExpressCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
Command2.Enabled = False
End Sub
Private Sub Form_Unload(ByRef Cancel As Short)
Call Command2_Click()
End Sub
Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Click
Call Command1_Click()
End Sub
Hoffe es hilft einigen ;)
Gruß 6for9 GrafiX
Kommentar von Ranti am 14.02.2005 um 22:48
Hallo!
der Tipp funktioniert prächtig; allerdings nicht mit dem Explorer (nicht IE). Warum nicht? und was muss ich ändern damit er mit dem Explorer funktioniert????
Kommentar von Michael Wolf am 06.02.2005 um 16:54
Bekomme keinen Handle, versuche ein cmd-fenster (c:\windows\system32\dcm.exe) zu öffnen, warum?
Kommentar von Erik am 09.05.2003 um 22:57
Warum bekom ich keine handle weile ich ein Word task start in:
Kommentar von am 08.04.2003 um 13:47
WARUM BEKOMME ICH MANCHMAL EINEN 0-Handle für das shell gestartete Prog zurück ???
Kommentar von Rudi am 26.11.2001 um 15:27
etwas holprig, aber doch möglich:
den algoritmus aus tip123 vorher und nachher durchlaufen und überprüfen, welches fenster dazugekommen ist.
Kommentar von Cycrotec am 02.06.2001 um 22:49
Warum willst du ShellExecute nehmen?
Nimm doch
set xl=createobject_
_("Excel.sheet")
Kommentar von HolgerH am 19.03.2001 um 14:51
Habe ein Problem, bei dem die obrigen Lösung zwar gute Ansätze zeigt, mir aber nicht so richtig weiterhilft:
Ich möchte nicht Anwendungen starten sondern dierekt bestimmte Dateien .doc .xls .???
Ich benutze dazu die ShellExecute-Anweisung. Ich benötige allerdings auch hier irgendwie die Möglichkeit das Fenster der gestarteten Datei zu aktivieren.
=:-)
HH