piątek, 5 lutego 2016

• Funkcje API - jak pobrać nazwę klasy okna

W poprzednim artykule • Funkcje API - jak pobrać tytuł (tekst) okna o uchwycie hwnd • dowiedzieliśmy się jak wykorzystać interfejs API, aby odczytać tytuł (tekst) okna. Czasami w trakcie działania aplikacji MS Access potrzebujemy sprawdzić nie tylko jaki tytuł (tekst) ma okno, ale także nazwę klasy okna w systemie Windows.

Klasa okna jest to struktura opisująca podstawowe cechy okna: kolor tła, szerokość obramowania, menu sterowania, przyciski minimalizuj, maksymalizuj, zamknij, ikona paska tytułowego, paski przewijania, przypisany do okna kursor myszy i wiele innych cech okna.

• Odczyt nazwy klasy okna o uchwycie hwnd.

MS Access nie posiada żadnych metod i właściwości pozwalających na odczytanie nazwy klasy okna. Aby pobrać nazwę klasy okna musimy skorzystać z interfejsu API i jednej z jego funkcji:
• GetClassName - zwracającą długość pobranej do buforu nazwy klasy okna, a w buforze nazwę klasy okna o uchwycie hwnd.

Option Compare Database
Option Explicit

' • Function GetWinClassName(hWind As Long;[LongLong];[LngPtr]) As String
' --------------------------------------------------------------
' autor: Zbigniew Bratko - 01.2016
' [hWind] - uchwyt okna, którego nazwa klasy będzie pobierana
'           w środowisku 32 bitowym liczba typu Long
'           w środowisku 64 bitowym liczba typy LongLong
'           w środowisku VBA7 może być typu LongPtr
' [Out] - zwraca nazwę klasy okna
' Przy niepowodzeniu zwraca ciąg zerowej długości ""
'

#If VBA7 Then
  Private Declare PtrSafe Function GetClassName Lib "user32" _
          Alias "GetClassNameA" _
          (ByVal hwnd As LongPtr, _
          ByVal lpClassName As String, _
          ByVal nMaxCount As Long) As Long
#Else
  Private Declare Function GetClassName Lib "user32" _
          Alias "GetClassNameA" _
          (ByVal hwnd As Long, _
          ByVal lpClassName As String, _
          ByVal nMaxCount As Long) As Long
#End If

' Funkcja własna GetWinClassName
#If VBA7 Then
  ' Deklaracja funkcji - zarówno w 32 jak i 64 bitowym środowisku VBA 7
  Public Function GetWinClassName(hWind As LongPtr) As String
#Else
  ' Deklaracja funkcji - tylko 32 bitowe środowisko VBA 6
  Public Function GetWinClassName(hWind As Long) As String
#End If
  
Dim sBuffer           As String
Dim lLenText          As Long
Const cMaxSizeBuffer  As Long = 256

   ' przygotuj bufor na przyjęcie tekstu
   sBuffer = String(cMaxSizeBuffer, vbNullChar)
   ' pobierz długość zwróconego tekstu
   lLenText = GetClassName(hWind, sBuffer, cMaxSizeBuffer)
   ' utnij nadmiarowy ciąg znaków vbNullChar w buforze
   GetWinClassName = Left$(sBuffer, lLenText)
  
End Function

' przykładowe wywołanie:
Private Sub btnTest_Click()
 
  ' pobierz nazwę klasu okna formularza i okna aplikacji MS Access
  MsgBox "Nazwa klasy okna formularza: " & _
         GetWinClassName(Me.hwnd) & vbNewLine & _
        "Nazwa klasy okna MS Access: " & _
         GetWinClassName(Application.hWndAccessApp)
End Sub

Po uruchomieniu przykładowego wywołania, MS Access wyświetla okno komunikatu:

• OMain - jest to nazwa klasy okna MS Access.
• OForm - jest to nazwa klasy okna formularza.

Obie te nazwy klas okien warto zapamiętać, gdyż przydadzą się na następnych stronach, na których będziemy korzystali z funkcji API, by odwoływać się do okien MS Access.