Access

  MS Access 2010+  |  Bitmapa *.bmp  |   VBA 7.0

• Graphics Device Interface (GDI).

GDI - kontekst urządzenia Jeden z trzech podstawowych komponentów (razem z jądrem i API Windows) interfejsu użytkownika (menedżera okien GDI) w Microsoft Windows. GDI odpowiedzialne jest za przedstawianie obiektów graficznych i przesyłanie ich do urządzeń wyjściowych, takich jak monitory i drukarki. Każdy program, który realizuje w sposób graficzny swoje obiekty na ekranie lub drukarce musi korzystać z funkcji GDI. Większość funkcji przechowywanych jest w pliku GDI.exe w folderze systemowym Windows.

 

Co umożliwiają funkcje GDI?

  • zarządzanie kontekstem urządzenia (jego tworzeniem, zwalnianiem, odczytem i ustawianiem atrybutów)
  • rysowanie (wyświetlanie tekstów, linii, prostokątów, bitmap itp.),
  • określanie cech obiektów rysujących,

Zasadniczo interfejs GDI możemy podzielić na cztery części:

  • Funkcje do rysowania linii i figur geometrycznych oraz wypełnianiem tych figur,
  • funkcje obsługujące bitmapy,
  • funkcje wyboru, tworzenie i wyświetlania czcionek oraz drukowania tekstu,
  • funkcje zarządzające regionami (obszarami) wyświetlanej grafiki oraz ich przycinaniem,

Operacje graficzne na kontekście urządzenia.

Operacje graficzne w systemie Windows wykonywane są na tak zwanym kontekście urządzenia. Dzięki wprowadzeniu kontekstu urządzenia możliwe stało się ujednolicenie funkcji graficznych zawartych w API. Każda z funkcji operuje na konkretnym kontekście urządzenia, który w rzeczywistości może oznaczać ekran monitora, drukarkę, czy też mapę bitową utworzoną w pamięci. Zrozumiałe jest, że nie każda operacja graficzna jest możliwa do wykonania na każdym kontekście urządzenia.

Każdy kontekst urządzenia pomiędzy kolejnymi operacjami graficznymi pamięta wszystkie atrybuty, jakie poprzednio stosowaliśmy. Dzięki temu nie musimy za każdym razem tworzyć lub wybierać pióra do rysowania linii, pędzla do malowania obszarów, czy czcionki do pisania tekstu. W każdej chwili możemy w danym kontekście urządzenia użyć inne, nowe pióro, inny pędzel, czy czcionkę równocześnie zmieniając kolor narzędzia, tła, wielkość i inne atrybuty.

Ponieważ w systemie Windows nie istnieje standardowe urządzenie graficzne, na którym moglibyśmy wykonywać operacje graficzne, za każdym razem, gdy chcemy coś narysować, musimy pobrać z systemu Windows kontekst urządzenia. Pobranie kontekstu urządzenia, to nic innego jak uzyskanie z systemu Windows identyfikatora kontekstu urządzenia. Takim identyfikatorem jest uchwyt kontekstu urządzenia hdc.

Identyfikowany poprzez swój uchwyt kontekst urządzenia jest strukturą zarządzaną przez system Windows i zawierającą nie tylko obiekt przeznaczony do wykonywanych operacji graficznych, ale przechowującą również wiele informacji o obiektach rysujących i parametrach określających tryby stosowane przez funkcje GDI podczas rysowania w kontekście urządzenia.
Poniższy przykład przedstawia sposób, w jaki można pobrać kilka najważniejszych atrybutów (właściwości) kontekstu urządzenia ekranu (Pulpitu).

Option Compare Database
Option Explicit

#If VBA7 Then
  Private Declare PtrSafe Function GetDeviceCaps Lib "gdi32" ( _
          ByVal hdc As LongPtr, _
          ByVal nIndex As Long) As Long
  Private Declare PtrSafe Function GetDC Lib "user32" ( _
          ByVal hwnd As LongPtr) As LongPtr
  Private Declare PtrSafe Function ReleaseDC Lib "user32" ( _
          ByVal hwnd As LongPtr, _
          ByVal hdc As LongPtr) As Long
#Else
  Private Declare Function GetDeviceCaps Lib "gdi32" ( _
          ByVal hdc As Long, _
          ByVal nIndex As Long) 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
#End If

Const HORZSIZE = 4           ' szerokość kontekstu w mm
Const VERTSIZE = 6           ' wysokość kontekstu w mm
Const HORZRES = 8            ' szerokość kontekstu w pikselach
Const VERTRES = 10           ' wysokość kontekstu w pikselach
Const BITSPIXEL = 12         ' liczba bitów na piksel (głębia koloru
Const LOGPIXELSX = 88        ' ilość punktów na cal w poziomie
Const LOGPIXELSY = 90        ' ilość punktów na cal w pionie
Const HWND_DESKTOP = 0       ' uchwyt pulpitu

Private Sub AtrybutyDC()
#If VBA7 Then
  Dim hdc As LongPtr
#Else
  Dim hdc As Long
#End If
Dim lRet  As Long
Dim sRet  As String

	'pobierz uchwyt kontekstu urządzenia ekranu
	hdc = GetDC(HWND_DESKTOP)
	' pobierz najważniejsze atrybuty kontekstu urządzenia ekranu
	sRet = sRet & "Pulpit: " & GetDeviceCaps(hdc, HORZRES) & " x " & _
						 GetDeviceCaps(hdc, VERTRES) & " pikseli "
	sRet = sRet & GetDeviceCaps(hdc, HORZSIZE) & " x " & _
						 GetDeviceCaps(hdc, VERTSIZE) & " mm)" & vbNewLine
	sRet = sRet & "Rozdzielczość poziomo (DPI): " & _
						 GetDeviceCaps(hdc, LOGPIXELSX) & " pikseli na cal" & vbNewLine
	sRet = sRet & "Rozdzielczość pionowo (DPI): " & _
						 GetDeviceCaps(hdc, LOGPIXELSY) & " pikseli na cal" & vbNewLine
	sRet = sRet & "Głębia kolorów: " & GetDeviceCaps(hdc, BITSPIXEL) & " bit"

	'zwolnij kontekst urządzenia obszaru roboczego ekranu („Pulpitu”)
	lRet = ReleaseDC(HWND_DESKTOP, hdc)
	MsgBox sRet

End Sub
Atrybuty kontekstu urządzenia

Niektóre atrybuty kontekstu urządzenia ekranu (Pulpitu)

Proste malowanie po ekranie

W podobny sposób możemy wykonać najprostszą i zarazem najwolniejszą operacje graficzną jaką jest malowanie piksel po pikselu w obszarze roboczym ekranu (Pulpitu).

Option Compare Database
Option Explicit

#If VBA7 Then

  Private Declare PtrSafe Function GetDC Lib "user32" ( _
          ByVal hwnd As LongPtr) As LongPtr
  Private Declare PtrSafe Function ReleaseDC Lib "user32" ( _
          ByVal hwnd As LongPtr, _
          ByVal hdc As LongPtr) As Long
  Private Declare PtrSafe Function SetPixel Lib "gdi32" ( _
          ByVal hdc As LongPtr, _
          ByVal x As Long, _
          ByVal y As Long, _
          ByVal crColor As Long) As Long
#Else

  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
  Private Declare Function SetPixel Lib "gdi32" ( _
          ByVal hdc As Long, _
          ByVal x As Long, _
          ByVal y As Long, _
          ByVal crColor As Long) As Long
#End If
Const HWND_DESKTOP = 0       ' uchwyt pulpitu

Private Sub bmpMalowaniePoEkranie()
#If VBA7 Then
  Dim hdc As LongPtr
#Else
  Dim hdc As Long
#End If
Dim x     As Long
Dim y     As Long
Dim lRet  As Long

	'pobierz kontekst urządzenia obszaru roboczego ekranu („Pulpitu”)
	hdc = GetDC(HWND_DESKTOP)
	'namaluj w górnym lewym rogu ekranu zielony kwadrat o wym. 100 x 100 pikseli
	For x = 0 To 100
		For y = 0 To 100
			 Call SetPixel(hdc, x, y, vbGreen)
		Next
	Next

	'zwolnij kontekst urządzenia obszaru roboczego ekranu („Pulpitu”)
	lRet = ReleaseDC(HWND_DESKTOP, hdc)

End Sub

W wyniku działania funkcji bmpMalowaniePoEkranie(...) otrzymujemy zielony kwadrat w lewym górnym rogu ekranu. Niestety, jeżeli nad tym zielonym kwadratem przesuniemy inne okno, przesłaniany obszar już nie będzie zielony. System Windows sam przemaluje (odświeży) odsłoniętego obszaru oryginalnym obrazem. Nie o takie malowanie zapewne chodziło, ale opisane funkcje służące do pobierania i zwalniania kontekstu urządzenia na pewno przydadzą się później do malowania po bitmapach w pamięciowym kontekście urządzenia.