MFC鼠标单击截获鼠标双击事件,且无法记录单击的数据的解决方案
遇到的问题:
- 鼠标点击会截断鼠标双击的事件,无法保存椭圆的数据。也就是说双击执行的过程是OnLButtonDown,OnLButtonUp,OnLButtonDblClk,OnLButtonUp。并不是想象中的直接执行OnLButtonDblClk,那么如果在OnLButtonDown中定义起始点,OnLButtonUp中定义终点,椭圆可以直接画出,但是双击时,会先执行OnLButtonDown,OnLButtonUp那么起点和终点就会被重新覆盖,且覆盖后的点的坐标都一样,然后才执行OnLButtonDblClk,此时,起点和终点相同,就没法再画椭圆,而且最后还会再执行一次OnLButtonUp。
那么如何解决问题?
刚开始百度发现他们是通过判断鼠标两次点击的时间差是否小于系统定义的时间差500,鼠标双击会先执行一次OnLButtonDown然后在第二次的OnLButtonDown来判断是不是鼠标在双击,然而这种方法还是会将原始数据覆盖,无法保存那条线的数据。
后来我在睡觉前突然想到可以通过数组来保存原始数据,通过数组的下标来控制鼠标双击时的数据保存到另一个数组中,以避免数据的覆盖,于是写出上面的程序。
- MFC中数据的查看
MFC中如何查看数据,刚开始打算直接使用TextOut来直接输出执行过程中的数据,但是,它只支持CString类型,遇到int型还要sprintf转格式,太麻烦,而且也不能实时刷新,显示的范围还有限。
使用控制台输出,可是MFC执行时 ,连控制台的界面都没见。
只能使用文件流来输出信息。
实现思路:
1通过两点画椭圆
2.以这将这两点组合到一起,也就是可以看做一条线决定了一个椭圆。每画一个椭圆就往线的数组里记录一次。
3.获取鼠标双击的坐标,并判断这点是否在椭圆内部,如果在内部,则重画椭圆(带填充)并将线的数组清空,如果不在,则继续双击时,线的数组的下标不增加,重新覆盖数据,然后再判断这个点是否在椭圆内。
程序:
全局变量
CPoint start_p,end_p;
bool flag=true;//双击时的点是否在椭圆内
ofstream myfile;
int i=;//用来计数线的数组 class Line{
public :
CPoint p1,p2;
Line(){
p1.SetPoint(,);
p2.SetPoint(,);
}
void set_p1( CPoint a1){
p1.SetPoint(a1.x,a1.y);
}
void set_p2( CPoint a2){
p2.SetPoint(a2.x,a2.y);
} }; Line l[];
1 // CMy91View 消息处理程序
void CMy91View::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: ÔÚ´ËÌí¼ÓÏûÏ¢´¦Àí³ÌÐò´úÂëºÍ/»òµ÷ÓÃĬÈÏÖµ CView::OnLButtonDown(nFlags, point); //单击
start_p=point;
l[i].set_p1(point); myfile.open("1.txt",ios::app);
myfile<<"单击OnLButtonDown:"<<endl;
myfile<<"l:"<<i<<endl;
myfile<<"p1:("<<l[i].p1.x<<","<<l[i].p1.y<<")"<<endl;
myfile<<"p2:("<<l[i].p2.x<<","<<l[i].p2.y<<")"<<endl;
myfile<<endl<<endl;
myfile.close(); } void CMy91View::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: ÔÚ´ËÌí¼ÓÏûÏ¢´¦Àí³ÌÐò´úÂëºÍ/»òµ÷ÓÃĬÈÏÖµ CView::OnLButtonUp(nFlags, point); if(){
end_p=point;
l[i].set_p2(point); CClientDC dc(this);
dc.Ellipse(start_p.x,start_p.y,end_p.x,end_p.y); myfile.open("1.txt",ios::app);
myfile<<"单击OnLButtonUp:"<<endl;
myfile<<"l:"<<i<<endl;
myfile<<"p1:("<<l[i].p1.x<<","<<l[i].p1.y<<")"<<endl;
myfile<<"p2:("<<l[i].p2.x<<","<<l[i].p2.y<<")"<<endl;
myfile<<endl<<endl;
myfile.close(); //判断是不是双击,双击后会让下一个坐标的p2点不为0,但p1点为0;
if(l[i].p1.x!=&&l[i].p1.y!=){
i++;//增加椭圆
}else{
if(i>&&!flag){
i--;//不在圆内双击,计数减1,,重新计数
} } }
} //判断一个点是否在椭圆内部
bool in_Elliplse(CPoint p1,CPoint p2,CPoint p3){
CPoint center((p1.x+p2.x)/,(p1.y+p2.y)/);
CPoint r(abs(p1.x-p2.x)/,abs(p1.y-p2.y));
CPoint p3_0(p3.x-center.x,p3.y-center.y); if(r.x>r.y){
double x=pow((double)p3_0.x,)/pow((double)r.x,);
double y=pow((double)p3_0.y,)/pow((double)r.y,);
if(x+y<=){
return true;
}else{
return false;
}
}else{
double x=pow((double)p3_0.y,)/pow((double)r.x,);
double y=pow((double)p3_0.x,)/pow((double)r.y,);
if(x+y<=){
return true;
}else{
return false;
}
} } void CMy91View::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: ÔÚ´ËÌí¼ÓÏûÏ¢´¦Àí³ÌÐò´úÂëºÍ/»òµ÷ÓÃĬÈÏÖµ CView::OnLButtonDblClk(nFlags, point); myfile.open("1.txt",ios::app);
myfile<<"双击"<<endl<<"OnLButtonDblClk:"<<endl;
myfile<<"l:"<<i<<endl;
myfile<<"p1:("<<l[i].p1.x<<","<<l[i].p1.y<<")"<<endl;
myfile<<"p2:("<<l[i].p2.x<<","<<l[i].p2.y<<")"<<endl;
myfile<<"l-1:"<<i-<<endl;
myfile<<"p1:("<<l[i-].p1.x<<","<<l[i-].p1.y<<")"<<endl;
myfile<<"p2:("<<l[i-].p2.x<<","<<l[i-].p2.y<<")"<<endl;
myfile<<"l-2:"<<i-<<endl;
myfile<<"p1:("<<l[i-].p1.x<<","<<l[i-].p1.y<<")"<<endl;
myfile<<"p2:("<<l[i-].p2.x<<","<<l[i-].p2.y<<")"<<endl;
myfile<<endl<<endl;
myfile.close(); //填充
if(in_Elliplse(l[i-].p1,l[i-].p2,l[i-].p1)){
CBrush brush(RGB(,,));
CClientDC dc(this);
dc.SelectObject(&brush);
dc.Ellipse(l[i-].p1.x,l[i-].p1.y,l[i-].p2.x,l[i-].p2.y); //重新计数
i=; //清空椭圆
for(int a=;a<;a++){
CPoint p(,);
l[i].set_p1(p);
l[i].set_p2(p);
}
flag=true;
}else{
flag=false;
} }
数据分析:
使用文件流来输出信息,如下:
在第一次鼠标按下再抬起时画椭圆,然后椭圆内双击填充时的数据信息:
单击OnLButtonDown:
l:0
p1:(270,94)
p2:(0,0)
单击OnLButtonUp:
l:0
p1:(270,94)
p2:(488,222)
单击OnLButtonDown:
l:1
p1:(391,176)
p2:(0,0)
单击OnLButtonUp:
l:1
p1:(391,176)
p2:(391,176)
双击
OnLButtonDblClk:
l:2
p1:(0,0)
p2:(0,0)
l-1:1
p1:(391,176)
p2:(391,176)
l-2:0
p1:(270,94)
p2:(488,222)
单击OnLButtonUp:
l:0
p1:(0,0)
p2:(391,176)
在第一次鼠标按下再抬起时画椭圆,然后椭圆外双击(可以任意次)这里就一次,然后在椭圆内双击填充时的数据信息:
单击OnLButtonDown:
l:0
p1:(335,85)
p2:(0,0)
单击OnLButtonUp:
l:0
p1:(335,85)
p2:(601,197)
单击OnLButtonDown:
l:1
p1:(397,284)
p2:(0,0)
单击OnLButtonUp:
l:1
p1:(397,284)
p2:(397,284)
双击
OnLButtonDblClk:
l:2
p1:(0,0)
p2:(0,0)
l-1:1
p1:(397,284)
p2:(397,284)
l-2:0
p1:(335,85)
p2:(601,197)
单击OnLButtonUp:
l:2
p1:(0,0)
p2:(397,284)
单击OnLButtonDown:
l:1
p1:(423,141)
p2:(397,284)
单击OnLButtonUp:
l:1
p1:(423,141)
p2:(423,140)
双击
OnLButtonDblClk:
l:2
p1:(0,0)
p2:(397,284)
l-1:1
p1:(423,141)
p2:(423,140)
l-2:0
p1:(335,85)
p2:(601,197)
单击OnLButtonUp:
l:0
p1:(0,0)
p2:(423,140)
实验结果:

程序的不足:
在程序只有双击填充时,线的数组才会清空,下标再次重0开始,如果用户不双击,一直在画椭圆,那么最多画30个椭圆(这个数值可以任意修改),但这个数值不是无穷的。或许可以通过动态建立数组或者使用线性列表来解决。(如果有谁解决了,@我,大家一起进步)
MFC鼠标单击截获鼠标双击事件,且无法记录单击的数据的解决方案的更多相关文章
- JQuery如何实现双击事件时不触发单击事件,解决鼠标单双击冲突问题
在jQuery的事件绑定中,如果元素同时绑定了单击事件(click)和双击事件(dblclick),那么执行单击事件(click)时,不会触发双击事件(dblclick), 执行双击事件(dblcli ...
- JQuery如何实现双击事件时不触发单击事件
单击和双击事件的执行顺序: 单击(click):mousedown,mouseout,click: 双击(dblclick):mousedown,mouseout,click , mousedown, ...
- Extjs给gridPanel添加单价双击事件和获取当前行的数据
有两个小属性,如下 this.on('rowdblclick', this.readContent, this); this.on('cellclick', this.gridCellClick, t ...
- IE和Chrome执行javascript对鼠标双击事件的不同响应
最近在用天地图API帮同学做点开发的工作,主要是基于天地图的API实现违法用地举报的在线地图标绘,要实现的效果如下: 由于是基于天地图API的TPolygonTool工具实现面积量测和多边形绘制功能, ...
- [转]jQuery 双击事件(dblclick)时,不触发单击事件(click)
例1: 链接:http://www.w3school.com.cn/jquery/event_dblclick.asp HTML 系列教程 浏览器脚本 服务器脚本 ASP.NET 教程 XML 系列教 ...
- GridView/DataGrid行单击和双击事件实现代码_.Net教程
功能: 单击选中行,双击打开详细页面 说明:单击事件(onclick)使用了 setTimeout 延迟,根据实际需要修改延迟时间 ;当双击时,通过全局变量 dbl_click 来取消单击事件的响应 ...
- Angular JS中双击事件ng-dblclick避免同时触发两次单击事件ng-click的解决方案
有些需求中,需要一个元素上既有双击事件,也有单击事件,而两者实现的效果不一样. 这时可以使用ng-dblclick与ng-click来实现需求,但是要避免浏览器将双击事件误认为是两次单击事件,从而出现 ...
- jQuery 双击事件(dblclick)时,不触发单击事件(click)
我这是转载的文字 原文地址:http://www.cnblogs.com/wyblog/archive/2011/12/15/2289219.html 万恶的双击事件啊!! 在jQuery的事件绑定中 ...
- [转] Ext Grid (ExtJs)上的单击以及双击事件
例1: 1.双击 var cb = new Ext.grid.RowSelectionModel({ singleSelect:true //如果值是false,表明可以选择多行:否则只能选择一行 } ...
随机推荐
- 如何利用panel在一个窗口中实现诸多页面的显示
Book_register form11 = new Book_register();//new一个对象 form11.TopLevel = false;//去除子窗体的顶级窗体设置 form11.P ...
- 【Flink】流-表概念
title: Flink流-表概念 date: 2017-12-12 14:48:16 categories: technique tags: Flink Flink Streaming Dynami ...
- centos7 简单搭建lnmp环境
1:查看环境: 1 2 [root@10-4-14-168 html]# cat /etc/redhat-release CentOS release 6.5 (Final) 2:关掉防火墙 1 [r ...
- 浏览器出现Cannot set property 'onclick' of null的问题
Part1: 当js文件放在head里面时,如果绑定了onclick事件,就会出现这样的错误, 是因为W3School的写法是浏览器先加载完按钮节点才执行的js,所以当浏览器自顶向下解析时,找不到on ...
- linux下的数据库管理工具phpmyadmin安装以及文件大小限制的配置修改
1.首先需要安装mysql和apache服务.具体安装过程百度; 2.安装php环境以及对apache的扩展; sudo apt install php7.0 对于这些软件可能还需要各自进行配置,这 ...
- DOMContentLoaded、readystatechange、load、ready详谈
对前端同学而言,loade,unload,DOMContentLoaded等页面加载过程中会触发的事件肯定是都接触过,不过要是具体问各个事件的区别,我就不是那么能清晰的解答上来的了.正好刚刚在无阻塞脚 ...
- Session与Cookie的概念原理
前言: 本文没有任何代码,内容全部都是概念与运行原理,在使用一个技术前一定要弄清他的本质,下面会讲Session.Cookie.ServletContext的概念与他们的联系区别 Session概念 ...
- Express4.x API (二):Request (译)
写在前面 最近学习express想要系统的过一遍API,www.expressjs.com是express英文官网(进入www.epxressjs.com.cn发现也是只有前几句话是中文呀~~),所以 ...
- 使用CEF的JSON解析功能
Cef提供了JSON解析功能,在cef_parser.h文件内有三个JSON相关的方法: CefParseJSON CefParseJSONAndReturnError CefWriteJSON 以最 ...
- 数据库中的參照完整性(Foreign Key)
之前在项目中遇到了这样一个问题,我举得简单的样例来说明. 比方我们有两个表,一个表(department)存放的是部门的信息,比如部门id,部门名称等:还有一个表是员工表(staff),员工表里面肯定 ...