键盘在应用程序中的应用
键盘上的键在按下或释放某键时产生一个唯一的标识值(扫描码)。
扫描码是依赖于具体设备的,为达到设备无关性的要求,往往使用与具体设备无关的虚拟码,虚拟码是由Windows系统定义的与设备无关的键的标识。设备驱动程序截取键的扫描码将其翻译成虚拟码。
按下讲盘上的按键将产生一条消息,它包含扫描码、虚拟码以及其他与击键有关的消息。
虚拟码是一种与设备无关的键盘编码,它的值存放在键盘消息的wParam参数中,用以标识哪一个键被按下或释放,最常用的虚拟码已经在Windows.h中定义。
常用的虚拟码
符号常量名称 等价的键盘键或鼠标按钮
VK_LBUTTON 鼠标左按钮
VK_RBUTTON 鼠标右按钮
VK_MBUTTON 鼠标中按钮
VK_SHIFT Shift键
VK_MENU Alt键
VK_CAPITAL Caps Lock键
VK_PRIOR Page Up键
VK_END End键
VK_LEFT 左键头键
VK_UP 上箭头键
VK_BACK 退格键
VK_TAB 制表键
VK_RETURN 回车键
VK_CONTROL Ctrl键
VK_PAUSE Pause键
VK_ESCAPE Esc键
VK_NEXT Page Down键
VK_HOME Home键
VK_RIGHT 右箭头键
VK_DOWN 下箭头键
VK_0~VK_9 0~9键
VK_A~VK_Z A~Z键
VK_0~VK_9以及VK_A~VK_Z在vc中并没有定义,需要自己定义:
//A-Z,0-9的键值,BC,VC头文件中均未定义
#define VK_A 0x41
#define VK_B 0x42
#define VK_C 0x43
#define VK_D 0x44
#define VK_E 0x45
#define VK_F 0x46
#define VK_G 0x47
#define VK_H 0x48
#define VK_I 0x49
#define VK_J 0x4A
#define VK_K 0x4B
#define VK_L 0x4C
#define VK_M 0x4D
#define VK_N 0x4E
#define VK_O 0x4F
#define VK_P 0x50
#define VK_Q 0x51
#define VK_R 0x52
#define VK_S 0x53
#define VK_T 0x54
#define VK_U 0x55
#define VK_V 0x56
#define VK_W 0x57
#define VK_X 0x58
#define VK_Y 0x59
#define VK_Z 0x5A
#define VK_0 0x30
#define VK_1 0x31
#define VK_2 0x32
#define VK_3 0x33
#define VK_4 0x34
#define VK_5 0x35
#define VK_6 0x36
#define VK_7 0x37
#define VK_8 0x38
#define VK_9 0x39
操作系统在接收到键盘输入后,把消息发送给具有“输入焦点(input focus)”的窗口。
应用程序一般有几个窗口,但当按下某一个键时,只有一个窗口能接收到该键盘消息,接收这个键盘消息的窗口称为有“输入焦点”的窗口。有“输入焦点”的窗口应是活动窗口或者活动窗口的子窗口。
窗口函数通过捕获WM_SETFOCUS和WM_KILLFOCUS消息确定当前窗口是否具有输入焦点。
WM_SETFOCUS表示窗口正在接收输入焦点;WM_KILLFOCUS表示窗口失去输入焦点。
|---字符消息
键盘消息---| |---非系统按键消息
|---按键消息---|
|---系统按键消息
按下或松开一个键时就产生了一按键消息。
一个按键的组合产生了一个可以显示的字符时,就产生了一个字符消息。
系统按键消息是由Alt键与相关输入键的组合产生的消息,这些键一般由Windows系统内部直接处理,应用程序不处理。
若应用程序处理了这些系统键消息,还要调用DefWindowsProc()函数,以便不影响系统对它们的处理。
非系统按键消息就是不使用Alt键组合的按键消息。
例如:
消息 类型 含义
WM_KEYDOWN 非系统 按下了非系统键消息
WM_KEYUP 非系统 松开了非系统键消息
WM_SYSKEYDOWN 系统 按下了系统键消息
WM_SYSKEYUP 系统 松开了系统键消息
按键消息由两个变量组成:wParam和lParam 。前者包含了识别按下的键的虚键码,后者则是个32位的变量,其具体含义如下:
0~15位 重复计数位
16~23位 OEM扫描码
24位 扩展键标志
25~28位 保留位
29位 关联码
30位 键的先前状态
31位 转换状态
在WinMain函数的消息循环中包含了TranslateMessage函数,其功能是把按键消息转化为字符消息,但只有当键盘驱动程序把键盘字符映射成ASCII码后才能产生WM_CHAR消息
字符消息分为系统与非系统。
WM_SYSKEYDOWN和WM_SYSKEYUP按键消息只能产生系统消息。
WM_KEYDOWN和WM_KEYUP的按键消息只能产生非系统消息。
消息 类型 含义
WM_CHAR 非系统 非系统字符
WM_DEADCHAR 非系统 非系统死字符
WM_SYSCHAR 系统 系统字符
WM_SYSDEADCHAR 系统 系统死字符
鼠标在应用程序中的应用
鼠标作为定位输入设备,通过鼠标单击、双击和拖动功能,用户可以很容易地操作基于Windows图形界面的应用程序。
Windows中通过光标来指示当前鼠标的位置,在Windows操作系统中预定义了几种光标,并在Windows.h头文件中加以定义,
预定义光标的常量 光标属性描述
IDC_ARROW 箭头光标
IDC_CROSS 十字光标
IDC_IBEAM I形文本光标
IDC_ICON 空图标
IDC_SIZEALL 十字箭头光标
IDC_SIZENESW 带有指向东北方和西南方箭头的光标
IDC_SIZENS 带有指向北方和南方箭头的光标
IDC_SIZENWSE 带有指向西北方和东南方箭头的光标
ISC_SIZEWE 带有指向东方和西方箭头的光标
IDC_UPARROW 垂直箭头光标
IDC_WAIT 计时光标(也称沙漏光标)
用户自定义光标
自定义光标保存在扩展名为.cur的文件中
光标名 CURSOR 光标文件(.cur)
采用自定义光标时,需在资源文件中定义光标资源。
加载光标资源(常在定义窗口类时进行)
LoadCursor(hThisInst,lpszCursorname)
例如,下面的语句为窗口类wndclass
WNDCLASS wndclass;
…
wndclass.hCursor=LoadCursor (hThislnst, IDC_WAIT);
…
此外,还可在应用程序中调用LoadCursor函数改变光标形式。
鼠标消息中lParam包含了鼠标位置(窗口的左上角为原点的坐标值),wParam包含了指示各种虚键状态的值。
lParam中低位包含鼠标位置的x坐标值,高位包含鼠标位置的y坐标。
wParam中:
值 含义
MK_CONTROL 按下键盘上的Ctrl键
MK_LBUTTON 按下了鼠标左键,等同与WM_LBUTTONDOWN
MK_MBUTTON 按下了鼠标中键,等同与WM_MBUTTONDOWN
MK_RBUTTON 按下了鼠标右键,等同与WM_RBUTTONDOWN
MK_SHIFT 按下键盘上的Shift键
对于鼠标消息的处理分2种
1.不监测Shift和Ctrl
case WM_LBUTTONDOWN: //按下鼠标左键
…
break;
case WM_LBUTTONUP: //释放鼠标左键
…
break;
…
2.要对Shift和Ctrl键进行监测
case WM_LBUTTONDOWN: //按下鼠标左键
if((wParam&MK_CONTROL)&&(wParam&MK_SHIFT))
… //Shift和Ctrl键都被按下
break;
case WM_LBUTTONUP: //释放鼠标左键
…
break;
…
鼠标双击
Windows系统默认的时间间隔为0.5秒,也可以调用SetDoubleClickTime()重新设定间隔值。
注意:要使窗口函数能接收鼠标双击产生的消息在注册窗口类时必须具有CS_DBLCLKS属性。
wndclass.style=CS_HEADRAW|CS_VERDRAW|CS_DBLCLKS;
若窗口不包含上述属性的定义,即使进行了双击操作,该窗口也只能接收到两条WM_BUTTONDOWN消息或两条WM_BUTTONUP消息。
用户区以外的地方发生的鼠标事件(菜单、滚动条工具条和标题条等处)将产生一个非用户区鼠标消息,该消息不由应用程序处理而是送往函数DefWindowProc() 。
由于鼠标移动的随机性,如果要使某一个窗口能不间断地捕获鼠标消息,就必须对鼠标加以捕获,可调用调用SetCapture()函数。
一旦从窗口捕获了鼠标,系统的键盘功能就暂时失效,其它窗口也无法得到鼠标消息。
SetCapture(hWnd):可以向句柄为hWnd的窗口发送所有的鼠标消息
当该窗口不再需要捕获鼠标消息时,应及时调用ReleaseCapture()以释放鼠标,否则,其他窗口无法接收鼠标信息。