Win32 assembly: 20. Window subclass

zhaozj2021-02-17  54

The second ten lesson window subclass

In this reason, we will learn what is window subclass and how to use it in the way you want.

theory:

If you have edited the program in the Windows environment, sometimes you will find: There is a ready-made window, almost all the features you need, but it is not exactly the same (otherwise there is no need to speak this section). Have you encountered such a situation, if you need an edit control with a special character function. Of course, the most direct way is to implement yourself, but this is indeed a time-friendly task, and window subcategory can be used to do this.

Window Subclass allows you to take over the subclass of windows, so that you have absolute control. For example, you need to accept a text edit box that only accepts hexadecimal numbers. If you use a simple Edit control, you don't know if you enter characters other than hexadecimal. There is no way. That is, when the user enters the text box, enter the string "ZB Q *", if almost anything else to accept the entire string, at least this is particularly unprofessional. It is important that you need to have the ability to input detection, that is, whenever the user enters a character into the edit box, you can detect this character.

Now explain the implementation details: When the user enters the character into the text box, Windows will send a WM_CHAR message to the Edit control window function. This window function itself is parasitized in Windows, so it cannot be modified directly. But we can redirect this message to the window handling function we have written in our own. If the custom window is to handle this message, you can process it. If you do not process, you can forward this message to its original window handling function. In this way, the custom window processing function is inserted into the Windows system and the EDIT control.

Look at the following process: Windows ==> Edit control window processing function before the window subcatenification.

After subclass, Windows ==> Custom Window Processing Function ==> The window handling function of the Edit control.

Attention is not limited to the control, you can submit any windows, now we have to concentrate on how to implement the subclass of one window. Let us think about how Windows knows where the edit control window handling function is placed. Guess? …Certainly not. The original WNDCLASSEX structure, LPFNWndProc, pointed out the window function address. If you can replace this member variable with the address of the window function you have written, the Windows does not send the message to a custom window function! We implemented this task by calling the function setWindowlong, this function is:

Setwindowlong Proto Hwnd: DWORD, NINDEX: DWORD, DWNEWLONG: DWORD

HWnd = The handle of the window to implement the subclass of the window NINDEX = function has the function index GWL_EXSTYLE setup window extension style. GWL_Style Sets the new window style GWL_WNDPROC Set the new window processing function address GWL_HINSTANCE Set the new application handle GWL_ID Set the new window Identify GWL_USERDATA Sets a 32-bit data dwnewlong used to users with this window = data used to update

Our work is still relatively simple:

Write a window function to process messages sent to the EDIT control. Use the parameter GWL_WNDPROC to call the setWindowlong function, if the call is successful, the return value is a 32-bit integer associated with the call function.

In our program, the return value is the address of the original window function. We want to save this value for later use. Remember: There are some news we don't deal with, you need to send them to the original window function, which uses another function CallWindowProc, the origin: CallWindowProc Proto LPPREvWndFunc: DWORD, HWND: DWORD, MSG: DWORD, WPARAM: DWORD, LPARAM: DWORD

LPPREVWNDFUNC = The address of the window is the original function. The remaining four parameters are the parameters sent to the custom function, directly pass them to the function CallWindowProc.

Code 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/ComctL32.inc

INCLUDELIB /MASM32/LIB/ComctL32.lib

INCLUDELIB /MASM32/LIB/USER32.LIB

INCLUDELIB /MASM32/LIB/kernel32.lib

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

EditWndProc Proto: DWORD,: DWORD,: DWORD,: DWORD

.DATA

ClassName DB "SubclasswinClass", 0

Appname DB "Subclassing Demo", 0

Editclass DB "Edit", 0

Message DB "You Pressed EnTer in the text box!", 0

.DATA?

Hinstance Hinstance?

HWndIt DD?

OldWndProc DD?

.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: 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, 350, 200, 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 HWND: HWND, UMSG: UINT, WPARAM: WPARAM, LPARAM: LPARAM

.IF uMSG == WM_CREATE

Invoke CreateWindowex, WS_EX_CLIENTEDGE, ADDR Editclass, NULL, /

WS_CHILD WS_VISIBLE WS_BORDER, 20, /

20, 300, 25, hwnd, null, /

Hinstance, NULL

Mov hwndedit, EAX

Invoke setfocus, EAX

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

Subclass it!

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

Invoke setWindowlong, HWndIt, GWL_WndProc, Addr EditWndProc

Mov OldWndProc, EAX

.ELSEIF uMSG == WM_DESTROY

Invoke PostquitMessage, NULL

.lse

Invoke DefWindowProc, Hwnd, UMSG, WPARAM, LPARAM

RET

.endif

XOR EAX, EAX

RET

WNDPROC ENDP

EditWndProc 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

.IF Al> = "a" && al <= "f"

SUB Al, 20h

.endif

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_ICONITIONFORMATION

Invoke setfocus, Hedit

.lse

Invoke CallWindowProc, OldWndproc, Hedit, UMSG, WPARAM, LPARAMRET

.endif

.lse

Invoke CallWindowProc, OldwndProc, Hedit, UMSG, WPARAM, LPARAM

RET

.endif

XOR EAX, EAX

RET

EditWndProc ENDP

End Start

analysis:

Invoke SetWindowlong, Hwndit, GWL_WndProc, Addr EditWndProcmov OldWndProc, Eax

After creating the Edit control, the original window function address is replaced with the address of the custom function by calling setWindowl, so that it is noted that in order to call the function CallWindowProc, we store the original window function address, self-written EditWndProc is just a Popular window function. Of course, you can also call a setWindowlong function to store this 32-bit value.

Invoke setWindowlong, HWndIt, GWL_USERDATA, EAX.

Of course, you will call getWindowlong to retrieve this value.

.IF uMSG == wm_char

Mov Eax, WPARAM

.IF (al> = "0" && al <= "9") || (al> = "a" && al <= "f") || (al> = "a" && al <= "f" ) || Al == VK_BACK

.IF Al> = "a" && al <= "f"

SUB Al, 20h

.endif

Invoke CallWindowProc, OldWndProc, Hedit, UMSG, Eax, LPARAM

RET

.endif

In the function editwndproc, we handle the WM_CHAR message: if the input character is '0' - '9', 'a' - 'f' or 'a' - 'f' accepts, and put this message Forward to the original window function, if you entered the lowercase 'a' - 'f', it becomes uppercase. If you enter is not a hexadecimal character, you will lose it and do not forward this message. Therefore, when the input is a non-hexadecimal character, this character will not be displayed in the Edit control.

.ELSEIF uMSG == WM_KEYDOWN

Mov Eax, WPARAM

.IF AL == VK_RETURN

Invoke Messagebox, Hedit, Addr Message, Addr Appname, MB_OK MB_ICONITIONFORMATION

Invoke setfocus, Hedit

.lse

Invoke CallWindowProc, OldwndProc, Hedit, UMSG, WPARAM, LPARAM

RET

.end .end

Here we further demonstrate the ability of subclass by handling the Enter key. EditWndProc determines if it is a Enter key by checking the WM_KeyDonw message, if the prompt message box is displayed, otherwise it is forwarded this message. You can use window subclass to control additional windows, which is one of the very useful technologies that must be mastered.

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

New Post(0)