![]() |
Wyjście Spis treści Poprzedni Następny
Autor:
©Iczelion |
©2008 mgr Jerzy Wałaszek I LO w Tarnowie
|
Na tej lekcji nauczymy się stosować grafikę rastrową (bitmap) w naszym programie. Konkretnie nauczymy się wyświetlać grafikę rastrową na obszarze roboczym naszego okna. Załaduj {ten przykład}.

Grafikę rastrową można uważać za obraz zapisany w komputerze. Istnieje wiele różnych formatów graficznych stosowanych z komputerami, lecz system Windows wewnętrznie obsługuje jedynie pliki grafiki rastrowej (Windows Bitmnap Graphics files) posiadające rozszerzenie nazwy .BMP. Najprostszym sposobem użycia grafiki rastrowej jest umieszczenie jej w zasobach. Można to zrobić na dwa sposoby. Możesz dołączyć grafikę rastrową do pliku definicji zasobów (.RC) w sposób następujący:
#define IDB_MYBITMAP 100 IDB_MYBITMAP BITMAP "c:\project\example.bmp"
Metoda ta wykorzystuje stałą do reprezentowania grafiki rastrowej. Pierwszy wiersz po prostu tworzy stałą o nazwie IDB_MYBITMAP, Która ma wartość 100. Będziemy używać tej etykiety do odwoływania się do grafiki rastrowej w programie. Następny wiersz deklaruje zasób grafiki rastrowej. Informuje on kompilator zasobów, gdzie należy znaleźć właściwy plik .BMP.
W drugiej metodzie wykorzystujemy nazwę do reprezentowania grafiki rastrowej w sposób następujący:
MyBitMap BITMAP "c:\project\example.bmp"
Metoda ta wymaga odwołania się do grafiki rastrowej przy pomocy łańcucha znaków "MyBitMap" zamiast wartości.
Każda z tych metod jest dobra, chyba że się pogubisz.
Teraz gdy już wstawiliśmy grafikę rastrową do pliku z zasobami. możemy przejść dalej do kroków niezbędnych przy umieszczaniu jej na obszarze roboczym okna.
LoadBitmap PROTO hInstance:HINSTANCE, lpBitmapName:LPSTR
Funkcja zwraca uchwyt grafiki rastrowej. hInstance jest uchwytem egzemplarza naszego programu. lpBitmapName to wskazanie do łańcucha znaków określającego nazwę grafiki (w przypadku zastosowania drugiej metody odwoływania się do grafiki rastrowej). Jeśli do określania grafiki stosujesz stałą (np. IDB_MYBITMAP), możesz wstawić tutaj jej wartość (w przykładzie powyżej byłoby to 100). A oto krótkie przykłady kolejnych dwóch metod:
Metoda Pierwsza:
.386
.MODEL FLAT, STDCALL
...
.CONST
IDB_MYBITMAP EQU 100
...
.DATA?
hInstance DD ?
...
.CODE
...
INVOKE GetModuleHandle, NULL mov hInstance, eax INVOKE LoadBitmap, hInstance, IDB_MYBITMAP
Metoda Druga
.386
.MODEL FLAT, STDCALL
...
.DATA
BitmapName DB "MyBitMap", 0
...
.DATA?
hInstance DD ?
...
.CODE
...
INVOKE GetModuleHandle, NULL
mov hInstance, eax
...
INVOKE LoadBitmap, hInstance, ADDR BitmapName
...CreateCompatibleDC PROTO hdc:HDC
Jeśli funkcja się powiedzie, to zwróci w rejestrze eax uchwyt do kontekstu urządzenia w pamięci. Parametr hdc jest uchwytem kontekstu urządzenia, dla którego chcemy utworzyć kompatybilny kontekst DC w pamięci.
SelectObject PROTO hdc:HDC, hGdiObject:DWORD
BitBlt PROTO hdcDest: DWORD,\
nxDest: DWORD,\
nyDest: DWORD,\
nWidth: DWORD,\
nHeight: DWORD,\
hdcSrc: DWORD,\
nxSrc: DWORD,\
nySrc: DWORD,\
dwROP: DWORDTo wszystko. Podsumujmy: musisz umieścić grafikę rastrową w skrypcie zasobów. Następnie ładujesz ją z zasobów przy pomocy funkcji LoadBitmap. Dostaniesz uchwyt grafiki. Dalej pobierasz uchwyt kontekstu urządzenia obszaru, na którym chcesz umieścić tę grafikę rastrową. Tworzysz kontekst urządzenia w pamięci, który jest kompatybilny z kontekstem urządzenia właśnie otrzymanym. Umieszczasz grafikę w DC w pamięci, a później kopiujesz zawartość DC w pamięci do rzeczywistego DC.
Plik SIMPLEBITMAP.ASM
.386
.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE
INCLUDE \masm32\include\windows.inc
INCLUDE \masm32\include\user32.inc
INCLUDE \masm32\include\kernel32.inc
INCLUDE \masm32\include\gdi32.inc
INCLUDELIB \masm32\lib\user32.lib
INCLUDELIB \masm32\lib\kernel32.lib
INCLUDELIB \masm32\lib\gdi32.lib
WinMain PROTO :DWORD, :DWORD, :DWORD, :DWORD
.CONST
IDB_MAIN EQU 1
.DATA
ClassName DB "SimpleWin32ASMBitmapClass", 0
AppName DB "Grafika rastrowa w Win32ASM", 0
.DATA?
hInstance HINSTANCE ?
CommandLine LPSTR ?
hBitmap DD ?
.CODE
start:
INVOKE GetModuleHandle, NULL
mov hInstance, eax
INVOKE GetCommandLine
mov CommandLine, eax
INVOKE WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT
INVOKE ExitProcess, eax
WinMain PROC hInst: HINSTANCE,\
hPrevInst: HINSTANCE,\
CmdLine: LPSTR,\
CmdShow: DWORD
LOCAL wc : WNDCLASSEX
LOCAL msg : MSG
LOCAL hwnd : HWND
mov wc.cbSize, SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW OR CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground, COLOR_WINDOW + 1
mov wc.lpszMenuName, NULL
mov wc.lpszClassName, OFFSET ClassName
INVOKE LoadIcon, NULL, IDI_APPLICATION
mov wc.hIcon, eax
mov wc.hIconSm, eax
INVOKE LoadCursor, NULL, IDC_ARROW
mov wc.hCursor, eax
INVOKE RegisterClassEx, ADDR wc
INVOKE CreateWindowEx, NULL, ADDR ClassName, ADDR AppName,\
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,\
CW_USEDEFAULT, 295, 310, NULL, NULL,\
hInst, NULL
mov hwnd, eax
INVOKE ShowWindow, hwnd, SW_SHOWNORMAL
INVOKE UpdateWindow, hwnd
.WHILE TRUE
INVOKE GetMessage, ADDR msg, NULL, 0, 0
.BREAK .IF (!eax)
INVOKE TranslateMessage, ADDR msg
INVOKE DispatchMessage, ADDR msg
.ENDW
mov eax, msg.wParam
ret
WinMain ENDP
WndProc PROC hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL ps: PAINTSTRUCT
LOCAL hdc: HDC
LOCAL hMemDC: HDC
LOCAL rect: RECT
.IF uMsg==WM_CREATE
INVOKE LoadBitmap, hInstance, IDB_MAIN
mov hBitmap, eax
.ELSEIF uMsg==WM_PAINT
INVOKE BeginPaint, hWnd, ADDR ps
mov hdc, eax
INVOKE CreateCompatibleDC, hdc
mov hMemDC, eax
INVOKE SelectObject, hMemDC, hBitmap
INVOKE GetClientRect, hWnd, ADDR rect
INVOKE BitBlt, hdc, 0, 0, rect.right, rect.bottom, hMemDC, 0, 0, SRCCOPY
INVOKE DeleteDC, hMemDC
INVOKE EndPaint, hWnd, ADDR ps
.ELSEIF uMsg==WM_DESTROY
INVOKE DeleteObject, hBitmap
INVOKE PostQuitMessage, NULL
.ELSE
INVOKE DefWindowProc, hWnd, uMsg, wParam, lParam
ret
.ENDIF
xor eax, eax
ret
WndProc ENDP
END start
Plik zasobów SIMPLEBITMAP.RC
#define IDB_MAIN 1 IDB_MAIN BITMAP "TWEETY78.bmp"
Na tej lekcji nie pozostaje nam zbyt wiele do analizowania ;)
#define IDB_MAIN 1 IDB_MAIN BITMAP "TWEETY78.bmp"
Zdefiniuj stałą o nazwie IDB_MAIN, przypisz jej jako wartość liczbę 1. A następnie wykorzystaj tę stałą w charakterze identyfikatora zasobu grafiki rastrowej. Plik z grafiką rastrową, który należy dołączyć do zasobów, posiada nazwę "TWEETY78.bmp" i znajduje się w tym samym katalogu, co skrypt zasobów.
.IF uMsg==WM_CREATE
INVOKE LoadBitmap, hInstance, IDB_MAIN
mov hBitmap, eax
W odpowiedzi na wiadomość WM_CREATE, wywołujemy LoadBitmap do załadowania grafiki rastrowej z zasobów przekazując w drugim parametrze jej identyfikator. Dostajemy przy powrocie funkcji uchwyt do grafiki.
Po załadowaniu grafiki rastrowej możemy ją namalować w obszarze roboczym naszego okna głównego.
.ELSEIF uMsg==WM_PAINT
INVOKE BeginPaint, hWnd, ADDR ps
mov hdc, eax
INVOKE CreateCompatibleDC, hdc
mov hMemDC, eax
INVOKE SelectObject, hMemDC, hBitmap
INVOKE GetClientRect, hWnd, ADDR rect
INVOKE BitBlt, hdc, 0, 0, rect.right, rect.bottom, hMemDC, 0, 0, SRCCOPY
INVOKE DeleteDC, hMemDC
INVOKE EndPaint, hWnd, ADDR ps
Malowanie grafiki przeprowadzamy w odpowiedzi na wiadomość WM_PAINT. Najpierw wywołujemy BeginPaint aby otrzymać uchwyt do kontekstu urządzenia. Następnie tworzymy kompatybilny kontekst urządzenia w pamięci za pomocą CreateCompatibleDC. Dalej wprowadzamy grafikę do DC w pamięci przy pomocy SelectObject. Określamy wymiary obszaru roboczego za pomocą GetClientRect. Teraz jesteśmy gotowi do wyświetlenia grafiki w obszarze roboczym wywołując funkcję BitBlt, która skopiuje grafikę z pamięci do właściwego kontekstu urządzenia. Po zakończeniu malowania nie potrzebujemy DC w pamięci, zatem usuwamy go przy pomocy DeleteDC. Kończymy sesję malowania wywołaniem EndPaint.
.ELSEIF uMsg==WM_DESTROY
INVOKE DeleteObject, hBitmap
INVOKE PostQuitMessage, NULL
Gdy grafika rastrowa przestanie nam być już potrzebna, usuwamy ją wywołując DeleteObject
|
Autorem
kursu jest
Iczelion. Kurs
programowania Windows znalazł się na serwerze I LO w Tarnowie za pisemną
zgodą autora. |
![]() | I Liceum Ogólnokształcące |
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe