窗体在失去焦点的时候发出 WM_WM_KILLFOCUS
窗体在获得焦点的时候会发出 WM_GETFOCUS
只有活动视窗 会受到键盘消息 受到键盘消息的窗体可以是 活动窗体 也可以是活动窗体的 子窗体 也可以是活动窗体的 衍生窗体
字元信息 例如 A按下了 既有字元信息也有按键信息
Alt + F4按下了只有按键信息 没有字元信息 系统键 带Alt的键 通常有 DefWindowProc处理
键按下 键释放非系统键 | WM_KEYDOWN | WM_KEYUP |
系统键 | WM_SYSKEYDOWN | WM_SYSKEYUP |
通常 WM_KEYDOWN和WM_KEYUP或者 (WM_SYSKEYDOWN WM_SYSKEYUP) 成对出现 我们可以调用 GetMessageTime 来获取键盘按下 和 弹起的相对时间
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
case WM_SYSCHAR:
return 0 ; //拦截系统消息
虚拟键码保存在WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN和WM_SYSKEYUP讯息的wParam参数中
十进位 十六进位 WINUSER.H识别字 必需? IBM相容键盘
1 | 01 | VK_LBUTTON | 滑鼠左键 | |
2 | 02 | VK_RBUTTON | 滑鼠右键 | |
3 | 03 | VK_CANCEL | ˇ | Ctrl-Break |
4 | 04 | VK_MBUTTON | 滑鼠中键 |
十进位 十六进位 WINUSER.H识别字 必需? IBM相容键盘
112-121 | 70-79 | VK_F1到VK_F10 | ˇ | 功能键F1到F10 |
122-135 | 7A-87 | VK_F11到VK_F24 | 功能键F11到F24 | |
144 | 90 | VK_NUMLOCK | Num Lock | |
145 | 91 | VK_SCROLL | Scroll Lock |
以上是一些虚拟键 我们可以在使用的时候参考
我们可以获取 键的状态 判断键是否被按下了 例如 :
GetKeyState()根据返回值我们可以判断一个键是 按下了还是抬起了 如果按下了 那么返回值是负值
SHORT GetKeyState( //具体看MSDN
int nVirtKey // virtual-key code //虚拟码
);
千万不要 while(GetKeyState(VK_F1)>=0) ;//那么程序会立即 卡死 。。。因为 如果键盘不按下 那么 返回值将一直为 TRUE 进入死循环 除非设置多线程
while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; }
这是WinMain中典型的讯息回圈。GetMessage函式用伫列中的下一个讯息填入msg结构的栏位。DispatchMessage以此讯息为参数呼叫适当的视窗讯息处理程式。
在这两个函式之间是TranslateMessage函式,它将按键讯息转换为字元讯息。如果讯息为WM_KEYDOWN或者WM_SYSKEYDOWN,并且按键与位移状态相组合产生一个字元,则TranslateMessage把字元讯息放入讯息伫列中。此字元讯息将是GetMessage从讯息伫列中得到的按键讯息之後的下一个讯息。
十进位 十六进位 WINUSER.H识别字 必需? IBM相容键盘8 | 08 | VK_BACK | ˇ | Backspace |
9 | 09 | VK_TAB | ˇ | Tab |
12 | 0C | VK_CLEAR | Num Lock关闭时的数字键盘5 | |
13 | 0D | VK_RETURN | ˇ | Enter (或者另一个) |
16 | 10 | VK_SHIFT | ˇ | Shift (或者另一个) |
17 | 11 | VK_CONTROL | ˇ | Ctrl (或者另一个) |
18 | 12 | VK_MENU | ˇ | Alt (或者另一个) |
19 | 13 | VK_PAUSE | Pause | |
20 | 14 | VK_CAPITAL | ˇ | Caps Lock |
27 | 1B | VK_ESCAPE | ˇ | Esc |
32 | 20 | VK_SPACE | ˇ | Spacebar |
,数字和字母的虚拟键码是ASCII码。Windows程式几乎从不使用这些虚拟键码;实际上,程式使用的是ASCII码字元的字元讯息。
十进位 十六进位 WINUSER.H识别字 必需? IBM相容键盘
96-105 | 60-69 | VK_NUMPAD0到VK_ NUMPAD9 | NumLock打开时数字键盘上的0到9 | |
106 | 6A | VK_MULTIPLY | 数字键盘上的* | |
107 | 6B | VK_ADD | 数字键盘上的+ | |
108 | 6C | VK_SEPARATOR | ||
109 | 6D | VK_SUBTRACT | 数字键盘上的- | |
110 | 6E | VK_DECIMAL | 数字键盘上的. | |
111 | 6F | VK_DIVIDE | 数字键盘上的/ |
表6-5 |
48-57 | 30-39 | 无 | ˇ | 主键盘上的0到9 |
65-90 | 41-5A | 无 | ˇ | A到Z |
同一个视窗讯息处理程式可能会用到两个视窗类别,一个用RegisterClassA注册,而另一个用RegisterClassW注册。也就是说,视窗讯息处理程式可能会获得一些ANSI字元代码讯息和一些Unicode字元代码讯息。如果您的视窗讯息处理程式需要晓得目前视窗是否处理Unicode讯息,则它可以呼叫:
fUnicode = IsWindowUnicode (hwnd) ;
如果hwnd的视窗讯息处理程式获得Unicode讯息,那么变数fUnicode将为TRUE,这表示视窗是用RegisterClassW注册的视窗类别。
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // WM_KEYDOWN
WPARAM wParam, // virtual-key code //虚拟码
LPARAM lParam // key data); //扫描码