vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
sevDataGrid - Gönnen Sie Ihrem SQL-Kommando diesen krönenden Abschluß!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück
Rubrik: System/Windows · Prozesse/Tasks   |   VB-Versionen: VB4, VB5, VB630.10.01
Handle einer mit Shell gestarteten Anwendung

Die Shell-Anweisung liefert als Rückgabewert den TaskID der gestarteten Anwendung. Was aber, wenn man das Fenster-Handle braucht...

Autor:   Dieter OtterBewertung:     [ Jetzt bewerten ]Views:  33.022 
www.tools4vb.deSystem:  Win9x, WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 Beispielprojekt auf CD 

Jeder kennt sie: die Shell-Anweisung. Mit der Shell-Anweisung lässt sich auf einfachste Weise eine externe Anwendung starten - mit oder ohne Parameterübergabe. Als Rückgabewert liefert Shell die TaskID der gestarteten Anwendung. Um nun die gestartete Anwendung per Code zu aktivieren, kann dann die TaskID in Verbindung mit der AppActivate-Anweisung verwendet werden.

Was aber, wenn man das Fenster-Handle der gestarteten Anwendung benötigt? Eben Pech gehabt!

Nein! Ganz und gar nicht. Die nachfolgende Funktion ersetzt die Standard Shell-Anweisung, wobei das Handling exakt genauso erfolgt. D.h. im ersten Parameter geben Sie den Dateinamen und ggf. die Parameter an, der zweite Parameter bestimmt den Fensterstil. Soweit also noch kein Unterschied zur Standard Shell-Anweisung.

Aber jetzt kommts. Als Rückgabewert liefert die Funktion nicht die TaskID, sondern das Fenster-Handle - so wie wir es uns schon oft gewünscht haben

' zunächst die benötigten API-Deklarationen
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 = 2
' Anwendung starten und Fenster-Handle zurückgeben
' Anwendung starten und Fenster-Handle zurückgeben
Private Function Shell2hWnd(ByVal sFilename As String, _
  Optional ByVal Mode As VbAppWinStyle)
 
  Dim lngAppTaskID As Long
  Dim lngProcTaskID As Long
  Dim lnghWnd As Long
 
  ' TaskID der zu startenden Anwendung
  lngAppTaskID = Shell(sFilename, Mode)
 
  ' Anwendung konnte nicht gestartet werden
  If lngAppTaskID = 0 Then Exit Function
 
  ' Fenster durchlaufen und nach Process-ID suchen
  lnghWnd = FindWindow(vbNullString, vbNullString)
  Do While lnghWnd <> 0
 
    ' Existiert kein Eltern-Fenster, dann ProcssID
    ' ermitteln und mit TaskID vergleichen
    If GetParent(lnghWnd) = 0 Then
      GetWindowThreadProcessId lnghWnd, lngProcTaskID
 
      ' Handelt es sich um die gesuchte TaskID?
      If lngProcTaskID = lngAppTaskID Then
        ' Fenster-Handle zurückgeben und Schleife
        ' verlassen!
        Shell2hWnd = lnghWnd
        Exit Do
      End If
 
    End If
 
    ' Nächstes Fenster
    lnghWnd = GetWindow(lnghWnd, GW_HWNDNEXT)
  Loop
End Function

Ein kleines Anwendungsbeispiel
Beim Klicken auf einen CommandButton soll der Windows-Taschenrechner geöffnet werden und immer im Vordergrund angezeigt werden. Um ein Fenster in den Vordergrund zu bringen, brauchen wir bekanntlich die API-Funktion SetWindowPos und natürlich das entsprechende Fenster-Handle.

' API für das Ermitteln des Systemordners
Private Declare Function GetSystemDirectory Lib "kernel32" _
  Alias "GetSystemDirectoryA" ( _
  ByVal lpBuffer As String, _
  ByVal nSize As Long) As Long
 
' API für das Anzeigen eines Fensters im Vordergrund
Private Declare Function SetWindowPos Lib "user32" ( _
  ByVal hWnd As Long, _
  ByVal hWndInsertAfter As Long, _
  ByVal x As Long, _
  ByVal y As Long, _
  ByVal cx As Long, _
  ByVal cy As Long, _
  ByVal wFlags As Long) As Long
 
' Konstanten
Private Const HWND_TOPMOST = -1
Private Const HWND_NOTOPMOST = -2
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOSIZE = &H1
 
' API für das Beenden einer Anwendung
Private Declare Function SendMessage Lib "user32" _
  Alias "SendMessageA" ( _
  ByVal hWnd As Long, _
  ByVal wMsg As Long, _
  ByVal wParam As Long, _
  ByVal lParam As Long) As Long
 
' Konstante - Fenster schliessen
Private Const WM_CLOSE = &H10
 
' Fenster-Handle der gestarteten Anwendung
Dim app_hWnd As Long
' Windows-System-Verzeichnis ermitteln
Public Function GetSystemDir() As String
  Dim Temp As String
  Dim lResult As Long
 
  Temp = Space$(256)
  lResult = GetSystemDirectory(Temp, Len(Temp))
  Temp = Left$(Temp, lResult)
  If Right$(Temp, 1) <> "\" Then Temp = Temp + "\"
  GetSystemDir = Temp
End Function
' Fenster in den Vordergrund setzen
Public Sub FormOnTop(ByVal hWnd As Long, _
  ByVal OnTop As Boolean)
 
  If OnTop Then
    ' immer im Vordergrund
    SetWindowPos hWnd, HWND_TOPMOST, 0, 0, 0, 0, _
      SWP_NOMOVE Or SWP_NOSIZE
  Else
    ' normal
    SetWindowPos hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, _
      SWP_NOMOVE Or SWP_NOSIZE
  End If
End Sub
' Taschenrechner starten und im
' Vordergrund anzeigen
Private Sub cmdCalcShow_Click()
  Dim sWinSysPath As String
 
  ' Anwendung starten...
  sWinSysPath = GetSystemDir()
  app_hWnd = Shell2hWnd(winSysPath & "calc.exe")
 
  ' ...und in den Vordergrund setzen
  If app_hWnd <> 0 Then
    FormOnTop app_hWnd, True
  End If
End Sub
 
' Taschenrechner wieder normal anzeigen
Private Sub cmdCalcNormal_Click()
  If app_hWnd <> 0 Then
    FormOnTop app_hWnd, False
  End If
End Sub
 
' Taschenrechner per Programmcode beenden
Private Sub cmdCalcHide_Click()
  If app_hWnd <> 0 Then
    SendMessage app_hWnd, WM_CLOSE, 0&, 0&
  End If
End Sub

Dieser Tipp wurde bereits 33.022 mal aufgerufen.

Voriger Tipp   |   Zufälliger Tipp   |   Nächster Tipp

Über diesen Tipp im Forum diskutieren
Haben Sie Fragen oder Anregungen zu diesem Tipp, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

Aktuelle Diskussion anzeigen (4 Beiträge)

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6
(einschl. Beispielprojekt!)

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
   

Druckansicht Druckansicht Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel