The process of compiling a tutorial keyboard input message

Source: Internet
Author: User
Tags textout

In this lesson, we're going to learn how the Windows program handles keyboard messages.

Theory:

Because most PCs have only one keyboard, all running Windows programs must share it. WINDOWS will be responsible for sending keystroke messages to the application with the input focus. Although there may be several application windows on the screen, only one window at a time has input focus. The title bar of the application with the input focus is always displayed in high brightness. You can actually look at keyboard messages from two angles: one is that you can think of it as a collection of a bunch of key messages, in which case, when you press a key, Windows sends a WM_KEYDOWN to the application with the input focus, reminding it that a key is being pressed. When you release the key, Windows sends a WM_KYEUP message telling you that a key is released. You think of each key as a button, and the other is that you can think of the keyboard as a character input device. When you press the "a" key, Windows sends a WM_CHAR message to the application with the input focus, telling it that the "a" key is pressed. In fact, Windows sends Wm_keydown and WWM_KEYUP messages to applications that have input focus, and these messages are translated into WM_CHAR messages by calling TranslateMessage. The Windows window process function will decide whether to process the received message, and generally you will not be able to handle WM_KEYDOWN, WM_KEYUP messages, in which the TranslateMessage function converts the message to the WM_CHAR message. In our course, we will only deal with WM_CHAR.

Example:

.386
. Model Flat,stdcall
Option Casemap:none
WinMain Proto:D Word,:D Word,:D Word,:D Word
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
Includelib \masm32\lib\gdi32.lib
. Data
ClassName db "Simplewinclass", 0
AppName db "Our", 0
Char WPARAM 20h; The character the 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 ENDP
WNDPROC 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
. ELSE
Invoke Defwindowproc,hwnd,umsg,wparam,lparam
Ret
. ENDIF
XOR Eax,eax
Ret
WndProc ENDP
End Start

Analysis:

char WPARAM 20h ; the character the program receives from keyboard

This variable will hold the characters received from the keyboard. Because it is transmitted through the WPARAM variable in the window process, we simply define it as a wparam type. Since our window was not entered at the initial refresh (that is, when it was just created), we set him to spaces (20h) so that you can't see anything when it is displayed.

.ELSEIF uMsg==WM_CHAR
push wParam
pop char
invoke InvalidateRect, hWnd,NULL,TRUE

This section is used to process WM_CHAR messages. It places the received character in the variable char, then calls InvalidateRect, and InvalidateRect invalidates the client area of the window so that it emits WM_PAINT messages, and WM_PAINT messages force Windows to redraw its client area. The syntax for this function is as follows:

InvalidateRect proto hWnd:HWND,\
lpRect:DWORD,\
bErase:DWORD

Lprect is a pointer to a square structure that points to the client area where we want it to be invalid. If the value is equal to NULL, the entire client area is invalid; the Boolean berase tells Windows whether to erase the background, and if true, Windows erases the background when it calls the BeginPaint function. So here's what we do: We'll save all the data about redrawing the client area, then send a WM_PAINT message, process the segment of the message, and then redraw the client area based on the relevant data. Although this is a bit like a walk in the arch, but windows to deal with such a large group of news, there is no certain rules can not. In fact, we can get the device context handle by calling GetDC, then draw the character, and then call ReleaseDC to release the device context handle, which will undoubtedly draw the correct character in the client area. But if the WM_PAINT message is to be processed after this, the client area refreshes, and the characters we draw earlier will disappear. So in order for the characters to be displayed correctly, they must be handled in the WM_PAINT process. You can send WM_PAINT messages in this message processing.

invoke TextOut,hdc,0,0,ADDR char,1

When InvalidateRect is invoked, the WM_PAINT message is sent to the Windows window process, the program flow is transferred to the program segment that handles the WM_PAINT message, and then the beginpaint gets the handle to the device context. The textout is then invoked to output the saved key characters at the client area (0,0). This way, whatever key you press can be displayed in the upper-left corner of the client area, not only that, regardless of how you scale the window (forcing Windows to redraw its client area), characters are displayed in the correct place, so all the important drawing actions must be placed in the program segment that handles the WM_PAINT message.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.