• Czy w 64-bitowym VBA 7 właściwość Me.hwnd jest liczbą typu LongLong ?
Z artykułu VBA 7.0 i MS Access 2010+ wiemy, że w 32-bitowym środowisku wszystkie
uchwyty i wskaźniki są liczbą typu Long, a w środowisku 64-bitowym liczbą typu LongLong. W celu ułatwienia pisanie przenośnego kodu wprowadzono
w środowisku VBA 7 nową liczbę typu LongPtr, która przyjmuje w 32-bitowym środowisku typ Long (liczba 4 bajtowa),
a w 64-bitowej wersji typ LongLong (8 bajtowa liczba).
Przypisanie uchwytu lub wskaźnika w środowisku 64-bitowym do zmiennej typu Long jest niepoprawne i może prowadzić do nieprzewidzianych błędów,
ponieważ 64-bitowy uchwyt lub wskaźnik może zostać „ucięty” do wartości 32-bitowej i wskazywać na nieprawidłowy obiekt.
Piszę, „może zostać ucięty”, gdyż w przypadku nieprzekroczenia przez uchwyt zakresu liczby Long, nie zmieni on wartości przy przypisaniu
do zmiennej typu Long.
• Jak przekazać uchwyt hwnd w 32-bitowej i 64-bitowej wersji MS Access 2010+ ?
Napiszmy prostą przykładową funkcję by pobrać i przypisać do zmiennej hWind uchwyt hwnd okna formularza MS Access
i odczytać jego tytuł za pomocą funkcji API GetTextWindow(...).
#If VBA7 Then
Private Declare PtrSafe Function GetWindowText Lib "user32" _
Alias "GetWindowTextA" ( _
ByVal hwnd As LongPtr, _
ByVal lpString As String, _
ByVal cch As Long) As Long
#Else
Private Declare Function GetWindowText Lib "user32" _
Alias "GetWindowTextA" ( _
ByVal hwnd As Long, _
ByVal lpString As String, _
ByVal cch As Long) As Long
#End If
#If VBA7 Then
Private Function GetFormCaption(hWind As LongPtr) As String
#Else
Private Function GetFormCaption(hWind As Long) As String
#End If
Dim lRet As Long
Dim sBuffer As String
Const conSize_Buffer = 256
' przygotuj buffor na przyjęcie tytułu okna
sBuffer = String(conSize_Buffer, vbNullChar)
' pobierz do bufora tytuł okna i zwróć ilość pobranych znaków
lRet = GetWindowText(hWind, sBuffer, conSize_Buffer)
GetFormCaption = Left$(sBuffer, lRet)
End Function
' przykładowe wywołanie
Private Sub btnTest_Click()
' ustaw nowy tytuł formularza
Me.Caption = "Nowy tytuł formularza"
' odczytaj tytuł formularza
MsgBox GetFormCaption(Me.hwnd)
End Sub
Po uruchomieniu kodu pojawia się okno komunikatu:
Wszystko się zgadza. Odczytany tytuł formularza jest taki sam, jaki został ustawiony za pomocą właściwości:Me.Caption = "Nowy tytuł formularza"
Praktycznie w tym miejscu, w poczuciu dobrze spełnionego obowiązku, powinienem zakończyć ten artykuł. Jednakże przeprowadzę jeszcze jeden malutki test odnośnie typu uchwytu hwnd. Zgodnie z wszystkimi wytycznymi Microsoftu uchwyt w 64-bitowym środowisku powinien być 8-bajtową liczbą typu LongLong, a w 32-bitowym środowisku 4-bajtową liczbą typu Long. Do sprawdzenia typu zmiennej użyję funkcji VarType( varname ), która dla zmiennej typu LongLong zwraca wartość vbLongLong = 20, a dla zmiennej typu Long zwraca wartość vbLong = 3 i tylko te dwa typy będą uwzględnione w procedurze testowej.
Private Sub GetTypeHwnd()
#If VBA7 Then
Dim hWind As LongPtr
#Else
Dim hWind As Long
#End If
Dim sRet As String
'sprawdź typ zmiennej hWind
sRet = sRet & "Zmienna hWind jest typu: " & _
IIf(VarType(hWind) = vbLongLong, "LongLong", "Long")
sRet = sRet & vbNewLine & vbNewLine
' sprawdź typ uchwytu okna
sRet = sRet & "Uchwyt Me.hwnd jest typu: " & _
IIf(VarType(Me.hwnd) = vbLongLong, "LongLong", "Long")
MsgBox sRet
End Sub
Znowu ZONK ! Co widać na poniższym oknie komunikatu:
Zmienna hWind jest typu LongLong, bo tak została zadeklarowana:
Dim hWind As LongPtr
Ale dlaczego właściwość Me.hwnd jest liczbę typu Long w 64-bitowym VBA 7.0 ? Aby odpowiedzieć na to pytanie wystarczy spojrzeć na deklarację tej właściwości w oknie „Object Browser”
Property Hwnd As LongProblem ten dotyczy także metody Application.hWndAccessApp, która ma postać:
Function hWndAccessApp() As Longi w 64-bitowym środowisku VBA 7.0 zwróci uchwyt okna MS Access jako liczbę typu Long zamiast liczby typu LongLong.




Brak komentarzy:
Prześlij komentarz