Class 22
In this lecture, we will learn what is superclade and what effect it; and you will learn how to switch this skill in the control in your own window.
theory:
In your program career, you must have encountered this situation, you need a series of controls, but there is only a little difference between them. For example, you may need 10 EDIT controls that only accept numbers, of course, you can achieve this with a variety of ways.
Create your own class and use it to instantiate to those controls to create those Edit controls and put them all subcatenium hyperphory EDIT controls
The first method is too boring, because you must implement each of the EDIT controls, but this work is not easy to complete. The second method is better than the first, but there is still a lot of work. Several EDIT controls can also be accepted, but if the subcolators are more than ten twenties, this work is simply a dream. In this case, you should use the superclassization skill, which is a special way to control a particular window class. Through this control, you can modify the characteristics of the window class, which meets your requirements, and then create that heap control.
Super category has the following steps:
Get information of window classes you want to perform supercarbed operations by calling getClassInfoEx. The function getClassInfoEx needs a pointer to the WNDCLASSEX structure to fill in the window class when successfully returns. The member of the WNDCLASSEX structure is modified as needed, with two members must modify: The instance of the Hinstance storage program points LPSZClassName points to a new class name that does not have to modify the member lpfnwndproc, but most cases still need. But remember if you want to use a function CallWindowProc to call the old window, you must save the original value of the member lpfnwndproc. Register the modified WNDCLASSEX structure to get a new window class with some of the old window classes. Create a window with a new window class
If you want to create multiple controls with the same characteristics, supercarbing is better than that.
Example:
.386 .model flat, stdcall option casemap: none include /masm32/include/windows.inc include /masm32/include/user32.inc include /masm32/include/kernel32.inc includelib /masm32/lib/user32.lib includelib / masm32 /LIB/kernel32.lib WM_SUPERCLASS EQU WM_USER 5 WINMAIN Proto: DWORD,: DWORD,: DWORD,: DWORD EditWord,: DWORD,: DWORD,: DWORD,: DWORD
.DATA CLASSNAME DB "Superclasswinclass", 0 AppName DB "Superclassing Demo", 0 Editclass DB "Edit", 0 Ourclass DB "SupeReditclass", 0 Message DB "You Pressed The Enter Key in The Text Box!", 0
.DATA? HINSTANCE DD? HWndedit DD 6 DUP (?); stores the array of 6 windows handle OldWndProc DD?; the original window process
. Code Start: Invoke GetModuleHandle, Null Mov Hinstance, Eax Invoke Winmain, Hinstance, Null, Null, SW_SHOWDEFAULT INVOKE EXITPROCESS, EAX
WinMain proc hInst: HINSTANCE, hPrevInst: HINSTANCE, CmdLine: LPSTR, CmdShow: DWORD LOCAL wc: WNDCLASSEX LOCAL msg: MSG LOCAL hwnd: HWNDmov 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 WS_EX_CONTROLPARENT, aDDR ClassName, aDDR AppName, / WS_OVERLAPPED WS_CAPTION WS_SYSMENU WS_MINIMIZEBOX WS_MAXIMIZEBOX WS_VISIBLE, CW_USEDEFAULT, / CW_USEDEFAULT, 350, 220, NULL, NULL, / HINST, NULL MOV HWND, EAX
.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 uses ebx edi hWnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM LOCAL wc: WNDCLASSEX .if uMsg == WM_CREATE mov wc.cbSize, sizeof WNDCLASSEX invoke GetClassInfoEx, NULL, addr EditClass, addr wc push wc. lpfnWndProc pop OldWndProc mov wc.lpfnWndProc, OFFSET EditWndProc push hInstance pop wc.hInstance mov wc.lpszClassName, OFFSET OurClass invoke RegisterClassEx, addr wc xor ebx, ebx mov edi, 20 .while ebx <6 invoke CreateWindowEx, WS_EX_CLIENTEDGE, aDDR OurClass, NULL , / WS_CHILD WS_VISIBLE WS_BORDER, 20, / EBX, 300, 25, HWND, EBX, / HINSTANCE, NULL MOV DWORD PTR [HWndedit 4 * EBX], EAX Add Edi, 25 Inc EBX .Endw Invoke SetFocus, HWndIt. Elseif UMSG == WM_DESTROY INVOKE POSTQUITMESSAGE, NULL .ELSE INVOKE DEFWINDOWPROC, HWND, UMSG, WPARAM, LPARAM RET WNDPROC ENDP
EditWordProc Proc Hedit: DWORD, UMSG: DWORD, WPARAM: DWORD, LPARAM: DWORD .IF UMSG == WM_CHAR MOV EAX, WPARAM .IF (Al> = "0" && al <= "9") || (al> = "A" && al <= "f") || (al> = "a" && al <= "f") || Al == vk_back; processing characters 0 ~ 9, a ~ f, a ~ f, this Several hexadecimal numbers .IF Al> = "a" && al <= "f" SUB AL, 20H If it is character A ~ F, turn them to capital. Nendif Invoke CallWindowProc, OldWndProc, Hedit, UMSG, eax, lParam ret .endif .elseif uMsg == WM_KEYDOWN mov eax, wParam .if al == VK_RETURN invoke MessageBox, hEdit, addr Message, addr AppName, MB_OK MB_ICONINFORMATION invoke SetFocus, hEdit .elseif al == VK_TAB invoke GetKeyState, VK_SHIFT test eax, 80000000 .if ZERO? invoke GetWindow, hEdit, GW_HWNDNEXT .if eax == NULL invoke GetWindow, hEdit, GW_HWNDFIRST .endif .else invoke GetWindow, hEdit, GW_HWNDPREV .if eax == NULL invoke GetWindow, hEdit, GW_HWNDLAST .endif .endif invoke SetFocus, eax xor eax, eax ret .else invoke CallWindowProc, OldWndProc, hEdit, uMsg, wParam, lParam ret .endif .else invoke CallWindowProc, OldWndProc, hEdit, uMsg, wParam, lParam ret .endif xor eax, eax ret EditWndProc Endp End Start Analysis
This program created a simple window with six modified EDIT controls in its client area, which only accepts hexadecimal numbers. In fact, this example is obtained by modifying the window of the window. The program starts with other programs, and the interesting portion appears when the main window is created:
.IF uMSG == WM_CREATE MOV WC.CBSIZE, SIZEOF WNDCLASSEX INVSIKE GETCLASSINFOEX, NULL, ADDR Editclass, Addr WC
You must fill the WNDCLASSEX structure with class data you want to perform superclass operation. In our example, you must fill in the member CBSIZE before calling the function getClassInfoEx. Otherwise, the function calls GetClassInfoEx will not fill in the correct in the WNDCLASSEX structure. return value. After successful returns, the variable wc is saved is to create all the information you need to create a new class.
push wc.lpfnWndProc pop OldWndProc mov wc.lpfnWndProc, OFFSET EditWndProc push hInstance pop wc.hInstance mov wc.lpszClassName, OFFSET OurClass must now modify some of the attributes wc variables: the first to be modified is a pointer to the window procedure. Because the function CallWindowProx is used in the new window to use the old window process, save it to a variable for use. This trick is used in subclass, but not calling setWindowlong but directly modifying the WNDCLASSEX structure. Next, you must get a name for this new class.
Invoke RegisterClassex, Addr WC
When all of this is complete, registering this new category will get a new class with some of the old class.
xor ebx, ebx mov edi, 20 .while ebx <6 invoke CreateWindowEx, WS_EX_CLIENTEDGE, ADDR OurClass, NULL, / WS_CHILD WS_VISIBLE WS_BORDER, 20, / edi, 300,25, hWnd, ebx, / hInstance, NULL mov dword ptr [hwndit 4 * EBX], EAX Add Edi, 25 Inc EBX .Endw Invoke SetFocus, HWndedit
Registering the new class to create its window: In the above program clip, use the register EBX to save the number of windows, with the register EDI to save the Y coordinates in the upper left corner of the window. When you create a new window, save its handle in an array of double words. When all the windows are created, set the input focus as the first window created.
At this time, there have been 6 EDIT window controls that can only accept hexadecimal numbers, and the replaceable window processes characters filtering, which is actually the same as examples in subclass. But you don't have to do extra work of those windows.
In this program, this program is more interesting by using a TABS key to cut in each EDIT control. In general, if you use a dialog, the dialog manager handles all of these issues, ie: Press the TABS input focus to switch to the next control window, press the SHIFT-TABS input focus to switch to the previous control window; But a simple window does not have this feature, and you must submit them to process the TABS key. In this example, it is not necessary to have one of the depers that have been hyperlying these controls, and a centralized control switching strategy can be used.
.elseif al == VK_TAB invoke GetKeyState, VK_SHIFT test eax, 80000000 .if ZERO? invoke GetWindow, hEdit, GW_HWNDNEXT .if eax == NULL invoke GetWindow, hEdit, GW_HWNDFIRST .endif .else invoke GetWindow, hEdit, GW_HWNDPREV .if eax = = Null Invoke GetWindow, Hedit, GW_HWndlast .ndif.ndif Invoke SetFocus, EAX XOR Eax, Eax Ret