ICZelion TUT6

zhaozj2021-02-11  215

Theory: Since normally there's only one keyboard in each PC, all running Windows programs must share it between them Windows is responsible for sending the key strokes to the window which has the input focus..

Although there may be several windows on the screen, only one of them has the input focus. The window which has input focus is the only one which can receive key strokes. You can differentiate the window which has input focus from other windows by looking at The title bar. The title bar of the window which has input focus is used.

Actually, there are two main types of keyboard messages, depending on your view of the keyboard. You can view a keyboard as a collection of keys. In this case, if you press a key, Windows sends a WM_KEYDOWN message to the window which has input focus, notifying that a key is pressed. When you release the key, Windows sends a WM_KEYUP message. you treat a key as a button. Another way to look at the keyboard is that it's a character input device. When you press "a "key, Windows sends a WM_CHAR message to the window which has input focus, telling it that the user sends" a "character to it. In fact, Windows sends WM_KEYDOWN and WM_KEYUP messages to the window which has input focus and those messages will be translated to WM_CHAR messages by TranslateMessage call. The window procedure may decide to process all three messages or only the messages it's interested in. Most of the time, you can ignore WM_KEYDOWN and WM_KEYUP since TranslateMessage function call in the message loop translate WM_ Keydown and WM_Keyup Messages to WM_CHAR Messages. We will focus on wm_char in this tutorial.

EXAMPLE:

.386

.Model flat, stdcall

Option CaseMAP: NONE

WinMain proto: DWORD,: DWORD,: DWORD,: DWORDinclude /masm32/include/windows.inc include /masm32/include/user32.inc include /masm32/include/kernel32.inc include /masm32/include/gdi32.inc includelib / Masm32 / lib / user32.lib incrudelib /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 WNDPRE END STARTANALSIS:

Char WPARAM 20H; The Character The Program Receives from Keyboard

This is the variable that will store the character received from the keyboard. Since the character is sent in WPARAM of the window procedure, we define the variable as type WPARAM for simplicity. The initial value is 20h or the space since when our window refreshes its Client Area The First Time, There Is No Character Input. So We Want To Display Space Instead.

.ELSEIF UMSG == WM_CHAR PUSH WPARAM POP Char Invoke InvalidateRect, HWND, NULL, TRUE

This is added in the window procedure to handle the WM_CHAR message. It just puts the character into the variable named "char" and then calls InvalidateRect. InvalidateRect makes the specified rectangle in the client area invalid which forces Windows to send WM_PAINT message to the window Procedure. ITS Syntax Is as Follows:

InvalidateRect Proto Hwnd: HWnd, / LPRECT: DWORD, / BERASE: DWORD

lpRect is a pointer to the rectagle in the client area that we want to declare invalid. If this parameter is null, the entire client area will be marked as invalid. bErase is a flag telling Windows if it needs to erase the background. If this flag is TRUE, then Windows will erase the backgroud of the invalid rectangle when BeginPaint is called.So the strategy we used here is that: we store all necessary information relating to painting the client area and generate WM_PAINT message to paint the client area of. course, the codes in WM_PAINT section must know beforehand what's expected of them. This seems a roundabout way of doing things but it's the way of Windows. Actually we can paint the client area during processing WM_CHAR message by calling GetDC and ReleaseDC pair. There is no problem there. But the fun begins when our window needs to repaint its client area. Since the codes that paint the character are in WM_CHAR section, the window procedure will not be able to repaint our chara . Cter in the client area So the bottom line is: put all necessary data and codes that do painting in WM_PAINT You can send WM_PAINT message from anywhere in your code anytime you want to repaint the client area..

Invoke TextOut, HDC, 0, 0, AddR Char, 1

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

New Post(0)