VBA Tipp: Anwendungsfenster zählen

Aus DBWiki
Wechseln zu: Navigation, Suche

Problem

Ich möchte herausfinden, wie viele Anwendungsfenster einer bestimmten Anwendung gleichzeitig vorhanden sind.

Lösung

Eine Möglichkeit dazu ist, den Windows-Klassennamen der Anwendung zu verwenden (dies leistet die unten vorgestellte Funktion CountAppsByClass), eine andere, den Fenster-Titel der Anwendung heranzuziehen (CountAppsByCaption). Je nach Art der Anwendung ist die eine oder andere Variante vorzuziehen. (Der Microsoft Internet Explorer ändert z.B. je nach dargestellter Web-Seite den Fenster-Titel, dort bietet sich also an, die Funktion CountAppsByClass zu verwenden.

Private Declare Function GetDesktopWindow Lib "User32" () _
                As Long
Private Declare Function GetWindow Lib "User32" _
       (ByVal hWnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetWindowText Lib "User32" _
        Alias "GetWindowTextA" _
        (ByVal hWnd As Long, ByVal lpString As String, _
        ByVal cch As Long) As Long
Private Declare Function GetClassName Lib "User32" _
        Alias "GetClassNameA" _
        (ByVal hWnd As Long, ByVal lpClassName As String, _
        ByVal nMaxCount As Long) As Long
Private Const GW_CHILD = 5
Private Const GW_HWNDNEXT = 2
Public Function CountAppsByClass(Optional strClass As String = "OMain")
'
' Zählt alle Fenster der angegebenen Window-Klasse
'
Dim hWnd As Long, tbuf As String, RetVal As Long
Dim I As Long, Cnt As Long
  hWnd = GetDesktopWindow()
  hWnd = GetWindow(hWnd, GW_CHILD)
  I = 0:  Cnt = 0
  Do While hWnd <> 0 And I < 1000
    tbuf = String(255, 0)
    RetVal = GetClassName(hWnd, tbuf, Len(tbuf))
    If Mid(tbuf, 1, RetVal) = strClass Then Cnt = Cnt + 1
    hWnd = GetWindow(hWnd, GW_HWNDNEXT)
    I = I + 1
  Loop
  CountAppsByClass = Cnt
End Function
 
Public Function CountAppsByCaption _
  (Optional strCaption As String = "Microsoft Access")
'
' Zählt alle Fenster mit dem angegebenen Fenster-Titel
'
Dim hWnd As Long, tbuf As String, RetVal As Long, I As Long, Cnt As Long
  hWnd = GetDesktopWindow()
  hWnd = GetWindow(hWnd, GW_CHILD)
  I = 0:  Cnt = 0
  Do While hWnd <> 0 And I < 1000
    tbuf = String(255, 0)
    RetVal = GetWindowText(hWnd, tbuf, Len(tbuf))
    If Mid(tbuf, 1, RetVal) = strCaption Then Cnt = Cnt + 1
    hWnd = GetWindow(hWnd, GW_HWNDNEXT)
    I = I + 1
  Loop
  CountAppsByCaption = Cnt
End Function

Die Klassennamen einiger gängiger Applikationen sind:

Applikation Klassenname
Rechner SciCalc
Excel XLMain
Word OpusApp
Internet Explorer IEFrame
Access OMain
PowerPoint95 PP7FrameClass
Powerpoint97 PP97FrameClass
Notepad Notepad
Paintbrush pbParent
Frontpage 2000 FrontPageExplorerWindow40
Wordpad WordPadClass
CorelDraw 7.0 CorelDRAW 7.0
Outlook2000 rctrl_renwnd32

Weitere Klassennamen kann man mit entsprechenden Tools ermitteln wie z.B. dem von MS mit Visual Studio mitgelieferten Spy++ , mit WinCheat von Alin Constantin oder dem InfTool von mossSOFT.

Aufruf

If CountAppsByClass("OpusApp") = 0 Then
  MsgBox "Word läuft derzeit nicht!"
End If

Mit dem folgenden Aufruf kann man z.B. sicherstellen, dass nur eine Instanz einer bestimmten Access-Anwendung zur Zeit läuft:

If CountAppsByCaption("Meine Anwendung")>1 Then
  Application.Quit
End If