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,表明可以选择多行:否则只能选择一行 } ...
随机推荐
- ChatterBot之linux下安装mongodb 02
当前环境 :centos 6.9 mongodb版本 mongodb-linux-x86_64-3.4.4.tgz 使用链接工具:studio-3t-x64.msi.zip 首先我们先来安装mongo ...
- Java关键字(一) 修饰符private、protected、public和default的作用域
我们经常用着四种修饰符去修饰变量.方法和类,但是这四种的作用域都一样吗? 其中private和public可能是最多人知道的,但是protected和default可能就不知道其具体的作用域是哪些范围 ...
- 当final作用于变量、参数、方法和类时该如何处理
final变量: 对于基本类型使用final:它就是一个常量,数值恒定不变 对于对象引用使用final:使得引用恒定不变,一旦引用被初始化指向一个对象,就无法再把 它改为指向另一个对象.然而,对象自身 ...
- P1092 虫食算
题目传送:https://www.luogu.org/problem/show?pid=1092 #include <iostream> #include <cstring> ...
- SPOJ SERGRID - Grid BFS
SERGRID - Grid no tags You are on an nxm grid where each square on the grid has a digit on it. From ...
- VMware12提示 已将该虚拟机配置为使用 64 位客户机操作系统。但是,无法执行 64 位操作。
VMware12提示 已将该虚拟机配置为使用 64 位客户机操作系统.但是,无法执行 64 位操作. 此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态 解决办法: 下载LeoM ...
- MySQL slave_exec_mode 参数说明
背景: 今天无意当中看到参数slave_exec_mode,从手册里的说明看出该参数和MySQL复制相关,是可以动态修改的变量,默认是STRICT模式(严格模式),可选值有IDEMPOTENT模式(幂 ...
- JAVA8之lambda表达式具体解释,及stream中的lambda使用
前言: 本人也是学习lambda不久,可能有些地方描写叙述有误,还请大家谅解及指正! lambda表达式具体解释 一.问题 1.什么是lambda表达式? 2.lambda表达式用来干什么的? 3.l ...
- Android Root原理初探
Root Linux:Root == Windows:Adminstrator Android是Linux系统吗? 操作系统 = 系统内核 + 文件系统 Linux发行版:Linux内核 + 文件系统 ...
- Microsoft Graph 桌面应用程序
作者:陈希章 发表于 2017年3月22日 桌面应用程序,在我这篇文章的语境中,我是特指在Windows桌面上面直接运行的.NET应用程序,包括Console Application,WPF Appl ...