Chapter 6 Processing Keyboard Input Messages
In this lesson, we will learn how the Windows program handles the keyboard message.
theory:
Because most PCs have only one keyboard, all running Windows programs must share it. Windows will be responsible for sending keystrom messages to that application with input focus. Although there may be several application windows on the screen, there is only one window with input focus. The title bar of the application with input focus is always high brightness display. In fact, you can see the keyboard message from two perspectives: First, you can see it as a collection of buttons messages, in which case, when you press a key, Windows will send one WM_keyDown gives that application with input focus, reminds it that there is a button being pressed. When you release the button, Windows will send a WM_KYEUP message, telling a button to be released. You regard each key as a button; another situation is: You can see the keyboard as a character input device. When you press the "A" button, Windows sends a WM_CHAR message to an application with input focus, telling it that the "A" button is pressed. In fact, Windows sent WM_KEYDOWN and WWM_KEYUP messages to applications with input focus, and these messages will be translated into WM_CHAR messages by calling translateMessage. The Windows window process function will determine whether to handle the message received, generally tell you to deal with WM_KEYDOWN, WM_KEYUP messages, and convert the above message into a WM_CHAR message in the message loop. WM_CHAR will only be processed in our curriculum.
example:
.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 include /masm32/include/gdi32.inc includelib /masm32/lib/user32.lib includelib / masm32 / lib / kernel32.lib incrudelib /masm32/lib/gdi32.lib
.data classname DB "SimpleWinclass", 0 Appname DB "Our First Window", 0 Char WPARAM 20H; The Character The Program Receives from Keyboard
.DATA? Hinstance Hinstance? Commandline LPSTR?
. 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_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 invoke DispatchMessage, ADDR msg .ENDW mov eax, msg.wParam ret WinMain endpWndProc proc hWnd: HWND, uMsg: UINT, wParam: WPARAM, LPARAM: LPARAM LOCAL HDC: HDC Local PS: Paintstruct
.IF uMsg == WM_DESTROY invoke PostQuitMessage, NULL .ELSEIF uMsg == WM_CHAR push wParam pop char invoke InvalidateRect, hWnd, NULL, TRUE .ELSEIF uMsg == WM_PAINT invoke BeginPaint, hWnd, ADDR ps mov hdc, eax invoke TextOut, hdc, 0,0, AddR Char, 1 Invoke Endpaint, HWnd, Addr Ps .lse Invoke DefWindowProc, HWnd, UMSG, WPARAM, LPARAM RET WNDPIF XOR END START analysis:
Char WPARAM 20H; The Character The Program Receives from Keyboard
This variable will save the characters received from the keyboard. Because it is transmitted through the WPARAM type variable during the window, we simply define it as a WPARAM. Since our window is in the first time (that is, the time that is created) is no keyboard input, we set him into space characters (20h), which you can't see it. .ELSEIF uMSG == wm_char
Push WPARAM
POP Char
Invoke InvalidateRect, HWND, NULL, TRUE
This section is used to handle WM_CHAR messages. It places the received characters in the variable char, then invoke INVALIDATERECT, and invalidateRect makes the window's client area invalid, which will issue a WM_PAINT message, and the WM_PAINT message forces Windows to reselect its client area. The syntax of this function is as follows:
InvalidateRect Proto Hwnd: HWnd, / LPRECT: DWORD, / BERASE: DWORD
LPRECT is a pointer to a square structure that we wants to be invalid at a client area. If this value is equal to NULL, the entire client area is invalid; the Boolean BERASE tells Windows whether it is erase the background. If it is true, Windows wipes the background when calling the BeginPaint function. So the practice we here is: We will save all data about redrawing the customer area, then send a WM_PAINT message, process the message to process the message and reopen the client area based on the relevant data. Although this is something like walking the bow, but Windows has to handle such a huge message group, there is no certain rule. In fact, we can fully obtain the device context handle by calling the GETDC, then call the character, then call the ReleaseDC Release Device Context handle, there is no doubt that you can also draw the correct characters in the customer area. However, if this is later received, the client district will re-refresh it, and the characters drawn before us will disappear. So in order to make characters all displayed correctly, they must be processed during processing of WM_PAINT. The WM_PAINT message is sent in this message processing.
Invoke TextOut, HDC, 0, 0, AddR Char, 1