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: DWORD
To 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