MFC Windows 程序设计 第三章 鼠标与键盘

来源:互联网 发布:海迅开料软件 编辑:程序博客网 时间:2024/05/17 07:30
第三章 鼠标与键盘

1、windows系统处理鼠标和键盘消息过程:设备驱动程序处理鼠标和键盘中断并将结果事件放入到一个系统范围的原始输入队列中,操作系统有一个专门的线程来监视原始输入队列,他把每个从队列中出来的消息转移到适当的线程消息队列中(32位应用程序每个线程都有自己的线程消息队列(MFC中UI线程有,而工作者线程没有))。
2、客户区鼠标消息处理函数原型:afx_msg void OnMsgName(UINT nFlags,CPoint point),其中point是相对于客户区左上角的坐标,可以使用CDC:DPtoLP转换成逻辑坐标,nFlags包含消息生成时鼠标键以及Shift、Ctrl键的情况、MK_LBUTTON、MK_CONTROL、MK_SHIFT,通过&与的方式来判断,鼠标的keydown和kewup不一定是一对,可能在界面按下按键,而在界面外进行释放,如果要形成一对,则在mousedown时Wnd::SetCapture(),在keyup时使用“if (GetCapture == this) ::ReseaseCapture”,
    非客户区鼠标消息原型:afx_msg void OnMsgName(UINT nHitTest,CPoint point),这里的point指的是屏幕坐标,而非客户区坐标,可以使用CWnd::ScreenToClient转换为客户区坐标,nHitTest包含表示窗口非客户区事件发生地方的命中测试码,常用的有:HTCAPTION(标题栏)、HTCLOSE(关闭按钮)、HTMENU(菜单)等。
   鼠标消息分客户区消息和非客户区消息(NC),如WM_LBUTTONDOWN、WM_NCLBUTTONDOWN,分类如下:
   WM_XBTUUONDOWN、WM_XBUTTONUP、WM_XBUTTONDBLCLK,X只的是L(左)、R(右)、M(中)、NCL(非客户左)、NLR、NCM,另外还有一个WM_MOUSEMOVE、WM_NCMOUSEMOVE
   其他的鼠标消息:WM_NCHITTEST(Windows通过此消息产生客户区、非客户区鼠标消息)、WM_MOUSELEAVE(离开)、WM_MOUSEHOVER(停留)、WM_MOUSEWHEEL(滚轮,用来处理鼠标滚动时的操作)
3、从CWnd类派生自己的类,需要使用AfxRegisterWndClass来注册窗口,使用CWnd::CreateEx来创建窗口,使用::RegisterClass和AfxRegisterClass注册窗口时,必须初始化WNDCLASS结构中的每个字段.
    WNDCLASS样式标志:CS_DBLCLKS、CS_HREDRAW、CS_VREDRAW,光标(LoadStandardCursor):IDC_ARROW、IDC_IBEAM、IDC_CROSS;背景颜色:HBRUSH(COLOR_3DFACE+1),图标(LoadStandardIcon:IDI_WINLOGO),
    框架窗口CFrameWnd创建窗口时,一般使用Create(NULL,_T("Title")),NULL指明将使用默认WNDCLASS样式。
    CreateEx中的窗口样式:WS_OVERLAPPED(作用不明,一般加上)、WS_SYSMENU、WS_MAXIMIZE、WS_MINIMIZE、WS_CAPTION、WS_THICKFRAME(边角拖动改变大小)
4、光标:一般在注册WNDCLASS时指定,或者通过::SetCursor进行指定,使用::SetCursor可以在一个窗口时灵活的设置多个光标,可通过::ShowCursor(TRUE)显示光标,::ShowCursor(False)隐藏光标。
   光标类型:IDC_ARROW、IDC_IBEAM、IDC_CROSS、IDC_WAIT(沙漏),显示沙漏光标 CWaitCursor wait;恢复 wait.Restore()。
   可通过::GetCursorPos和::SetCursorPos获取光标的屏幕坐标和设置光标的屏幕坐标。通过::ClipCursor(CPoint point)和::ClipCursor(NULL)来限制和取消光标在某个矩形区域
   ::GetDoubleClickTime()和::SetDoubleClickTime设置和取消双击间隔时间(毫秒),::GetKeyState获取键盘消息生成时键的状态,不是当前实时状态,::GetKeyState(VK_CONTROL) < 0时,Ctrl键被按下,
   ::GetKeyState(VK_NUMLOCK)&0x01为非零时,num Lock被锁定,0为非锁定。
   ::GetAsyncKeyState可以当前获取鼠标键的状态,::GetAsyncKeyState(VK_LBUTTON)返回负值表示左键被按下。   
   ::GetSystemMetric通过参数SM_CXDOUBLECLK和SM_CYDOUBLECLK和SM_SWAPBUTTON获取鼠标双击最大间隔水平距离和垂直距离(像素),以及确认鼠标左右键是否被交换。
5、通过WM_KEYUP和WM_KEYDOWN来处理键盘输入,对于可打印字符,则可以使用WM_CHAR来简化处理,处理WM_CHAR可以不用考虑VK_Shift、VK_NumLock等键的状态,这些由Windows处理。
6、Windows通过标识光标下的窗口来确定给哪个窗口发生鼠标消息,而通过键盘消息则发送给具有输入焦点的窗口,使用CWnd::GetFoucs()和CWnd::SetFocus获取焦点窗口和设置焦点窗口。
   WM_SETFOCUS和WM_KILLFOCUS消息通知即将获取或者失去焦点的窗口。
7、击键消息:WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN、WM_SYSKEYUP,消息处理原型:afx_msg void OnMsgName(UINT nChar,UINT nRepCnt,UINT nFlags),nCHar是虚拟键代码,如VK_LEFT等,
   除了Alt和F10,其他键都产生WM_KEYDOWN和WM_KEYUP消息,这两个键有特殊意义,按下时产生WM_SYSKEYDOWN和WM_SYSKEYUP事件,nFlags包括键的扫描码和一些标志位,nRepCnt指重复次数,实际不处理,
   对于WM_SYSKEYDOWN和WM_SYSKEYUP消息一般交由Windows处理。   
8、在Windwos程序中,闪烁的竖直条称为插入符,插入符是单线程共享资源,接收输入焦点时使用CWnd::CreateCaret创建插入符,失去焦点时,使用::DestroyCaret销毁插入符,
    CWnd::HideCaret和CWnd::SHowCaret隐藏和显示插入符,GetCaretPos和SetCaretPos获取和设置插入符位置,通过GetTextExtent(_T("aaaa",5))和GetTabbedTextExtent来计算字符串前n个字符累积的宽度。
9、在处理非客户区鼠标消息和系统键盘消息时,必须调用基类的默认处理过程,以避免忽略某些消息造成一些莫名其妙的问题出现。
10 、获取字体的宽度和高度TEXTMETRIC tm;
       pdc.GetTextMetrics(&tm);
       m_cxChar = tm.tmAveCharWidth;
       m_cyChar = tm.tmHeight;
       m_cyLine = tm.tmHeight + tm.tmExternalLeading;  
原创粉丝点击