《应用程序对键盘与鼠标的响应.ppt》由会员分享,可在线阅读,更多相关《应用程序对键盘与鼠标的响应.ppt(37页珍藏版)》请在三一办公上搜索。
1、第6章 Windows应用程序对键盘与鼠标的响应,扫描码是依赖于具体设备的,为达到设备无关性的要求,往往使用与具体设备无关的虚拟码,虚拟码是由Windows系统定义的与设备无关的键的标识,6.1 键盘在应用程序中的应用,虚拟码是一种与设备无关的键盘编码,它的值存放在键盘消息的wParam参数中,用以标识哪一个键被按下或释放,最常用的虚拟码已经在Windows.h中定义。,应用程序一般有几个窗口,但当按下某一个键时,只有一个窗口能接收到该键盘消息,接收这个键盘消息的窗口称为有“输入焦点”的窗口,有“输入焦点”的窗口应是活动窗口或者活动窗口的子窗口,键盘消息,按键消息,字符消息,按下或松开一个键时
2、就产生了一按键消息,一个按键的组合产生了一个可以显示的字符时,就产生了一个字符消息,系统按键消息,非系统按键消息,Alt键与相关输入键的组合产生的消息,这些键一般由Windows系统内部直接处理,应用程序不处理,若应用程序处理了这些系统键消息,还要调用DefWindowsProc()函数,以便不影响系统对它们的处理,不使用Alt键组合的的按键消息,32位的变量,包含了识别按下的键的虚键码,在WinMain函数的消息循环中包含了TranslateMessage函数,其功能是把按键消息转化为字符消息,但只有当键盘驱动程序把键盘字符映射成ASCII码后才能产生WM_CHAR消息。,【例6-1】设计一
3、个窗口,在该窗口中练习键盘的响应,要求如下:(1)单击键盘上的向上箭头时,窗口中显示“You had hitted the up key”(2)单击键时,窗口中显示“You had hitted the SHIFT key”(3)单击键时,窗口中显示“You had hitted the CTRL key”(4)单击键时,窗口中显示“You had hitted the CTRL A key”(5)单击键时,窗口中显示“You had hitted the SHIFT B key”,long WINAPI WndProc(HWND hWnd,UINT iMessage,UINT wParam,
4、LONG lParam)HDC hDC;/定义设备环境句柄 PAINTSTRUCT ps;/定义包含绘图信息的结构体变量 HPEN hPen;/定义画笔句柄 HBRUSH hBrush;/定义画刷句柄,/以下定义输出的字符串 static char cUp=You had hitted the UP key;static char cCtrl=You had hitted the Ctrl key;static char cShift=You had hitted the SHIFT key;static char cCtrl_A=You had hitted the CTRL A key;s
5、tatic char cShift_B=You had hitted the SHIFT B key;,/下面定义并初始化按键标志变量 static BOOL nUpKeyDown=FALSE,nShiftKeyDown=FALSE,nCtrlKeyDown=FALSE,nCtrlAKeyDown=FALSE,nShiftBKeyDown=FALSE;,switch(iMessage)case WM_KEYDOWN:switch(wParam)case VK_UP:/当按上箭头键时,变量置为真nUpKeyDown=TRUE;break;case VK_SHIFT:/当按Shift键时,变量置为
6、真nShiftKeyDown=TRUE;break;case VK_CONTROL:/当按Control键时,变量置为真nCtrlKeyDown=TRUE;break;default:break;break;case WM_KEYUP:InvalidateRect(hWnd,NULL,FALSE);break;,case WM_CHAR:if(wParam=(65,case WM_PAINT:/处理绘图消息.hDC=BeginPaint(hWnd,/设置字体颜色为红色。,/输出信息。if(nUpKeyDown=TRUE)Rectangle(hDC,0,0,300,200);TextOut(hD
7、C,0,0,cUp,strlen(cUp);nUpKeyDown=FALSE;,else if(nCtrlAKeyDown=TRUE)Rectangle(hDC,0,0,300,200);TextOut(hDC,0,100,cCtrl_A,strlen(cCtrl_A);nCtrlAKeyDown=FALSE;nCtrlKeyDown=FALSE;,else if(nCtrlAKeyDown=TRUE)else if(nCtrlKeyDown=TRUE,else if(nShiftBKeyDown=TRUE)Rectangle(hDC,0,0,300,200);TextOut(hDC,0,0,
8、cShift_B,strlen(cShift_B);nShiftBKeyDown=FALSE;nShiftKeyDown=FALSE;,else if(nShiftBKeyDown=FALSEelse;,/删除画笔和画刷DeleteObject(hPen);DeleteObject(hBrush);EndPaint(hWnd,case WM_DESTROY:PostQuitMessage(0);return 0;default:return(DefWindowProc(hWnd,iMessage,wParam,lParam);return 0;,程序中缓冲区大小只设30个字符,当缓冲区满时若再
9、输入任何字符,就出现(1)号错误提示,用户按下左箭头键直至光标到达本行起始位置时,就无法再往左移动,则出现(2)号错误信息,若此时您按下Esc键,就出现(3)号错误提示信息,若当前光标位置处于本行的起始位置,此时按下回退键(BackSpace),则出现编号为(4)的错误提示信息,若字符缓冲区中已没有任何字符,此时按下了Delete键,则出现(5)号错误提示信息,【例6-2本例演示键盘输入时所产生的消息序列并在窗口的客户区显示对应的字符,6.2 键盘操作应用举例,#include#include#includevoid WINAPI CaretPos(int*xCaret,int*yCaret)
10、;long WINAPI WndProc(HWND hWnd,UINT iMessage,UINT wParam,LONG lParam);BOOL InitWindowsClass(HINSTANCE hInstance);BOOL InitWindows(HINSTANCE hInstance,int nCmdShow);HWND hWndMain;,long WINAPI WndProc(HWND hWnd,UINT iMessage,UINT wParam,LONG lParam)#define BufSize 30/设置存放字符的缓冲区大小 static char cCharBufB
11、ufSize;/设置静态字符数组,/存放输入的字符,字符个数不能超出缓冲区大小 static int nNumChar=0;/现有字符个数 static int nArrayPos=0;/字符的位置 static int nLnHeight;static int nCharWidth;static int xCaret,yCaret;int x;HDC hDC;TEXTMETRIC tm;PAINTSTRUCT PtStr;/定义指向包含绘图信息的结构体变量,switch(iMessage)/处理消息case WM_CHAR:/遇到非系统字符所作的处理 if(wParam=VK_BACK)/处
12、理遇到回退键的消息 if(nArrayPos=0)/若已在一行文字的开始处,则提示不能回退 MessageBox(hWnd,“当前位置是文本的起始位置,不能回退,NULL,MB_OK);else nArrayPos=nArrayPos-1;/按一次回退键就回退一字符位置 CaretPos(,if(wParam=VK_ESCAPE)/处理按下Escape键消息 MessageBox(hWnd,“您现在不能按ESC键,请继续其它操作,NULL,MB_OK);break;,if(nNumChar=BufSize)/如写入的字符数超过缓冲区大小,则报警 MessageBox(hWnd,“缓冲区已满,不
13、能再输入字符了n 若需要删除字符,请用BackSpace键,NULL,MB_OK);break;for(x=nNumChar;xnArrayPos;x=x-1)cCharBufx=cCharBufx-1;cCharBufnArrayPos=(unsigned char)wParam;nArrayPos=nArrayPos+1;nNumChar=nNumChar+1;CaretPos(,case WM_CREATE:/处理窗口创建消息hDC=GetDC(hWnd);GetTextMetrics(hDC,case WM_SETFOCUS:/处理活动焦点消息 CreateCaret(hWnd,0,0
14、,nLnHeight);CaretPos(,case WM_KILLFOCUS:/处理失去焦点消息 DestroyCaret();break;,case WM_KEYDOWN:/处理按下键消息 switch(wParam)case VK_END:/处理按下键为End时的消息nArrayPos=nNumChar;/输入位置从本行的末尾开始CaretPos(,case VK_DELETE:/处理按下键为Delete时的消息 if(nArrayPos=nNumChar)/输入位置处于本行的末尾 MessageBox(hWnd,缓冲区已空,没有字符可供删除,NULL,MB_OK);else for(x
15、=nArrayPos;xnNumChar;x=x+1)cCharBufx=cCharBufx+1;/每删一字符,缓冲区中总字符数减1 nNumChar=nNumChar-1;InvalidateRect(hWnd,NULL,TRUE);/用户区刷新 break;,case VK_LEFT:/处理按下左方向键时的消息 if(nArrayPos0)nArrayPos=nArrayPos-1;/当前输入位置往前移一个位 置,再输入字符时,等于插入字符 CaretPos(,case VK_RIGHT:/处理按下右方向键时的消息 if(nArrayPosnNumChar)/如果当前位置没有到缓冲区的最后
16、位置,还能向右移动 nArrayPos=nArrayPos+1;CaretPos(,case WM_PAINT:/处理重画消息 hDC=BeginPaint(hWnd,case WM_DESTROY:PostQuitMessage(0);break;default:return(DefWindowProc(hWnd,iMessage,wParam,lParam);return 0;,BOOL InitWindowsClass(HINSTANCE hInstance)/初始化窗口类WNDCLASS WndClass;WndClass.cbClsExtra=0;.WndClass.style=CS
17、_HREDRAW|CS_VREDRAW;return RegisterClass(,BOOL InitWindows(HINSTANCE hInstance,int nCmdShow)/初始化窗口 HWND hWnd;hWnd=CreateWindow(.);if(!hWnd)return FALSE;hWndMain=hWnd;ShowWindow(hWnd,nCmdShow);/显示窗口UpdateWindow(hWnd);/绘制用户区return TRUE;,void WINAPI CaretPos(int*xCaret,int*yCaret)/处理插字符位置的函数 SetCaretPo
18、s(*xCaret,*yCaret);/设置插字符位置坐标,鼠标作为定位输入设备,通过鼠标单击、双击和拖动功能,用户可以很容易地操作基于Windows图形界面的应用程序。,Windows中通过光标来指示当前鼠标的位置,在Windows操作系统中预定义了几种光标,并在Windows.h头文件中加以定义。,6.3 鼠标在应用程序中的应用,例如,下面的语句为窗口类wndclassWNDCLASS wndclass;wndclass.hCursor=LoadCursor(hThislnst,IDC_WAIT);此外,还可在应用程序中调用LoadCursor函数改变光标形式。,相当于窗口的左上角为原点的
19、坐标值,对于鼠标消息的处理,Windows系统默认的时间间隔为0.5秒,也可以调用SetDoubleClickTime()重新设定间隔值,若窗口不包含上述属性的定义,即使进行了双击操作,该窗口也只能接收到两条WM_BUTTONDOWN消息或两条WN_BUTTONUP消息。,鼠标双击,wndclass.style=CS_HEADRAW|CS_VERDRAW|CS_DBLCLKS;,要使窗口函数能接收鼠标双击产生的消息在注册窗口类时必须具有CS_DBLCLKS属性,由于鼠标移动的随机性,如果要使某一个窗口能不间断地捕获鼠标消息,就必须对鼠标加以捕获,SetCapture(hWnd):可以向句柄为h
20、Wnd的窗口发送所有的鼠标消息,调用SetCapture()函数,一旦从窗口捕获了鼠标,系统的键盘功能就暂时失效,其它窗口也无法得到鼠标消息,当该窗口不再需要捕获鼠标消息时,应及时调用ReleaseCapture()以释放鼠标,否则,其他窗口无法接收鼠标信息。,菜单、滚动条工具条和标题条等处,【例6-2】鼠标输入示范程序,本例介绍如何响应鼠标信息、并改变光标形状等用法,用户在窗口的不同区域移动鼠标时,光标将显示如下图所标识的不同箭头的形状,6.4 鼠标应用程序实例,#include#include LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM
21、);int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInst,LPSTR lpszCmdLine,int nCmdShow)HWND hwnd;MSG Msg;WNDCLASS wndclass;char lpszClassName=窗口;char lpszTitle=My_Windows;wndclass.style=0;wndclass.lpszClassName=lpszClassName;if(!RegisterClass(,LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPA
22、RAM wParam,LPARAM lParam)PAINTSTRUCT ps;HDC hdc;TEXTMETRIC tm;HBRUSH hbrush;HPEN hpen;HCURSOR hcursor;char str15;static int x,y;switch(message)case WM_MOUSEMOVE:x=LOWORD(lParam);y=HIWORD(lParam);if(x50,if(x150,if(x250/西南-东北光标,if(x50/I字型光标,if(x50/东西向箭头,if(x150/沙漏光标,if(x250/向上箭头光标,if(x150/西北-东南箭头,if(x
23、250/南北向箭头,hdc=GetDC(hwnd);GetTextMetrics(hdc,case WM_PAINT:hdc=BeginPaint(hwnd,【6-3】编写一个鼠标应用程序,按下鼠标左键在窗口中移动时,将按下左键时所在点和当前点所形成的矩形涂成灰色,此时光标为十字型。当抬起鼠标左键时,将前面所绘制度矩形拉伸到整个窗口,拉伸过程中将光标设置为沙漏型。然后,若双击鼠标的左键,则灰色消失,窗口恢复到初始状态。,void InvertBlock(HWND hwnd,POINT ptBeg,POINT ptEnd)HDC hdc;hdc=CreateDC(DISPLAY,NULL,NUL
24、L,NULL);ClientToScreen(hwnd,LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)static BOOL operate=FALSE,ready=TRUE;static POINT BeginP,EndP;static RECT rect=0,0,0,0;HDC hdc;PAINTSTRUCT PtStr;HBRUSH hBrush;,switch(message)case WM_LBUTTONDOWN:if(!operate),case WM_MOUSEMOVE:if
25、(operate)EndP.x=LOWORD(lParam);EndP.y=HIWORD(lParam);rect.left=BeginP.xEndP.x?BeginP.x:EndP.x;rect.top=BeginP.yEndP.y?BeginP.y:EndP.y;SetCursor(LoadCursor(NULL,IDC_WAIT);/载入沙漏光标 InvalidateRect(hwnd,NULL,TRUE);return 0;,case WM_PAINT:if(ready=FALSE)hdc=BeginPaint(hwnd,case WM_LBUTTONUP:if(operate)operate=FALSE;SetCursor(LoadCursor(NULL,IDC_WAIT);GetClientRect(hwnd,case WM_LBUTTONDBLCLK:if(ready=FALSE)ready=TRUE;InvalidateRect(hwnd,NULL,TRUE);return 0;case WM_DESTROY:PostQuitMessage(0);return 0;return DefWindowProc(hwnd,message,wParam,lParam);,
链接地址:https://www.31ppt.com/p-5764461.html