第六章 键盘消息
来源:互联网 发布:小学英语课文朗读软件 编辑:程序博客网 时间:2024/06/02 09:23
窗口过程通过捕获WM_SETFOCUS 和 WM_KILLFOCUS消息来确定自己的窗口是否具有输入焦点。
WM_SETFOCUS 表明窗口正在接受输入焦点。
WM_KILLFOCUS 表明窗口正在失去输入焦点。
应用程序从Windows接收的关于键盘事件的消息可分为击键和字符两种。
击键:如键盘上的仅有一个键标“A”。按下此键是一次击键,释放此键也认为是一次击键。
字符:键盘也是能产生可显示字符或者控制字符的输入设备。“A”键能产生一些不同的字符,这取决于同Ctrl、Shift、Caps Lock键的组合。
通常地,此字符为小写字母“a”。如果Shift键被按下或者Caps Lock被锁定,此字符就为大写字母“A”。如果Ctrl键被按下,此字符就是Ctrl + A
对产生可显示字符的击键组合,Windows在发送击键消息的同时还发送字符消息。
有些键不产生字符,如Shift键、功能键、光标移动键和特殊字符键。对于这些键,Windows只产生击键消息。
击键消息
键按下键释放非系统键击
WM_KEYDOWNWM_KEYUP系统键击WM_SYSKEYDOWNWM_SYSYKEYUP通常键按下消息和键释放消息是成对出现的。像所有的队列消息一样,击键消息可被实时追踪的。通过调用GetMessageTime函数,得到键被按下释放的相对时间。
系统键击 和 非系统键击
WM_SYSKEYDOWN 和 WM_SYSYKEYUP 中“SYS”代表系统,它表明该击键对Windows比对Windows应用程序更加重要。
当输入键和Alt 键组合时通常产生的是WM_SYSYKEYDOWN 和 WM_SYSYKEYUP 消息。这些按键调用程序菜单或系统菜单选项,被用来实现系统功能如转换活动窗口,
或作为系统快捷键。应用程序通常忽略WM_SYSYKEYDOWN 和 WM_SYSYKEYUP消息,将它们交给DefWindowProc函数完成默认处理。
因为Windows关注所有的Alt键功能逻辑,应用程序就不必处理这些消息。
不与Alt组合时按下和释放键会产生WM_KEYDOWN 和 WM_KEYUP消息。应用程序可以使用或者丢弃这些击键消息。Windows也不处理它们。
虚拟键代码
对于所有四类击键消息,wParam是虚拟键代码,用于标识哪个键被按下或被释放,而lParam包含属于本次击键的一些其他数据。
虚拟键代码存储在 WM_KEYDOWN 、WM_KEYUP 、 WM_SYSYKEYDOWN、 WM_SYSYKEYUP消息的wParam参数中。此代码确定哪个键被按下或被释放。
经常使用的大多数键代码命名是以 VK_ 开头的,它定义在WINUSER.H头文件中。
lparam消息
在四个击键消息中,wParam消息参数包含了虚拟键代码,lParam消息参数包含了帮助理解击键的其他有用的信息。
32位的lParam消息被分成了6个字段,
重复计数:是消息所表示的击键的数目。大多数情况下,它被设置为1.
OEM扫描码:是键盘硬件产生的代码。Windows通常几乎忽略OEM扫描码,除非是它要依赖于键盘上键的分布。
扩展键标记:Windows通常忽略扩展键标记。
内容代码:如果击键的同时也按下了Alt键,则内容代码为 1 。 ~~
键的先前状态:如果键以前是释放状态的,则键的先前状态为 0. 而如果键以前是按下的,则键的先前状态为 1.
WM_KEYUP 和 WM_SYSYKEYUP消息的此字段总是 1.
但WM_SYSKEYDOWN 、WM_KEYDOWN消息的此字段可能为0或1.该位为1表明,消息为重复击键产生的第二个或后续发出的消息。
转换状态:如果键正在被按下,转换状态为0;如果键正在被释放转换状态为1.
WM_SYSKEYDOWN 、WM_KEYDOWN消息的此字段设置为0,WM_KEYUP 和 WM_SYSYKEYUP消息的此字段设置为1
程序实例:
如果单独的处理WM_KEYDOWN逻辑,这样不管任何时候想修改滚动条逻辑,就不得不在WM_KEYDOWN消息上做同样的改变。
我们可以通过给窗口过程发送假冒的消息欺骗WndProc函数,使它认为收到了滚动条消息。Windows允许你这样做。
SendMessage函数携带了传给窗口过程的参数:
SendMessage(hwnd, message, wParam, lParam);
下面是用光标移动键实现滚动条逻辑代码:
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){static int cxChar,cyChar,cxCaps,cyClient;int i, y, iVertPos, iPaintBeg, iPaintEnd;char szBuffer[10];HDChdc;TEXTMETRICtm;PAINTSTRUCT ps;SCROLLINFOsi;switch (message){case WM_CREATE:hdc = GetDC(hwnd);GetTextMetrics(hdc,&tm);cxChar = tm.tmAveCharWidth;cyChar = tm.tmHeight + tm.tmExternalLeading;cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;ReleaseDC(hwnd,hdc);return 0;case WM_SIZE:cyClient= HIWORD(lParam);si.cbSize= sizeof(si);si.fMask= SIF_PAGE|SIF_RANGE;si.nMin= 0;si.nMax= NUMLINES - 1;si.nPage= cyClient / cyChar;SetScrollInfo(hwnd,SB_VERT,&si,TRUE);return 0;case WM_VSCROLL:si.cbSize= sizeof(si);si.fMask= SIF_ALL;GetScrollInfo(hwnd,SB_VERT,&si);iVertPos = si.nPos;switch (LOWORD(wParam)){case SB_TOP:si.nPos = si.nMin;break;case SB_BOTTOM:si.nPos = si.nMax;break;case SB_LINEUP:si.nPos -= 1;break;case SB_LINEDOWN:si.nPos += 1;break;case SB_PAGEUP:si.nPos -= si.nPage;break;case SB_PAGEDOWN:si.nPos+= si.nPage;break;case SB_THUMBPOSITION:si.nPos = si.nTrackPos;break;default:break;}si.fMask= SIF_POS;SetScrollInfo(hwnd,SB_VERT,&si,TRUE);GetScrollInfo(hwnd,SB_VERT,&si);if(si.nPos != iVertPos){ScrollWindow(hwnd, 0, cyChar*(iVertPos - si.nPos),NULL,NULL);UpdateWindow(hwnd);}return 0;case WM_KEYDOWN:switch (wParam){case VK_HOME:SendMessage(hwnd,WM_VSCROLL,SB_TOP,0);break;case VK_END:SendMessage(hwnd,WM_VSCROLL,SB_BOTTOM,0);break;case VK_PRIOR:SendMessage(hwnd,WM_VSCROLL,SB_PAGEUP,0);break;case VK_NEXT:SendMessage(hwnd,WM_VSCROLL,SB_PAGEDOWN,0);break;case VK_UP:SendMessage(hwnd,WM_VSCROLL,SB_LINEUP,0);break;case VK_DOWN:SendMessage(hwnd,WM_VSCROLL,SB_LINEDOWN,0);break;case VK_LEFT:SendMessage(hwnd,WM_VSCROLL,SB_PAGEUP,0);break;case VK_RIGHT:SendMessage(hwnd,WM_VSCROLL,SB_PAGEDOWN,0);break;}return 0;case WM_PAINT:hdc= BeginPaint(hwnd,&ps);si.cbSize= sizeof(si);si.fMask= SIF_POS;GetScrollInfo(hwnd,SB_VERT,&si);iVertPos= si.nPos;iPaintBeg = max(0, iVertPos + ps.rcPaint.top / cyChar);iPaintEnd = min(NUMLINES - 1, iVertPos + ps.rcPaint.bottom / cyChar);for (i = iPaintBeg; i <= iPaintEnd; i++){y = cyChar* (i - iVertPos);TextOut(hdc,0,y,sysmetrics[i].szLabel,lstrlen(sysmetrics[i].szLabel));TextOut(hdc,22*cxCaps,y,sysmetrics[i].szDesc,lstrlen(sysmetrics[i].szDesc));SetTextAlign(hdc,TA_TOP|TA_RIGHT);TextOut(hdc,22*cxCaps + 40*cxChar,y,szBuffer,wsprintf(szBuffer,TEXT("%5d"),GetSystemMetrics(sysmetrics[i].iIndex)));SetTextAlign(hdc,TA_TOP|TA_LEFT);}EndPaint(hwnd,&ps);return 0;case WM_DESTROY:PostQuitMessage(0);return 0;}return DefWindowProc(hwnd,message,wParam,lParam);}
字符消息:
四类字符消息
字符死字符非系统字符WM_CHARWM_DEADCHAR系统字符WM_SYSCHARWM_SYSDEADCHARWM_CHAR 、 WM_DEADCHAR 来自于 WM_KEYDOWN消息
WM_SYSCHAR、WM_SYSDEADCHAR来自于 WM_SYSKEYDOWN消息
Windows通常只处理 WM_CHAR消息,而忽略其它三个。
typedef struct tagMSG { HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; POINT pt; } MSG, *PMSG;
- 第六章 键盘消息
- 第六章 鼠标消息与键盘消息
- 第六章 6-1 键盘消息
- 第六章 键盘part1
- 第六章 键盘part2
- windows程序设计第六章 键盘
- VC++60 第六章 键盘事件
- 键盘消息
- 键盘消息
- 键盘消息
- 键盘消息
- 悟透delphi 第六章事件与消息
- 悟透delphi 第六章 事件与消息
- UNPv2第六章:System V 消息队列
- 鼠标消息与键盘消息
- 鼠标消息与键盘消息
- 第六课:键盘和鼠标
- 得到键盘消息
- 尊重原创,请保证您的文章为原创作品
- LA5904 Please, go first
- 关于链表的升序排列问题
- 在linux/unix上分析程序日志的技巧
- java_IO流
- 第六章 键盘消息
- PHPvod在线视频网站的搭建
- 2.策略模式
- java_GUI
- [Leetcode] Reverse Words in a String
- python进阶五_类(一)
- NYOJ 228 士兵杀敌 五
- 四组件之Activity
- linux整理之压缩解压缩、加密、分卷