Chapter 25: Preliminary bitmap
In this lesson, we will learn how to use a bitmap in the program. More accurately, what we want to learn how to display bitmaps in a window's client area.
Theoretical bitmap is a picture stored in a computer. Bitmap files have considerable formats (translator: such as .bmp.jpg.gif.pic, Windows only supports Windows Bitmap Graphics format, namely BMP files. The bitmap referred to in this lesson is also a BMP file. The easiest way to use bitmap is to define it in the resource file (.rc). There are two ways to define. The first method is to define it as an integer macro, as follows:
#define idb_mybitmap 100
IDB_MYBITMAP
Bitmap "c: /project/example.bmp"
The first line we defined an integer macro worth 100. The second line we put this integer macro to the bitmap you want to define, so that the compiler can know the path where the bitmap is located.
Another way is to give it a name, that is, defined it as a string, as follows:
Mybitmap
Bitmap "c: /project/example.bmp"
The effect is the same. Which method is selected, depending on how you like an integer macro in the program, you can point to the bitmap.
Now we have defined bitmaps in the resource file, the next step is to display it on the window of the window.
In the program, we use the API function loadbitmap to get the bitmap sector. The following is the completion of the LoadBitmap function:
Loadbitmap Proto Hinstance: Hinstance, LPbitmapname: LPSTR
This function returns a bitmap sector. The function has two parameters, where Hinstance is a program handle. lpbitmapname is a pointer for bitmap names (for the second definition method). If you use the first definition method, you can fill in the value or integer macro pointing the bitmap (the value of the above case is 100, the integer macro is IDB_MYBITMAP). The following is a simple example:
the first method:
.386 .Model flat, stdcall ................ .const IDB_mybitmap EQU 100 .............. .data? Hinstance dd?. ............ .code ................. Invoke getModuleHandle, Null Mov Hinstance, Eax ......... Invoke loadingBitmap , hinstance, idb_mybitmap ...........
The second method:
.386 .Model flat, stdcall .............. .data Bitmapname DB "mybitmap", 0 .............. .data? Hinstance dd? .............. .code .......................................... .. invoke loadingbitmap, hinstance, addr bitmapname ...........
A device text (DC) handle is obtained. You can get through the API function based on the WM_PAINT message. If you can use the API function GetDC in other messages. Create this DC memory image. The purpose of this is to establish a "hidden drawing paper", draw the bitmap "painting" on it, and use the buffer. After this work is completed, we copied the bitmaps on the "drawing paper" into the real DC through a function. This is a double buffer technology that quickly displays the image on the screen. (Translator: You can reduce image jitter) This "drawing paper" is built with API function createCompatibleDC. Here is its integration: CreateCompatibleDC Proto HDC: HDC
If the function is successful, the DC memory image is also returned to the handle of "drawing".
Now we already have "drawing paper", you can draw your bitmap above. This can be done through the API function SelectObject, where the first parameter is the handle of "drawing paper", the second parameter is the handle of the bitmap, the following is the function of the function:
SelectObject Proto HDC: HDC, HGDiobject: DWORD
Now the bitmap has been drawn on "drawing paper". Next we have to copy bitmaps to the real DC. There are many API functions to complete this work, such as Bitblt and Stretchblt. Function BitBLT simply copies the content of a DC to another DC, and the function StretchBLT can automatically adjust the size of the source DC replication content that has been adapted to the output area of the destination DC, so the former is faster than the latter. Here we only use the function bitblt, below is its completion:
Bitblt Proto HDCDEST: DWORD, NXDEST: DWORD, NYDEST: DWORD, NWIDTH: DWORD, NHEIGHT: DWORD, HDCSRC: DWORD, NXSRC: DWORD, NYSRC: DWORD, DWROP: DWORD
HDCDEST destination DC handle.
NXDEST, NYDEST destination DC output area of the upper left corner coordinate.
NWIDTH, NHEIGHT destination DC output area length and width.
HDCSRC source DC handle.
NXSRC, the upper left corner coordinate of the NYSRC source DC.
DWROP screen operation code (ROP). This parameter is used to determine which operation of the color of the copy content is handled by the original color of the output area. Typically, it is only necessary to simply use replication content to overwrite the output area.
After all, use the API function deleteObject to release bitmap objects, which is to "wipe out". Datual, now come back to review the whole process: First, you need to define the bitmap in the resource file. Then you need to load the bitmap resources in the program and get the bitmap sector. Subsequently, you need to get the DC of the bitmap output area, and create the memory image of this DC and put the bitmap in this DC memory image. Finally, the bitmap is copied from the DC memory image to the true DC.
Example: .386
.Model flat, stdcall
Option CaseMAP: NONE
INCLUDE /MASM32/INCLUDE/Windows.inc
INCLUDE /MASM32/INCLUDE/USER32.INC
INCLUDE /MASM32/INCLUDE / WANEL32.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 IDB_MAIN EQU 1.Data ClassName DB "SimpleWin32asmbitmapclass", 0 Appname DB "Win32ASM Simple Bitmap Example", 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, CW_USEDEFAULT, CW_USEDEFAULT, 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 invok E 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; --------------------------------------- ------------------------------; Resource definition; -------------------------------------------------------------- -------------------------------------------------- - #Define idb_main 1 idb_main bitmap "Tw Eety78.bmp "
analysis:
#define idb_main 1
IDB_MAIN bitmap "Tweety78.BMP"
Define the value of an integer macro IDB_MAIN, and point it to a bitmap name "Tweety.bmp" with the resource file in the same directory file.
.IF uMsg == wm_create invoke loadingbitmap, hinstance, idb_main mov hbitmap, EAX
When processing the WM_CREATE message, we load bitmap resources through the API function loadbitmap and get the bitmap sector through the function return value. Then we can draw bit graphs on the window client area.
.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, Srcopy Invoke deletedc, HMEMDC Invoke Endpaint, HWnd, Addr PS
In this example, we choose to draw a bitmap when responding to WM_PAINT messages. First we get the DC handle of the window client via the API function L BeGinPaint. Then we create the DC memory image via the API function createCompatibleDC and put the bitmap into the memory image via the API function SelectObject. Next, we obtain the size of the window client via the API function getClientRect. Finally, we copy the bitmap from the DC memory image to the true client area DC through the API function bitblt. After completing the display, we release the DC memory image through the API function deletedc, and release the client area DC with the API function Endpaint, end the drawing work. .ELSEIF uMSG == WM_DESTROY
Invoke deleteObject, hbitmap
Invoke PostquitMessage, NULL
When we no longer need a bitmap, let it release it through the API function deleteObject.