09 Windows编程——键盘消息

焦点窗口:接收到这个键盘事件的窗口称为有输入焦点的窗口。具有输入焦点的窗口要么是活动窗口,要么是活动窗口的子孙窗口。

活动窗口:活动窗口通常是很好鉴别的。它总是最上层的窗口——也就是说,它的父窗口句柄是NULL。

系统消息队列 & 应用程序消息队列

当用户按下和释放键盘上的一个键时,Windows和键盘设备驱动程序将硬件扫描码转换为格式化后的消息。但是,这些消息并不立即被放入应用程序消息队列,而是由Wimdows把这些消息存储在系统消息队列中。系统消息队列是一个单独的消息队列,它被 Windows用来初步存储用户从键盘和鼠标输入的消息。仅当Windows应用程序完成了对前一个用户输入消息的处理后,Windows才从系统消息队列中取出下一条消息,并把它放入应用程序消息队列。

应用程序从Windows接收的关于键盘事件的消息可分为击键消息和字符消息两种。对产生可显示字符的击键组合,Windows在发送击键消息的同时还发送字符消息。有些键不产生字符,如Shift键、功能键、光标移动键和特殊字符键(如Insert键和Delete键)。对于这些键,Windows只产生击键消息。

字符消息

WM_CHAR,WM_SYSCHAR,WM_DEADCHAR,WM_SYSDEADCHAR

wParam就是按键字符,TCHAR(wParam)就可以获得这个字符,不要去区分这个字符是ASCII字符或者UNICODE字符,因为TCHAR数据类型已经帮你区分好了!

一个按键会产生以下4个消息:WM_KEYDOWN,WM_CHAR,WM_KEYUP,WM_DEADCHAR 4个消息。

击键消息

通常键按下消息和键释放消息是成对出现的。但是如果你按下一个键不放时,则被认为发生了一次连续按键(自动重复)行为,Windows将发送给窗口过程一连串的WM KEYDOWN(或WMSYSKEYDOWN)消息。当此键最终被释放时,Windows发送给窗口过程一个WMKEYUP(或WMSYSKEYUP)消息。像所有的队列消息一样,击键消息是可被实时追踪的。你能通过调用GetMessageTime函数,得到键被按下或释放的相对时间。

系统击键

表明该击键对Windows比对Windows应用程序更加重要。当输入键和Alt键组合时通常产生的是WM SYSKEYDOWN和WMSYSKEYUP消息。应用程序通常忽略WMSYSKEYUP和WMSYSKEYDOWN消息,将它们交付给DefWindowProc函数完成默认处理。因为Windows关注所有的Alt键功能逻辑,应用程序就不必处理这些消息。如果你非要处理这些消息,则在处理完毕后,仍然需要发送这些消息给DefWindowProc函数,以便不影响Windows对它的处理。

对所有四类击键消息,wParam是虚拟键代码,用于标识哪个键被按下或被释放,而IParam包含属于本次击键的一些其他数据。大多数虚拟键代码命名是以VK_开头的,它定义在WINUSER日头文件中。lParam消息参数包含了帮助理解击键的其他有用信息。32位的lParam消息被分成了6个字段,如图所示。

 1 #include<Windows.h>
 2 #include<WinUser.h>
 3 #include<tchar.h>
 4 #include<stdio.h>
 5 
 6 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
 7 
 8 int WinMain(HINSTANCE hInst, HINSTANCE tmp, LPSTR szCmd, int nShow)
 9 {
10     WNDCLASS WndClass;
11     TCHAR* ClassName = TEXT("MyClass");
12     HWND hwnd;
13     MSG msg;
14 
15     WndClass.cbClsExtra = 0;
16     WndClass.cbWndExtra = 0;
17     WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
18     WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
19     WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
20     WndClass.hInstance = hInst;
21     WndClass.lpfnWndProc = WindProc;
22     WndClass.lpszClassName = ClassName;
23     WndClass.lpszMenuName = NULL;
24     WndClass.style = CS_VREDRAW | CS_HREDRAW;
25 
26     RegisterClass(&WndClass);
27     hwnd = CreateWindow(ClassName, TEXT("Hello"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300, NULL, NULL, hInst, NULL);
28     ShowWindow(hwnd, nShow);
29     UpdateWindow(hwnd);
30 
31     while (GetMessage(&msg, NULL, 0, 0))
32     {
33         TranslateMessage(&msg);
34         DispatchMessage(&msg);
35     }
36     return 0;
37 }
38 
39 
40 
41 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
42 {
43     HDC hdc;
44     PAINTSTRUCT pt;
45     static int cx, cy;
46     static int cyChar;
47     static int iLine;
48     static int iMaxLine;
49     static TCHAR cBuf[1024] = { "Please Press Key:" };
50     TEXTMETRIC tm;
51     RECT rect;
52     switch (message)
53     {
54     case WM_CREATE:
55         hdc = GetDC(hwnd);
56         GetTextMetrics(hdc, &tm);
57         cyChar = tm.tmHeight;
58         ReleaseDC(hwnd, hdc);
59         iLine = 0;
60         iMaxLine = 0;
61         return 0;
62     case WM_SIZE:
63         cx = LOWORD(lParam);
64         cy = HIWORD(lParam);
65         iMaxLine = cy / cyChar-1;
66         iLine = iLine > iMaxLine ? iMaxLine : iLine;
67         return 0;
68     case WM_PAINT:
69         hdc = BeginPaint(hwnd, &pt);
70         TextOut(hdc, pt.rcPaint.left, pt.rcPaint.top, cBuf, _tcslen(cBuf));
71         EndPaint(hwnd, &pt);
72         iLine++;
73         return 0;
74     case WM_CHAR:
75         iLine = iLine > iMaxLine ? iMaxLine : iLine;
76         _stprintf(cBuf, TEXT("lParam=0x%X   wParam=0x%X  : %c"), lParam, wParam,wParam);
77         rect.left = 0;
78         rect.top = iLine * cyChar;
79         rect.right = cx;
80         rect.bottom = (iLine + 1)*cyChar;
81         InvalidateRect(hwnd, &rect, TRUE);
82         return 0;
83     case WM_DESTROY:
84         PostQuitMessage(0);
85         return 0;
86     default:
87         break;
88     }
89 
90     return DefWindowProc(hwnd, message, wParam, lParam);
91 }
View Code
原文地址:https://www.cnblogs.com/kelamoyujuzhen/p/9320644.html