Eighteenth lesson general control
In this lesson, we will learn what is a general control and how to use them.
Theory: Win95 has several enhanced user interface controls with respect to Win3X. In fact, these controls are in use before WIN95, such as: status bars, tool bars, etc. Previous programmers have to program themselves, and now Microsoft has contains them to Win9X and Winnt.
Toolbar --- Tools Tooltip --- Tips text status bar --- Status PROPERTY SHEET --- Properties page list --- Tree View List View --- List View Animation --- Animation Drag List --- Ability to handle Drag-DROP list box Header --- Hot-key --- Hotkey Image List --- Image Links PROGRESS BAR - - Process Status Right Edit --- Tab --- Jumping Fit TRACKBAR --- Tracking UP-DOWN - - Rolling Bar Because the general control is large, all of them are all loaded and registered. They are very waste of memory. In addition to "RTF Text Edit" control, the executable code of other controls is placed in chactl32.dll, so other applications can use them. "RTF Text Editing" control is in richedxx.dll, because the control is very complicated, it is better than other controls.
To load COMCTL32.DLL can call the function initcommonControls in your application. The INITCOMMONTROLS function is a function in dynamic link libctl32.dll, as long as this function is referenced anywhere in your program, the library will be loaded. The function initcommonControls actually only one command "RET", its unique purpose is to make it in the "introduction" segment in the PE header of the executable of this function, such a "introduction" in the "introduction" segment, so when The app will load the library for you. So the real initialization work is done at the entry point of the library, where all the general control classes are registered here, and then all general controls can be created on these classes, which is like creating other sub-window controls. .
RTF text editing controls are different. If you want to use it, you must call the LoadLibrary function to dynamically load and call FreeELibrary to dynamically uninstall.
Now we learn how to create these general controls. You can use the resource editor to put them in a dialog, or you can also call the relevant functions to manually create them. Almost all common controls are created by calling the function createWindowEx or CREATEWINDOW, and you can only pass the class names of the general control. There are some universal controls with some special creation functions, but in fact, these functions call CreateWindowex inside, just that the package after the package is more convenient. After packaging functions:
CreateToolbarex CreateStatusWindow CreatePropertySheetPage PropertySheet ImageList_create To create a general control you must know their class name, we are listed in the following:
Class name
General control
ToolbarWindow32Toolbartooltips_class32Tooltipmsctls_statusbar32Status barSysTreeView32Tree viewSysListView32List viewSysAnimate32AnimationSysHeader32Headermsctls_hotkey32Hot-keymsctls_progress32Progress barRICHEDITRich editmsctls_updown32Up-downSysTabControl32Tab
Property Sheets, Property Pages and Image List controls have their own creation functions. Drag List is actually a scalable ListBox control, so it doesn't have your own class name. The above class name is provided by the VC resource editor, which is not the same as Borland's Win32 API guide, and PROGRAMMING Windows 95 "in Borland is different. It is certain that the class names listed above are absolutely accurate. These universal controls can have some styles of the universal window class, such as WS_CHILD, and more. They certainly have other special styles, such as tree view controls, have a TVS_XXXXX style, and list controls have a lvs_xxxx style. Specific best to find the relevant Win32 API function guide. Since we already know how to create a general control, we can discuss how these general controls and how to communicate between their parent windows. Unimedian window controls, universal controls are not transmitted by sending WM_NOTIFY messages and parent windows when they change the WM_COMMAND. The parent window can control the behavior of the sub-window by sending messages. For those new generic controls, there are some new messages. You can refer to your Win32 API manual. In the following example, we will experiment with the progress bar and status bar.
Example code:
.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/ComctL32.inc
INCLUDELIB /MASM32/LIB/ComctL32.lib
INCLUDELIB /MASM32/LIB/USER32.LIB
INCLUDELIB /MASM32/LIB/kernel32.lib
Winmain Proto: DWORD,: DWORD,: DWORD,: DWORD
.const IDC_Progress EQU 1; Control IDS IDC_STATUS EQU 2 IDC_TIMER EQU 3
.data classname DB "Commontrolwinclass", 0 AppName DB "Common Control Demo", 0 ProgressClass DB "Msctls_Progress32", 0; The Class Name of the Progress Bar Message DB "Finished!", 0 Timerid DD 0
? .Data hInstance HINSTANCE hwndProgress dd hwndStatus dd CurrentStep dd .code start:???? Invoke GetModuleHandle, NULL mov hInstance, eax invoke WinMain, hInstance, NULL, NULL, SW_SHOWDEFAULT invoke ExitProcess, eax invoke InitCommonControls
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 hInst pop wc.hInstance mov wc.hbrBackground, COLOR_APPWORKSPACE 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, WS_EX_CLIENTEDGE, aDDR ClassName, ADDR AppName, / WS_OVERLAPPED WS_CAPTION WS_SYSMENU WS_MINIMIZEBOX WS_MAXIMIZEBOX WS_VISIBLE, CW_USEDEFAULT, / CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, / hInst, NULL mov hwnd, eax .while TRUE invoke GetMessage, ADDR msg, NULL, 0,0 .break .if (! EAX) Invoke TranslateMessage, Addr Msg .Endw Mov Eax, Msg.wParam RET WinMain Endp
WndProc proc hWnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM .if uMsg == WM_CREATE invoke CreateWindowEx, NULL, ADDR ProgressClass, NULL, / WS_CHILD WS_VISIBLE, 100, / 200,300,20, hWnd, IDC_PROGRESS, / hInstance, NULL mov hwndProgress, eax mov eax, 1000; the lParam of PBM_SETRANGE message contains the range mov currentStep, eax shl eax, 16; the high range is in the high word invoke SendMessage, hwndProgress, PBM_SETRANGE, 0, eax invoke SendMessage, hwndProgress, PBM_SETSTEP, 10,0 invoke CreateStatusWindow, WS_CHILD WS_VISIBLE, NULL, hWnd, IDC_STATUS mov hwndStatus, eax invoke SetTimer, hWnd, IDC_TIMER, 100, NULL; create a timer mov timerID, eax .elseif uMsg == WM_DESTROY invoke PostQuitMessage, Null .IF Timerid! = 0 Invoke Killtimer, HWnd, Timerid .ndif .elseif UMSG == WM_TIMER; WHEN A TIMER EVENT OCCURS invoke SendMessage, hwndProgress, PBM_STEPIT, 0,0; step up the progress in the progress bar sub CurrentStep, 10 .if CurrentStep == 0 invoke KillTimer, hWnd, TimerID mov TimerID, 0 invoke SendMessage, hwndStatus, SB_SETTEXT, 0, addr Message invoke MessageBox, hWnd, addr Message, addr AppName, MB_OK MB_ICONINFORMATION invoke SendMessage, hwndStatus, SB_SETTEXT, 0,0 invoke SendMessage, hwndProgress, PBM_SETPOS, 0,0 .endif .else invoke DefWindowProc, hWnd, uMsg, wParam, lParam ret. Endif XOR EAX, EAX RET WNDPROC END START Analysis:
Invoke Winmain, Hinstance, Null, NULL, SW_SHOWDEFAULT
Invoke EXITPROCESS, EAXINVOKE INITCOMMONCONTROLS
I deliberately put the function initcommonControls after exitprocess so that you can verify that the function is only to place information in the introduction segment in the PE header of the executable file of our program. You can see that even if the function doesn't do, our General Control Dialog is still working properly.
.IF uMSG == WM_CREATE
Invoke CreateWindowex, Null, Addr ProgressClass, NULL, /
WS_CHILD WS_VISIBLE, 100, /
200, 300, 20, hwnd, IDC_Progress, /
Hinstance, NULL
Mov HWndProgress, EAX
Here we have created a general control. Note that the parameter hWnd in the CREATEWINDOWEX function is the handle of the parent window. In addition, it also specifies the ID number of the general control. Because we directly use the control window handle, there is no use of the ID number. All windows must have a WS_CHILD style.
Mov Eax, 1000
Mov Currentstep, EAX
SHL EAX, 16
Invoke SendMessage, HWndProgress, PBM_SETRANGE, 0, EAX
Invoke SendMessage, HWndProgress, PBM_SETSTEP, 10, 0
After you create a progress bar, we set its range. The default range is 0-100. If you are not satisfied, you can reset it, which is implemented by passing the PBM_setRange message. The parameter LPARAM contains range values, where the bottom and high words are the starting and value of the range, respectively. You can specify a step size per move. In this example, the step size is set to 10, which means that each of the PBM_STEPIT messages gives the progress bar, and its display pointer will move 10. Of course, you can call PBM_SETPOS to directly set the position of the pointer on the progress bar. With this message you can set the progress bar more conveniently.
Invoke CreateStatusWindow, WS_CHILD WS_VISible, NULL, HWND, IDC_STATUS
Mov hwndstatus, EAX
Invoke SetTimer, HWND, IDC_TIMER, 100, NULL; CREATE A TIMER
Mov Timerid, EAX
Below we call CreateStatusWindow to create a status bar. This call is very understanding, there is no need to explain more. We created a timer after the status bar was created. In this case, we update a progress bar every 100 milliseconds. Create a function prototype of the timer when you are below:
SetTimer Proto Hwnd: DWORD, TIMERID: DWORD, TIMEINTERVAL: DWORD, LPTIMERPROC: DWORD
HWND: The handle of the parent window.
Timerid: The ID number of the timer. You can specify a unique non-zero value.
TimerInterval: Time interval in millisecond.
LPTIMERPROC: The address of the timer callback function. This function will be called whenever time interval. If the value is null, the timer will send the WM_TIMER message to the parent window.
If the setTimer calls successfully returns the ID number value of the timer, otherwise it returns 0. This is also why the ID number of the timer must be a non-zero value.
.ELSEIF uMSG == WM_TIMER
Invoke SendMessage, HWndProgress, PBM_STEPIT, 0, 0
Sub Currentstep, 10
.IF currentstep == 0
Invoke Killtimer, Hwnd, Timerid
Mov Timerid, 0
Invoke SendMessage, HWndStatus, Sb_Settext, 0, Addr MessageInvoke MessageBox, HWnd, Addr Message, Addr Appname, MB_OK MB_ICONIONFORMATION
Invoke SendMessage, HWndStatus, Sb_Settext, 0, 0
Invoke SendMessage, HWndProgress, PBM_SETPOS, 0, 0
.endif
When the specified time is here, the timer will send a WM_TIMER message. You can work properly when processing the message. In this example we will update the progress bar and check whether the progress bar exceeds the maximum value. If you exceed it, we set the text in the status bar by sending the SB_SETTEXT message. At this time, a dialog is popped, and after the user turns off the dialog, we remove the text in the progress bar and status bar.