Win32 assembly: 26. Startup screen

zhaozj2021-02-17  49

Chapter 26: Starting the screen

Previous chapter we have learned the use of bitmaps. In this chapter we have to use God to give our creativity to integrate the knowledge we have learned. That is to study how to use the bitmap to create a startup screen. You can Download the demonstration here:

The example.

Theory first, let's first understand what is startup. For a simple example: When some of the programs of some professionals (such as Netscape, Adobe Acrobat, etc.) will first jump out of the screen. There are usually some copyrights. Information, version number, etc. At the same time, the program background is doing some programs loading or initialization. This startup screen is different from the general window. It does not have a title bar, no system menu, no border. There is only one bit. The figure shows a while on the screen, then disappears. In this chapter, let's try yourself.

The first step You may think that the bitmap you want to display is to go in the resource file. But doing this is a shortcoming. Your program only shows this bitmap when starting, but it is still in the end. Your memory until you turn it off. This can't be said to be a great waste of memory. Good way is: Create a "resource" DLL (Dynamic Library) to include bitmaps and its unique display code. In this way, you can load him when you want to display the startup screen. If you run it out, you will uninstall it. So, our program requires 2 modules: main program and start screen DLL. We must put the bitmap in this DLL resource go with.

The basic steps are as follows:

Put the bitmap as a bitmap resource to the DLL. The main program call LoadLibrary puts the DLL to the memory. After the DLL is called, it will establish a timer to manage the time displayed by the start screen. Then, register and create A window without a title and border. At the same time, the bitmap is displayed at the window of the window. The display time length of the startup screen reaches your pre-set value, the startup screen disappears, the control is returned to the main program. Main program call FreeElibrary Uninstall the DLL in memory. Then, do what it should do. Let's study the details section.

Load / Uninstall DLL You can use LoadLibrary to flexibly load a DLL, its format is as follows:

LoadLibrary Proto LPDLLNAME: DWORD

It has only one parameter: you want the name of the DLL of the DLL. The call successfully returns the handle of the DLL module, and then returns NULL.

To uninstall the DLL, call FreeElibrary:

Freeelibrary Proto Hlib: DWORD

It also has only one parameter: you want to uninstall the handle of the DLL module (usually the above function returned).

How to use the timer first, you have to create a timer with setTimer:

Settimer Proto Hwnd: DWORD, TIMERID: DWORD, UELAPSE: DWORD, LPTIMERFUNC: DWORD

HWND accepts the handle of the window of this timer message. If your timer does not need a window to accept its message, you can use null as the ID value of the parameter Timerid timer. Beyond you know. UELAPSE timer time . With MS (in a second). LPTIMERFUNC processes the address of the function of the timer message. If you use null as this parameter, then the timer's message will be given to the window specified by the HWND parameter.

SetTimer If successfully returns the ID of the timer, returns null. So it is best not to set the ID of the timer to 0 (PHEADNIUS: NULL stands 0, remember?).

You can create timers with two ways:

If you have a window and the timer passes the message to this window. Then you need to transfer all 4 parameters to the SetTimer function (the lptimerfunc parameter must be null). If you don't have a window or you don't want the window to handle the timer Message, then you must transfer a null in the window handle. At the same time, you want to specify the address of the function used to process the timer message. In this example we want to use the first method.

When you set the time, the window connected to the timer will receive a WM_TIMER message. For example, you specify the value of the uLapse 1000, your window receives the WM_TIMER message every one second.

Wait until you don't need this timer, use KillTimer to remove the timer.

Killtimer Proto Hwnd: DWORD, TIMERID: DWORD

example:;----------------------------------------------- ------------------------;

; ------------------------------------------------- ----------------------

.386

.Model flat, stdcall

Option CaseMAP: NONE

INCLUDE /MASM32/INCLUDE/Windows.inc

INCLUDE /MASM32/INCLUDE/USER32.INC

INCLUDE /MASM32/INCLUDE / WANEL32.INC

INCLUDELIB /MASM32/LIB/USER32.LIB

INCLUDELIB /MASM32/LIB/kernel32.lib

Winmain Proto: DWORD,: DWORD,: DWORD,: DWORD

.DATA CLASSNAME DB "SplashDemowInClass", 0 Appname DB "Splash Screen Example", 0 libName DB "Splash.dll", 0

? .Data hInstance HINSTANCE CommandLine LPSTR .code start:?? Invoke LoadLibrary, addr Libname .if eax = NULL invoke FreeLibrary, eax .endif 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 endpWndProc proc hWnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM .IF uMsg == WM_DESTROY invoke PostQuitMessage, NULL .ELSE invoke DefWindowProc, hWnd, uMsg , WPARAM, LPARAM RET .Endif Xor Eax, EAX RET WNDPROC ENDS End Start

; ------------------------------------------------- -------------------; Bit map DLL; ------------------------------------------------------------------------------------------------------------------------------------------------ ----------------------------------------- .386 .Model flat, stdcall 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 .data bitmapname DB "mysplashbmp", 0 ClassName DB "splashWndclass", 0 HBitmap DD 0 Timerid DD 0.Data Hinstance DD?

.code

DllEntry proc hInst: DWORD, reason: DWORD, reserved1: DWORD .if reason == DLL_PROCESS_ATTACH; When the dll is loaded push hInst pop hInstance call ShowBitMap .endif mov eax, TRUE ret DllEntry Endp ShowBitMap proc 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, 0 invoke LoadCursor, NULL, IDC_ARROW mov wc.hCursor, eax invoke RegisterClassEx, addr wc Invoke CreateWindowex, Null, AddR ClassName, NULL, / WS_POPUP, CW_USEDEFAULT, / CW_USEDEFAULT, 250,250, NULL, NULL, / hInstance, NULL mov hwnd, eax INVOKE ShowWindow, hwnd, SW_SHOWNORMAL .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 ShowBitMap endp WndProc proc hWnd: DWORD, uMsg: DWORD, wParam: DWORD, lParam: DWORD LOCAL ps: PAINTSTRUCT LOCAL hdc: HDC LOCAL hMemoryDC: HDC LOCAL hOldBmp: DWORD LOCAL bitmap : Bitmap Local Dlgheight: DWORD LOCAL DLGWIDTH: DWORD LOCAL DLGRECT: RECT LOCAL DesktopRect: Rect

.if uMsg == WM_DESTROY .if hBitMap! = 0 invoke DeleteObject, hBitMap .endif invoke PostQuitMessage, NULL .elseif uMsg == WM_CREATE invoke GetWindowRect, hWnd, addr DlgRect invoke GetDesktopWindow mov ecx, eax invoke GetWindowRect, ecx, addr DesktopRect push 0 mov eax, DlgRect.bottom sub eax, DlgRect.top mov DlgHeight, eax push eax mov eax, DlgRect.right sub eax, DlgRect.left mov DlgWidth, eax push eax mov eax, DesktopRect.bottom sub eax, DlgHeight shr eax, 1 Push Eax Mov Eax, DesktopRect.right Sub Eax, DLGWIDTH SHR Eax, 1 Push Eax Push Hwnd Call MoveWindow invoke LoadBitmap, hInstance, addr BitmapName mov hBitMap, eax invoke SetTimer, hWnd, 1,2000, NULL mov TimerID, eax .elseif uMsg == WM_TIMER invoke SendMessage, hWnd, WM_LBUTTONDOWN, NULL, NULL invoke KillTimer, hWnd, TimerID .elseif uMsg ==

WM_PAINT invoke BeginPaint, hWnd, addr ps mov hdc, eax invoke CreateCompatibleDC, hdc mov hMemoryDC, eax invoke SelectObject, eax, hBitMap mov hOldBmp, eax invoke GetObject, hBitMap, sizeof BITMAP, addr bitmap invoke StretchBlt, hdc, 0,0,250,250, / hMemoryDC, 0,0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY invoke SelectObject, hMemoryDC, hOldBmp invoke DeleteDC, hMemoryDC invoke EndPaint, hWnd, addr ps .elseif uMsg == WM_LBUTTONDOWN invoke DestroyWindow, hWnd .else invoke DefWindowProc, hWnd, uMsg , WPARAM, LPARAM RET .Endif Xor Eax, EAX RET WNDPROC Endpend DLLENTRY

Analysis: We must first check this code in the main program.

Invoke LoadLibrary, Addr Libname

.IF EAX! = NULL

Invoke Freelibrary, EAX

.endif

We call LoadLibrary to read the DLL name "splash.dll". Then, uninstall with FreeElibrary. Organize until the DLL is initialized, or LoadLibrary will return.

The master's task is to this, and more interesting parts are again DLL.

.IF real_attach; when the dll is loading push hinst pop hinstance call showbitmap

After the DLL is loaded, Windows calls its entry function with a DLL_PROCESS_ATTACH tag. We borrow this opportunity to display the startup screen. First, we save the handle of the DLL case for future use. Then, call a function of showbitmap to make a real job. Showbitmap registers a window, creates this window and display it. Just as we have created the window before. Interesting is this CreateWindowEx call:

Invoke CreateWindowex, Null, AddR Classname, Null, / WS_POPUP, CW_USEDEFAULT, / CW_USEDEFAULT, 250, 250, NULL, NULL, / HINSTANCE, NULL

Note that the window style here only uses WS_POPUP. So there is no title bar, and there is no boundary. We also limit the width of the window to 250x250 pixels. Now the window is created. We will put in the WM_CREATE message processing code This window is moved to the center of the screen. The code is as follows:

invoke GetWindowRect, hWnd, addr DlgRect invoke GetDesktopWindow mov ecx, eax invoke GetWindowRect, ecx, addr DesktopRect push 0 mov eax, DlgRect.bottom sub eax, DlgRect.top mov DlgHeight, eax push eax mov eax, DlgRect.right sub eax, DlgRect .left mov DlgWidth, eax push eax mov eax, DesktopRect.bottom sub eax, DlgHeight shr eax, 1 push eax mov eax, DesktopRect.right sub eax, DlgWidth shr eax, 1 push eax push hWnd call MoveWindow find it first desktop and windows The size. Then, calculate the coordinates of the upper left corner of the window. Make this window in the center of the screen.

Invoke Loadbitmap, Hinstance, Addr Bitmapname Mov Hbitmap, Eax Invoke Settimer, Hwnd, 1,2000, Null Mov Timerid, EAX

Next, it reads the bitmap from the resource with loadbitmap and creates a timer. The timer's ID is 2 seconds. The timer will send a WM_TIMER message every 2 seconds.

.elseif uMsg == WM_PAINT invoke BeginPaint, hWnd, addr ps mov hdc, eax invoke CreateCompatibleDC, hdc mov hMemoryDC, eax invoke SelectObject, eax, hBitMap mov hOldBmp, eax invoke GetObject, hBitMap, sizeof BITMAP, addr bitmap invoke StretchBlt, hdc, 0,0,250,250, / hmemorydc, 0,0, bitmap.bmwidth, Bitmap.bmheight, Srcopy Invoke Selectobject, HMemorydc, Holdbmp Invoke deletedc, HMemorydc Invoke Endpaint, HWnd, Addr PS

When the window receives a WM_Paint message, it creates a memory DC (PHEADNIUS: Remember DC. In Win32 programming you will often encounter DC this word. It is the abbreviation of Device Context, the official translation is "Device Description Table". If You have studied VC, you should be unfamiliar with it. But if you don't understand what it is, you can think of it as a handle. It is a name of a device or a block.), Then select the bitmap selection In-memory DC. Use the getObject function to get the size of the bitmap, then display the bitmap on the window with StretchBLT. Stretchblt's role is the same as Bitblt, but it can stretch or compress the bitmap to our hopes. Here we I hope that the bitmap can fit the size of the window, so our streetchblt instead of Bitblt. After we delete the memory DC..EELSEIF UMSG == WM_LButtondown Invoke DestroyWindow, Hwnd

If your programs are used to see the launch screen to disappear every time they will be bored. We can provide more options for users. When he clicks on the startup screen, it will disappear. This is why we To handle WM_LBUTTONDOWN messages in the DLL. After receiving this message, use DestroyWindow to turn off the window.

.ELSEIF UMSG == WM_Timer Invoke SendMessage, HWnd, WM_LButtondown, Null, Null Invoke Killtimer, HWnd, Timerid

If the user selects waiting, the startup screen disappears after the timer has been specified. (In this case, it is 2 seconds). We can achieve this with this news. After receiving this news, we You can transfer the WM_LBUTTONDOWN message to the window to turn off the window. This is to avoid code repetition. Now we no longer need this timer, so we remove it with KillTimer. After the window is closed, the DLL puts control to the main program.

转载请注明原文地址:https://www.9cbs.com/read-30112.html

New Post(0)