一个程序最重要的部分之一是对鼠标和键盘操作的响应.

  一.  理解鼠标事件.之前对鼠标事件的认识仅仅局限于处理控件的单击与双击事件.但实际鼠标的操作包含很多.这里将以一个画图的小程序讲解对鼠标的响应.

    首先新建一个MFC程序,选择对话框类型,将Mouse设为程序标题.建立程序框架后将对话窗口中所有的控件删除.这样整个对话框都可以用来作图.

    然后选中对话框窗口在右下角属性窗口中的message(消息)选项,会列出一大串的事件消息.例如WM_LBUTONDOWN(鼠标左键被按下),WM_LBUTTONUP(鼠标左键被释放),WM_MOUSEMOVE(鼠标在应用程序窗口空间中移动).画图程序主要通过mousemove事件来实现.选中事件add一个函数.进入函数的实现中加入如下代码.

void CMouseDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
//检查鼠标左键是否被按下
if ((nFlags&MK_LBUTTON) == MK_LBUTTON){
//获取设备上下文
CClientDC dc(this);
//画出像素
dc.SetPixel(point.x, point.y, RGB(100, 100, 250));
}
CDialogEx::OnMouseMove(nFlags, point);
}

    然后便可以运行程序了,只是这个画图程序与我们平常的并不一样.这个后面再说.

    我们先来看这段代码,有两个参数传递给这个函数.第一个参数是一组标记,用来判断哪个鼠标的按钮被按下,if中的判断前一半是按位与,筛选为便是左键被按下的标记然后与后一半进行匹配;第二个参数是当前鼠标的位置,即鼠标在对话框窗口中的坐标,它包含两个成员:x,y;然后可以使用这个信息在窗口上画一个点.

    在画点之前我们还需要为对话窗口获取设备上下文.即CClientDC dc(this);这条语句.通过为CClientDC类声明一个新的实例来完成,参数this是当前窗口的指针.这个类封装了设备上下文以及大多数可以对其进行的操作,包括所有的屏幕绘制操作.可以这么理解,设备上下文是一块画布,你可以在上面为你的程序作画.

    下一条语句就是画一个点了,并且可以控制点的颜色,颜色控制是RGB的值来控制.

  然后来说一说这个程序的问题,在运行程序的时候会发现如果移动过快就不是一条实线了而是一个个的点,这是程序的性质决定的我们的计算机每隔一段时间检查鼠标的位置然后画一个点,如果移动很慢还能是一条实现,如果过快就变成虚线了.那我们如何解决呢?很简单,在鼠标确定的两点间连上直线.可以按照如下步骤来实现:

    首先向我们的对话框类--CMouseDlg类中添加两个成员变量,m_iPrevX,m_iPrevY,类型为int,属性为private.用来保存上一个点的数据.方便连线.

    然后对上一个函数做点修改.

void CMouseDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
//检查鼠标左键是否被按下
if ((nFlags&MK_LBUTTON) == MK_LBUTTON){
//获取设备上下文
CClientDC dc(this);
//从从前一点到当前点画一条线
dc.MoveTo(m_iPrevX, m_iPrevY);
dc.LineTo(point.x, point.y);
//把当前点作为前一点保存
m_iPrevX = point.x; m_iPrevY = point.y;
}
CDialogEx::OnMouseMove(nFlags, point);
}

   dc.MoveTo(m_iPrevX, m_iPrevY);dc.LineTo(point.x, point.y);这两局用来连线,首先需要移动到第一个位置,然后向第二个位置画线.这是非常重要的一步,如果没有这一步,windows将不知道从哪里开始画.这时再运行程序会好一些不再出现虚线,但又有了一个新的问题,每次按下鼠标左键的时候便与刚才最后一个点进行连线.

  现在进行最后的完善,将程序完善成:当鼠标左键被按下时,用当前的位置来初始化上一个位置的位置变量.

    首先在消息模式中为对话框对象的WM_LBUTTONDOWN消息添加一个函数.函数内容如下:

void CMouseDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_iPrevX = point.x;
m_iPrevY = point.y;
CDialogEx::OnLButtonDown(nFlags, point);
}

    再次运行时程序达到了我们想要的功能.

二.  对键盘的响应.

    获得键盘事件与获得鼠标事件非常相似.但键盘的事件比鼠标事件要少的多.

      WM_KEYDOWN  一个键被按下

      WM_KEYUP    一个键被释放

      WM_SYSKEYDOWN  F10被按下或者Alt与另一个键被同时按下

      WM_SYSKEYUP    F10被释放或者Alt与另一个键被同时释放

    这些事件消息对于对话框窗口对象是可用的,并且只有窗口中没有启用的控件时才会被激发.

  我们为上面的画图程序添加一点功能,当某个键被按下时,改变光标的形状.A改为默认的光标;B改为I型竖线;C改为沙漏型;X退出程序

    首先选择WM_KEYDOWN消息添加一个函数.代码如下:

void CMouseDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
char cChar;//当前被按下的字符
HCURSOR hCursor = ;//显示光标句柄
HCURSOR hPrevCursor = ;//以前的光标句柄
cChar = char(nChar);//将按下的键转换为字符
if (cChar == 'A'){
//加载箭头光标
hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
}
if (cChar == 'B'){
//加载箭头光标
hCursor = AfxGetApp()->LoadStandardCursor(IDC_IBEAM);
}
if (cChar == 'C'){
//加载箭头光标
hCursor = AfxGetApp()->LoadStandardCursor(IDC_WAIT);
}
if (cChar == 'X'){
hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
hPrevCursor = SetCursor(hCursor);
if (hPrevCursor)
DestroyCursor(hPrevCursor);
OnOK();//退出应用
}
else{
if (hCursor){
hPrevCursor = SetCursor(hCursor);
if (hPrevCursor)
DestroyCursor(hPrevCursor);
}
}
CDialogEx::OnKeyDown(nChar, nRepCnt, nFlags);
}

  这个函数有三个参数.第一个nChar是被按下的键,这个是字符的字符代码,在代码的的第一行需要被转化为字符.然后就可直接比较了;第二个参数nRepCnt是这个键被按下的时间.通常被按下就释放,这个值是1.如果一直按下这个键的值会上升,这个值告诉你Windows认为这个键被按下了多少次;第三个参数nFlags是个组合的标记,它可以确定在键被按下的时候是否同时有Alt键被按下,或者被按下的是一个扩展键.

   改光标的过程为:第一步将光标调入内存中,通过LoadStandardCursor(IDC_ARROW)实现.然后这个光标的句柄被传给SetCursor函数,这个函数将光标转换为句柄所对应的光标,并返回前一个光标的句柄.可以使用DestroyCursor(hPrevCursor)销毁前一个光标.

  注意:当鼠标移动过程中光标将切换为默认的箭头.

  AfxGetApp函数:上面的LoadStandardCursor是通过AfxGetApp来调用的,这个函数是一个全局函数,它返回当前应用程序类的一个实例.应用程序类是当前应用程序中CWinApp的子孙类.对我们写的程序来说就是CMouseApp类.当我们需要访问封装在CWinApp类中的功能或当前的派生类时,可以使用AfxGetApp函数得到指向它的指针.对继承派生不熟的回去好好看看c++的书.

 

MFC--响应鼠标和键盘操作的更多相关文章

  1. Qt之股票组件-股票检索--支持预览框、鼠标、键盘操作

    目录 一.感慨一下 二.效果展示 三.搜索编辑框 1.编辑框 2.预览框 四.相关文章 原文链接:Qt之股票组件-股票检索--支持预览框.鼠标.键盘操作 一.感慨一下 之前做过一款炒股软件,个人觉着是 ...

  2. Python模拟鼠标和键盘操作实现重复性操作

    前言 由于工作需要,要利用某软件去采集数据,做重复的动作大概500多次.所以想写一个程序代替人,去点击和输入. 一开始的思路有两个:1.用Python或者windows对此软件直接操作.2.利用Pyt ...

  3. selenium 使用action进行鼠标,键盘操作

    <!--test.html--> <html> <head> <title>Set Timeout</title> <script&g ...

  4. WebDriver API——鼠标及键盘操作Actions

    在自动化中我们可能需要用到鼠标或者是键盘操作,在webdriver中是Actions类进行这些操作的. 代码如下: Actions action = new Actions(driver); //-- ...

  5. python + selenium webdriver 通过python来模拟鼠标、键盘操作,来解决SWFFileUpload调用系统底层弹出框无法定位问题

    Webdriver是基于浏览器操作的,当页面上传文件使用的是flash的控件SWFFileUpload调用的时候,调用的是系统底层的文件选择弹出框 这种情况,Webdriver暂时是不支持除页面外的其 ...

  6. selenium中元素操作之简单的鼠标、键盘操作(三)

    1.鼠标操作导入类:ActionChains --鼠标的操作形成一连串的动作链,由selenium的ActionChains类来完成模拟鼠标操作手表操作的过程:1.鼠标的操作,先放到一个列表中2.利用 ...

  7. 4. selenium中鼠标和键盘操作

    一.鼠标操作 第一步:引入模块函数 from selenium.webdriver.common.action_chains import ActionChains 第二步:元素定位 element ...

  8. web自动化 模拟鼠标、键盘操作

    一.鼠标操作 1.1鼠标的悬停操作,move_to_element from selenium import webdriver from selenium.webdriver.common.acti ...

  9. selenium 鼠标,键盘操作

    1.鼠标操作 导包:from selenium.webdriver.common.action_chains import ActionChains 1.context_click()        ...

随机推荐

  1. CRM/ERP 企业管理软件中常见的七种程序设计模式

    管理软件中的常见代码设计模式,来自于业务上的需要,有不恰当的地方欢迎批评指正. 1  RE-TRY 重试模式 场景:在连接数据库服务器时,如果SQL Server数据库没有启动或正在启动,我们需要有一 ...

  2. Sql Server系列:查询分页语句

    1 利用临时表分页 分页存储过程: CREATE PROCEDURE [USP_Product_GetPaged] ), ), @PageIndex INT, @PageSize INT AS BEG ...

  3. Git-Notes

    1.Git安装,直接在官网下载安装即可. 2.Git配置,使用config选项,配置名字和邮箱,如下所示 C:\Users\1yyg>git config --global user.name ...

  4. 重磅开源:TN文本分析语言

    tn是desert(沙漠之鹰)和tan共同开发的一种用于匹配,转写和抽取文本的语言(DSL).并为其开发和优化了专用的编译器.基于递归下降方法和正则表达式,能解析自然文本并转换为树和字典,识别时间,地 ...

  5. Android随笔之——Activity中启动另一应用

    最近在写语音交互程序,在语音打开应用这块碰到如何用代码控制应用启动的问题.百度了一下,有两种方案:1.获取应用的包名:2.获取应用的包名.入口类名. 之前对两种方案都进行了尝试,发现方案二中存在一个弊 ...

  6. Kooboo CMS 无聊随笔(2)

    上次写了一篇博客 http://www.cnblogs.com/kmsfan/p/Kooboo_CMS_suibi.html 作为这个系列的开篇,简单的介绍了一下Kooboo CMS的一些基本情况和界 ...

  7. 用HTML5 CANVAS做自定义路径的动态效果图片!

    最近对HTML5开始感兴趣了,实现的效果如下图,大家可以从代码里换掉图片 我用的是canvas里面的2d绘图,其中上图的路径是网上在线绘制的,我太懒了,哈哈 下面是网址: http://www.vic ...

  8. Android 程序打包及签名

    为什么要签名??? 开发Android的人这么多,完全有可能大家都把类名,包名起成了一个同样的名字,这时候如何区分?签名这时候就是起区分作用的. 由于开发商可能通过使用相同的Package Name来 ...

  9. Ajax 与 XmlHttpRequest

    AJAX描述了确保Web应用在Web服务器请求新数据的情况下也能(几乎)实时反应的一种方法.具体地说,AJAX只是一些建立已久的技术的相互作用,从HTML.XHTML和HTTP,到JavaScript ...

  10. git安装和初次使用

    为了知道某人安装git,我也是重装啊. 1.下载git并安装 2.打开我的电脑,右键属性,选择高级设置,打开环境变量设置: 3.键盘输入窗口键+r,或者点击开始->运行 输入cmd 在新打开的命 ...