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
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.