Win32 assembly: 9. Sub-window control

zhaozj2021-02-17  58

Ninth lesson window control

In this lesson, we will explore the control, which is the main input and output devices in our program.

Theory: Windows offers several predefined window classes to facilitate our use. In most time, we use them in the dialog, so we generally call the sub-window controls. The sub-window control will handle the message and inform the parent window when changing in its own state. This greatly reduces our programming, so we should use them as much as possible. In this lesson, we put these controls in the window to simplify the program, but most of the sub-window controls are placed in the dialog. The sub-window controls present in our example include: buttons, drop-down menu, check box, radio button, edit box, etc. When using sub-window controls, call CREATEWINDOW or CREATEWINDOWEX first. Here, because Windows has already registered these child controls, there is no need to register again. Of course we can't change their names. For example, if you want a button, you must specify "Button" when calling the above two functions. Other parameters that must be specified also include the handle of the parent window and the ID number of the sub-control to be generated. The ID number of the sub-control is used to identify the sub-control, so it must be unique. After the sub-control is generated, the message will be sent to the parent window when its status changes. Generally we should generate a word control in the WM_CREATE message of the parent window. The message sent to the parent window is WM_COMMAND, and includes the ID number of the control in the passage of the parameter WPARA, the message number in WPARAM, including the handle of the window of the sub-control. Various types of controls have different news codes. For details, please refer to the Win32 API Reference Manual. The parent window can also send messages to the child control by calling the function sendMessage, where the first parameter is the window handle of the child control, the second parameter is the message number to send, and the additional parameters can be passed in WPARAM and LPARAM, in fact I know the handle of a window to send the relevant message to it. So generate the WM_COMMAND message after generating a child window so that the message of the child control can be received.

Example: We will generate a window that has an edit box and a button in this window. When you press the button, a dialog box will pop up in which you entered in the edit box. In addition, the application has a menu, which has four menu items:

Say Hello - Enter a string to edit the control; Clear Edit Box - Clear the string in the edit control; Get Text - Pop-pop-up dialog box to display the string in the edit control; Exit - Exit the application.

.386

.Model flat, stdcall

Option CaseMAP: NONE

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

Include /masm32/include/windows.inc include /masm32/include/user32.inc include /masm32/include/kernel32.inc includelib /masm32/lib/user32.lib incrudelib /masm32/lib/kernel32.lib

.data ClassName db "SimpleWinClass", 0 AppName db "Our First Window", 0 MenuName db "FirstMenu", 0 ButtonClassName db "button", 0 ButtonText db "My First Button", 0 EditClassName db "edit", 0 TestString db "WOW! I'M in an Edit Box Now", 0.data? Hinstance Hinstance? CommandLine LPSTR? HWNDBUTTON HWND? HWNDIT HWND? Buffer DB 512 DUP (?); Buffer to Store TEXT RETRIEVED from The Edit Box

.const buttonid EQU 1; the control id of the button control Editid EQU 2; The control id of the edit control idm_hello eQU 1 IDM_CLEAR EQU 2 IDM_GETTEXT EQU 3 IDM_EXIT EQU 4

. 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 hInst pop wc.hInstance mov wc.hbrBackground, COLOR_BTNFACE 1 mov wc.lpszMenuName, OFFSET MenuName 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_OVERLAPPEDWINDOW, / CW_USEDEFAULT, CW_USEDEFAULT, / 300,200, 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 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_DESTROY invoke PostQuitMessage, NULL .ELSEIF uMsg == WM_CREATE invoke CreateWindowEx, WS_EX_CLIENTEDGE, ADDR EditClassName, NULL, / WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or / ES_AUTOHSCROLL, / 50,35,200,25, hWnd, 8, hInstance, NULL mov hwndEdit, eax invoke SetFocus, hwndEdit invoke CreateWindowEx, NULL, ADDR ButtonClassName, ADDR ButtonText, / WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, / 75,70,140, 25, hWnd, buttonID, hInstance, NULL mov hwndButton, eax .ELSEIF uMsg == WM_COMMAND mov eax, wParam .IF lParam == 0 .IF ax == IDM_HELLO invoke SetWindowText, hwndEdit, ADDR TestString .ELSEIF ax == IDM_CLEAR invoke SetWindowText , hwndite, null .elseif AX == idm_gettext invoke GetWindowText, hwndEdit, ADDR buffer, 512 invoke MessageBox, NULL, ADDR buffer, ADDR AppName, MB_OK .ELSE invoke DestroyWindow, hWnd .ENDIF .ELSE .IF ax == ButtonID shr eax, 16 .IF ax == BN_CLICKED invoke SendMessage, HWND, WM_COMMAND, IDM_GETTEXT, 0 .Endif .ndif.ndif.Else Invoke DefWindowProc, HWND, UMSG, WPARAM, LPARAM RET WNDPROC ENDP END Start Analysis: We now start analysis,

.ELSEIF uMSG == WM_CREATE

Invoke CreateWindowex, WS_EX_CLIENTEDGE, /

AddR editclassname, null, / ws_child or ws_visible or ws_border or es_left /

OR ES_AUTOHSCROLL, /

50, 35, 200, 25, Hwnd, Editid, Hinstance, Null

Mov hwndedit, EAX

Invoke setfocus, hwndedit

Invoke CreateWindowex, Null, AddR ButtonClassName, /

AddR buttonText, /

WS_CHILD or WS_VISIBLE OR BS_DEFPUSHBUTTON, /

75, 70, 140, 25, hwnd, buttonid, hinstance, null

Mov hwndbutton, EAX

We have a child control in WM_CREATE, where is a WS_EX_CLIENTEDGE style to the child control window in the function CreateWindowEx, which makes the sub-control window looks at the boundary, and has three-dimensional. The class names of each sub-control are predefined, such as: The predefined class name of the button is "Button", the edit box is "Edit". The next parameter is the window style. In addition to the usual window, each control has its own extension style, such as the button class extension style, in front of the BS_, edit box class is: ES_, Win32 API reference Description of all extended styles. Note: You have no side effects that you have to pass the menu of the menu handle in the CreateWindowsex function, because the sub-window control itself does not have a menu. After generating controls, we save their handles, then call setfocus to set the focus to the editing control so that the user can enter. The next is how to handle the notification message sent by the control message WM_COMMAND:

.ELSEIF uMSG == WM_Command Mov Eax, wparam .IF lparam == 0

We used to say that the choice of menu would want to send WM_COMMAND messages, how should we distinguish? You will be at a glance at the table below:

Low Word of WParamhigh Word of WParamlParammenUMenu ID00ControlControl IDNotification CodeChild WINDOW HANDLE

We can see that you can't use WPARAM, because the menu and control ID number may be the same, and the message number of the child window space may be 0.

.IF ax == IDM_HELLO invoke SetWindowText, hwndEdit, ADDR TestString .ELSEIF ax == IDM_CLEAR invoke SetWindowText, hwndEdit, NULL .ELSEIF ax == IDM_GETTEXT invoke GetWindowText, hwndEdit, ADDR buffer, 512 invoke MessageBox, NULL, ADDR buffer, ADDR AppName , MB_OK

You can call the setWindowText function to bring a string to the editing control, for the sake of 0, pass to the NULL value. SetWindowText is a universal function that can be used to set the title of a window, or use it to change the text on a button. If you want to get the text on the button, call getWindowText. .IF AX == Buttonid SHR EAX, 16 .IF AX == BN_Clicked Invoke SendMessage, HWnd, WM_COMMAND, IDM_GETTEXT, 0 .endif .Endif.

The above fragment is to process the user button event. He first checks if the WPARAM's high byte is a button ID number. If you check if the low byte is sent to send the message number to bn_clicked, the message is sent when the button is pressed, if everything is correct, then transfer This message, we can copy all of the code from the processing message IDM_Gettext, but a more professional way is to send a IDM_GETTEXT message to process the main window process, which sets the transferred message to WM_COMMAND, and then put the low byte of WPARAM Set to IDM_Gettext. This way, your code is simple, so you can use this skill as much as possible. Finally, of course not or or have no, the function TRANSLATEMESSAGE must be called in the message loop because your application needs to enter readable text in the edit box. If this function is omitted, you cannot enter anything in the edit box.

Ninth lesson window control

In this lesson, we will explore the control, which is the main input and output devices in our program.

theory:

Windows offers several predefined window classes to facilitate our use. In most time, we use them in the dialog, so we generally call the sub-window controls. The sub-window control will handle the message and inform the parent window when changing in its own state. This greatly reduces our programming, so we should use them as much as possible. In this lesson, we put these controls in the window to simplify the program, but most of the sub-window controls are placed in the dialog. The sub-window controls present in our example include: buttons, drop-down menu, check box, radio button, edit box, etc. When using sub-window controls, call CREATEWINDOW or CREATEWINDOWEX first. Here, because Windows has already registered these child controls, there is no need to register again. Of course we can't change their names. For example, if you want a button, you must specify "Button" when calling the above two functions. Other parameters that must be specified also include the handle of the parent window and the ID number of the sub-control to be generated. The ID number of the sub-control is used to identify the sub-control, so it must be unique. After the sub-control is generated, the message will be sent to the parent window when its status changes. Generally we should generate a word control in the WM_CREATE message of the parent window. The message sent to the parent window is WM_COMMAND, and includes the ID number of the control in the passage of the parameter WPARA, the message number in WPARAM, including the handle of the window of the sub-control. Various types of controls have different news codes. For details, please refer to the Win32 API Reference Manual. The parent window can also send messages to the child control by calling the function sendMessage, where the first parameter is the window handle of the child control, the second parameter is the message number to send, and the additional parameters can be passed in WPARAM and LPARAM, in fact I know the handle of a window to send the relevant message to it. So generate the WM_COMMAND message after generating a child window so that the message of the child control can be received.

example:

We will generate a window, there is an edit box and a button in this window. When you press the button, a dialog box will pop up in which you entered in the edit box. In addition, the application has a menu, which has four menu items: Say Hello - Enter a string into the edit control; Clear Edit Box - Clear the string in the edit control; Get Text - Pop-up dialog box Edit the string in the control; Exit - Exit the application.

.386 .Model flat, Stdcall Option Casemap: NONE

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

Include /masm32/include/windows.inc include /masm32/include/user32.inc include /masm32/include/kernel32.inc includelib /masm32/lib/user32.lib incrudelib /masm32/lib/kernel32.lib

.data ClassName db "SimpleWinClass", 0 AppName db "Our First Window", 0 MenuName db "FirstMenu", 0 ButtonClassName db "button", 0 ButtonText db "My First Button", 0 EditClassName db "edit", 0 TestString db "WOW! I'm in an Edit Box Now", 0

.DATA? HINSTANCE HINSTANCE? COMMANDLINE LPSTR? HWNDIT HWND? Buffer DB 512 DUP (?); Buffer to Store TEXT RETRIEVED from The Edit Box

.const buttonid EQU 1; the control id of the button control Editid EQU 2; The control id of the edit control idm_hello eQU 1 IDM_CLEAR EQU 2 IDM_GETTEXT EQU 3 IDM_EXIT EQU 4

. 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 hInst pop wc.hInstance mov wc.hbrBackground, COLOR_BTNFACE 1 mov wc.lpszMenuName, OFFSET MenuName 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_OVERLAPPEDWINDOW, / CW_USEDEFAULT, CW_USEDEFAULT, / 300,200, 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 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_DESTROY invoke PostQuitMessage, NULL .ELSEIF uMsg == WM_CREATE invoke CreateWindowEx, WS_EX_CLIENTEDGE, ADDR EditClassName, NULL, / WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or / ES_AUTOHSCROLL, / 50,35,200,25, hWnd, 8, hInstance, NULL mov hwndEdit, eax invoke SetFocus, hwndEdit invoke CreateWindowEx, NULL, ADDR ButtonClassName, ADDR ButtonText, / WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, / 75,70,140, 25, hWnd, buttonID, hInstance, NULL mov hwndButton, eax .ELSEIF uMsg == WM_COMMAND mov eax, wParam .IF lParam == 0 .IF ax == IDM_HELLO invoke SetWindowText, hwndEdit, ADDR TestString .ELSEIF ax == IDM_CLEAR invoke SetWindowText , hwndite, null .elseif AX == idm_gettext invoke GetWindowText, hwndEdit, ADDR buffer, 512 invoke MessageBox, NULL, ADDR buffer, ADDR AppName, MB_OK .ELSE invoke DestroyWindow, hWnd .ENDIF .ELSE .IF ax == ButtonID shr eax, 16 .IF ax == BN_CLICKED invoke SendMessage, HWND, WM_COMMAND, IDM_GETTEXT, 0 .Endif .Endif .Endif.Else Invoke DefWindowProc, HWnd, UMSG, WPARAM, LPARAM RET WNDPROG END START analysis:

We started analysis now.

.ELSEIF uMSG == WM_CREATE

Invoke CreateWindowex, WS_EX_CLIENTEDGE, /

AddR editclassname, null, / ws_child or ws_visible or ws_border or es_left /

OR ES_AUTOHSCROLL, /

50, 35, 200, 25, Hwnd, Editid, Hinstance, Null

Mov hwndedit, EAX

Invoke setfocus, hwndedit

Invoke CreateWindowex, Null, AddR ButtonClassName, /

AddR buttonText, /

WS_CHILD or WS_VISIBLE OR BS_DEFPUSHBUTTON, /

75, 70, 140, 25, hwnd, buttonid, hinstance, null

Mov hwndbutton, EAX

We have a child control in WM_CREATE, where is a WS_EX_CLIENTEDGE style to the child control window in the function CreateWindowEx, which makes the sub-control window looks at the boundary, and has three-dimensional. The class names of each sub-control are predefined, such as: The predefined class name of the button is "Button", the edit box is "Edit". The next parameter is the window style. In addition to the usual window, each control has its own extension style, such as the button class extension style, in front of the BS_, edit box class is: ES_, Win32 API reference Description of all extended styles. Note: You have no side effects that you have to pass the menu of the menu handle in the CreateWindowsex function, because the sub-window control itself does not have a menu. After generating controls, we save their handles, then call setfocus to set the focus to the editing control so that the user can enter. The next is how to handle the notification message sent by the control message WM_COMMAND:

.ELSEIF uMSG == WM_Command Mov Eax, wparam .IF lparam == 0

We used to say that the choice of menu would want to send WM_COMMAND messages, how should we distinguish? You will be at a glance at the table below:

Low Word of WParamhigh Word of WParamlParammenUMenu ID00ControlControl IDNotification CodeChild WINDOW HANDLE

We can see that you can't use WPARAM, because the menu and control ID number may be the same, and the message number of the child window space may be 0.

.IF ax == IDM_HELLO invoke SetWindowText, hwndEdit, ADDR TestString .ELSEIF ax == IDM_CLEAR invoke SetWindowText, hwndEdit, NULL .ELSEIF ax == IDM_GETTEXT invoke GetWindowText, hwndEdit, ADDR buffer, 512 invoke MessageBox, NULL, ADDR buffer, ADDR AppName , MB_OK

You can call the setWindowText function to bring a string to the editing control, for the sake of 0, pass to the NULL value. SetWindowText is a universal function that can be used to set the title of a window, or use it to change the text on a button. If you want to get the text on the button, call getWindowText. .IF AX == Buttonid SHR EAX, 16 .IF AX == BN_Clicked Invoke SendMessage, HWnd, WM_COMMAND, IDM_GETTEXT, 0 .endif .Endif.

The above fragment is to process the user button event. He first checks if the WPARAM's high byte is a button ID number. If you check if the low byte is sent to send the message number to bn_clicked, the message is sent when the button is pressed, if everything is correct, then transfer This message, we can copy all of the code from the processing message IDM_Gettext, but a more professional way is to send a IDM_GETTEXT message to process the main window process, which sets the transferred message to WM_COMMAND, and then put the low byte of WPARAM Set to IDM_Gettext. This way, your code is simple, so you can use this skill as much as possible. Finally, of course not or or have no, the function TRANSLATEMESSAGE must be called in the message loop because your application needs to enter readable text in the edit box. If this function is omitted, you cannot enter anything in the edit box.

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

New Post(0)