|
1.1 Podstawowe informacje o funkcjach API ?
API - Application Programming Interface jest to zbiór funkcji i procedur znajdujących się w plikach dll (Dynamic Link Library), inaczej mówiąc są to biblioteki dołączane dynamicznie. Spis funkcji API
Podstawowe biblioteki to:
• USER32.dll - funkcje zarządzania środowiskiem Windows
• KERNEL32.dll - funkcje zarządzania funkcjami systemu operacyjnego
• GDI32.dll - Graphics Device Interface - funkcje zarządzające wyprawadzaniem danych na zewnętrzne urządzenia,
Inne biblioteki to:
winspool.drv, shell32.dll, comdlg32.dll, version.dll, comctl32.dll, netapi32.dll, winmm.dll, lz32.dll, advapi32.dll, mpr.dll, imm32.dll

Jak zadeklarować funkcję API, wywołać ją i pobrać zwracaną wartość

• funkcje API mogą być procedurami, które nie zwracają żadnej wartości, np.
Private Declare Sub Sleep Lib "kernel32" _
(ByVal dwMilliseconds As Long)
' wstrzymuje działanie systemu na czas 500 milisekund
Call Sleep(500&)

• mogą zwracać wartość, ale nie wymagają argumentu:
Private Declare Function GetFocus Lib "user32" () As Long
Dim lRet As Long
' zwraca uchwyt okna mającego fokus
lRet = GetFocus

• lub poinformować nas tylko o prawidłowym działaniu, zwracając przy błędzie ZERO, a przy powodzeniu wartość <> ZERA
Private Declare Function SetWindowText Lib "user32" _
Alias "SetWindowTextA" _
(ByVal hwnd As Long, _
ByVal lpString As String) As Long
Dim lRet As Long
' ustawia tytuł formularza
lRet = SetWindowText(Me.hWnd, ByVal "Mój tytuł")

• procedura API, można zwrócić (ustawić) wartości poprzez argument ByRef nie zwracając żadnej wartości,
Private Declare Sub GetSystemTime Lib "kernel32" _
Alias "GetSystemTime" _
(lpSystemTime As SYSTEMTIME)
Private Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
Dim stm As SYSTEMTIME
' zwraca dane w strukturze SYSTEMTIME
Call GetSystemTime(stm)
With stm
Debug.Print .wDay; .wMonth; .wYear;
Debug.Print .wHour; .wMinute; .wSecond; .wMilliseconds
End With

• funkcja API może zwrócić wartości poprzez argument ByRef, zwracając przy błędzie Zero, a przy powodzeniu wartość <>0,
Private Declare Function GetWindowRect Lib "user32" _
(ByVal hwnd As Long, _
lpRect As RECT) As Long
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Dim rct As RECT
Dim lRet As Long
lRet = GetWindowRect(Me.hwnd, rct)
With rct
' zwraca współrzędne okna
Debug.Print .Left, .Top, .Right, .Top
End With

• czasami, aby uzyskać żądaną wartość musimy wywołać dwie lub więcej funkcji API i wykonać dodatkowe czynności przygotowawcze np. przygotować odpowiedniej długości ciąg znków na przyjęcie zwracanej wartości,
Private Declare Function GetWindowTextLength Lib "user32" _
Alias "GetWindowTextLengthA" _
(ByVal hwnd 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
Dim lLenText As Long
Dim sBuffer As String
' 1. pobierz długość tekstu okna
lLenText = GetWindowTextLength(Me.hwnd)
' 2. przygotuj bufor na przyjęcie tekstu, dodajemy jeden znak więcej ponieważ zwracany ciąg musi być zakończony znakiem końca tekstu (vbNullChar), jeżeli tego nie zrobimy to i tak VBA zrobi to za nas,
sBuffer = String(lLenText + 1, vbNullChar)
' 3. pobieramy do bufora tekst okna, a funkcja zwraca nam ilość skopiowanych znaków
lLenText = GetWindowText(Me.hwnd, ByVal sBuffer, Len(sBuffer))
' 4. pobieramy z bufora tytuł okna
sBuffer = Left$(sBuffer, lLenText)
Debug.Print sBuffer

• w szczególnych przypadkach musimy bezwzględnie wywołać wzajemnie skojarzone funkcje API, ponieważ możemy narazić się na poważne kłopoty w trakcie dalszego działania naszej aplikacji,
Private Declare Function OpenClipboard Lib "user32" _
(ByVal hwnd As Long) As Long
Private Declare Function CloseClipboard Lib "user32" () As Long
lRet = OpenClipboard(0&)
' ... jakieś operacje na schowku
lRet = CloseClipboard

Private Declare Function GetDesktopWindow _
Lib "user32" () As Long
Private Declare Function GetDC Lib "user32" _
(ByVal hwnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32" _
(ByVal hwnd As Long, _
ByVal hDC As Long) As Long
Dim hDsk As Long
Dim hDC As Long
hDsk = GetDesktopWindow()
hDC = GetDC(hDsk)
' ... jakieś operacje
lRet = ReleaseDC(hDsk, hDC)

Private Declare Function CreateSolidBrush Lib "gdi32" _
(ByVal crColor As Long) As Long
Private Declare Function SelectObject Lib "gdi32" _
(ByVal hDC As Long, _
ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" _
(ByVal hObject As Long) As Long
Dim hBrush As Long
Dim hOldBrush As Long
' utwórz nowy pędzel w kontekście hDC,
hBrush = CreateSolidBrush(vbRed)
' wybierz nowy pędzel, by coś pomalować
hOldBrush = SelectObject(hDC, hBrush)
...
' ... wykonaj jakieś operacje pędzlem
...
' wybierz stary pędzel, by usunąć utworzony pędzel
SelectObject hDC, hOldBrush
' usuń utworzony pędzel
lRet = DeleteObject(hBrush)

• wiele funkcji API posiada dużą liczbę argumentów, ale czasami nie musimy ustawiać ich wartości, ponieważ argumenty te mogą być ignorowane przez funkcję w zależności od ustawionej tzw. Flagi
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
Const SWP_NOSIZE = &H1 | ' ignorowane są argumenty: cx i cy |
Const SWP_NOMOVE = &H2 | ' ignorowane są argumenty: x i y |
Const SWP_NOOWNERZORDER = &H200 | ' nie jest zmieniana pozycja Z-Order |
Const SWP_FRAMECHANGED = &H20 | ' zostanie wysłany komunikat WM_NCCALCSIZE ' i okno zostanie odświeżone |
Const SWP_NOZORDER = &H4 | ' ignorowany jest hWndInsertAfter |
Const SWP_SHOWWINDOW = &H40 | ' pokazuje okno |
Const SWP_HIDEWINDOW = &H80 | ' ukrywa okno |
Const MY_FLAGS As Long = _
SWP_SHOWWINDOW Or _
SWP_FRAMECHANGED Or _
SWP_NOSIZE Or -
SWP_NOOWNERZORDER Or _
SWP_NOZORDER
Dim lRet As Long
' m.in Flaga SWP_NOSIZE - nie pozwala na zmianę rozmiaru formularza, pomimo wstawionych wartości argumentów cx, cy
lRet = SetWindowPos(Me.hwnd, 0&, 100&, 100&, _
300&, 300&, MY_FLAGS)

• argumentami procedury (funkcji) API mogą być różne typy danych np.
Private Declare Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" _
(Destination As Any, _
Source As Any, _
ByVal Length As Long)
Dim sString As String
Dim aRGB(0 To 3) As Byte
Dim lColor As Long
Dim lRet As Long
Dim i As Long
sString = "Mój tekst"
' musimy przygotować tablicę na przyjęcie określonej ilości bajtów
ReDim aBytes(0 To Len(sString) - 1) As Byte
' 1. ciąg znaków zostanie skopiowany do tablicy bajtów
Call CopyMemory(aBytes(0), ByVal sString, Len(sString))
Debug.Print "1. ";
For i = LBound(aBytes) To UBound(aBytes)
Debug.Print Chr$(aBytes(i)); "|";
Next
Debug.Print
' 2. tablica bajtów zostanie skopiowana do ciągu znaków
sString = String(UBound(aBytes) - LBound(aBytes) + 1, vbNullChar)
Call CopyMemory(ByVal sString, aBytes(0), Len(sString))
Debug.Print "2. "; sString
lColor = RGB(150, 200, 250)
' 3. liczba Long zostanie skopiowana do tablicy bajtów
Call CopyMemory(aRGB(0), lColor, 4)
Debug.Print "3. R="; aRGB(0); "; G="; aRGB(1); "; B="; aRGB(2); "; T="; aRGB(3)
' 4. z tablicy 4-ech bajtów utworzona zostanie liczba Long
Call CopyMemory(lRet, aRGB(0), 4)
Debug.Print "4. lRet ="; lRet; "; lColor ="; lColor
DoCmd.RunCommand acCmdDebugWindow
ΔΔΔ | |