项目需要根据左键单击计时的手段来模拟左键双击的效果。

msdn对于WM_LBUTTONDBLCLK中有一句:

Only windows that have the CS_DBLCLKS style can receive WM_LBUTTONDBLCLK messages, which the system generates whenever the user presses, releases, and again presses the left mouse button within the system's double-click time limit. Double-clicking the left mouse button actually generates a sequence of four messages: WM_LBUTTONDOWN,WM_LBUTTONUP, WM_LBUTTONDBLCLK, and WM_LBUTTONUP.

也就是说,带有CS_DBLCLKS标志的窗口类可接收到WM_LBUTTONDBLCLK消息,且消息以下列序列发出:

WM_LBUTTONDOWN

WM_LBUTTONUP

WM_LBUTTONDBLCLK

WM_LBUTTONUP

开始时在WM_LBUTTONDOWN消息响应函数中计数处理,死活不行,需要三击鼠标左键才能判断为双击,原因就在于对于CS_DCLCLKS标志的窗口类创建的窗口实例,对于双击操作的第二下左键down,不发WM_LBUTTONDOWN消息,所以就漏过了,需要第三下左键按下才判断为双击并进行响应。问题找到了,解决方案有三:

1.在WM_LBUTTONUP中判断双击或是单击

2.在PreTranslateMessage中拦截WM_LBUTTONDBCLK,令其为WM_LBUTTONDOWN,仍然return 0 分发这个消息,只是修改一下pMsg->message

3.改变窗口类风格,用到SetClassLong函数

1)起先,在CWnd::OnCreate中直接改变窗口类风格:

 DWORD style = GetClassLong(m_hWnd, GCL_STYLE);style &= ~CS_DBLCLKS;SetClassLong(m_hWnd, GCL_STYLE, style);

发现ok了,但是除此之外的有些窗口也无法响应双击消息了。判断为该段代码通过某窗口类(这里记为wndclassA)的一个窗口实例改变了wndclassA的风格,导致同一进程中其它使用wndclassA创建的窗口实例都失去了响应双击消息的能力(不知道窗口过程是否会影响,反正style是影响了),我的项目中wndclassA是windows标准控件LISTBOX,更具体的在《Win32中安全的子类化
》http://www.cppblog.com/mydriverc/articles/28233.html。

“要全局子类化一个窗口类,应用程序必须拥有一个该类的窗口实例。想要获得该类的窗口实例,大多数应用程序采取建立一个属于将要被全局子类化的窗口类的窗口的方法,当应用程序要移除子类化,也必须有一个窗口句柄,该句柄应该是属于应用程序要子类化的窗口类的,因此,为此而专门创建并保存一个窗口是个不错的办法。如果应用程序需要创建它所要子类化的窗口类的窗口实例,这个窗口实例通常应该是不可见的。”

为了验证这个想法,按向导建了个最简单的单文档程序,在CView的OnCreate中写入代码:

 HWND btn1 = CreateWindowEx(0,_T("BUTTON"),_T("改变button类游标前"),WS_CHILD | WS_VISIBLE | BS_FLAT | WS_BORDER,220,10,40,20,m_hWnd,NULL,AfxGetApp()->m_hInstance,NULL);SetClassLong(btn1, GCL_HCURSOR,(LONG)LoadCursor(NULL, IDC_HELP) ); HWND btn2 = CreateWindowEx(0,_T("BUTTON"),_T("改变button类游标后"),WS_CHILD | WS_VISIBLE | BS_FLAT | WS_BORDER,220,100,40,20,m_hWnd,NULL,AfxGetApp()->m_hInstance,NULL);

SetClassLong的操作同时影响了两个button,无论创建先后于SetClassLong,这就意味着SetClassLong的操作直接改变了进程中所有以button窗口类名创建的按钮。

2)然后,就只能把我的窗口类单独拉出来注册,由于SetWindowLong函数无法在运行期改变某窗口实例指向的窗口类,故就在PreCreateWindow中处理传入的参数

CREATESTRUCT& cs

写入代码:

BOOL CmySetLongView::PreCreateWindow(CREATESTRUCT& cs)
{   WNDCLASSEX myWndClass;myWndClass.cbSize = sizeof(WNDCLASSEX);GetClassInfoEx(AfxGetApp()->m_hInstance, _T("listbox"), &myWndClass);myWndClass.lpszClassName = _T("MYLISTBOXWITHOUTDBCLK");myWndClass.style &= ~CS_DBLCLKS;RegisterClassEx(&myWndClass);cs.lpszClass = _T("MYLISTBOXWITHOUTDBCLK");return CView::PreCreateWindow(cs);
}

这样,利用GetClassName函数查看窗口类名,已经是“MYLISTBOXWITHOUTDBCLK”。仅以该类名创建的窗口实例才会无法响应双击消息。

除此之外,还可以使用SetClassLong改变图标、游标等,用SetWindowLong搞掉最小化按钮等

SetWindowLong(m_hWnd,GWL_STYLE,(LONG)GetWindowLong(m_hWnd,GWL_STYLE) & ~WS_MINIMIZEBOX);

(也可以直接操作PreCreateWindow传入的cs:

cs.style &= ~WS_MINIMIZEBOX

转载于:https://www.cnblogs.com/silyvin/p/9106883.html

MFC中由左键单击模拟左键双击引起的问题相关推荐

  1. android怎么模拟返回,Android中障蔽返回键,HOME键以及模拟HOME键返回效果的方法...

    Android中屏蔽返回键,HOME键以及模拟HOME键返回效果的方法 在Android开发中,有时需要屏蔽一些实体的按键,如HOME键,返回键等实体的按键,实现的方法如下. 1. 屏蔽实体按键 屏蔽 ...

  2. php控制鼠标,HTML_用VBS控制鼠标的实现代码(获取鼠标坐标、鼠标移动、鼠标单击、鼠标双击、鼠标右击),怎么用VBS模拟鼠标左键单击、 - phpStudy...

    用VBS控制鼠标的实现代码(获取鼠标坐标.鼠标移动.鼠标单击.鼠标双击.鼠标右击) 怎么用VBS模拟鼠标左键单击.左键双击.右键单击?-- 网上搜到的答案普遍是VBS无法实现,或者是要用第三方COM( ...

  3. 网站选择按钮点击无反应?_Win10系统电脑鼠标左键单击没有反应的解决办法

    Win10系统鼠标左键单击没有反应是怎么回事?最近一个用户在用电脑的时候,突然遇到鼠标左键单击没有反应的问题,是鼠标坏了吗?还是系统问题呢?今天就给大家分析Win10系统电脑鼠标左键单击没有反应的可能 ...

  4. 点击欺诈木马利用单击鼠标左键逃避检测

    2019独角兽企业重金招聘Python工程师标准>>> 研究人员发现,一种新的木马在等到受害者单击鼠标左键再执行命令并感染系统,从而逃避检测.这项新的研究是基于之前对利用鼠标操作隐藏 ...

  5. 模拟鼠标的左键单击和右键单击

    ' ------------------------------------------- '        模拟鼠标的左键单击和右键单击 ' ---------------------------- ...

  6. winform ctrl键单击多选_鼠标各键在CAD中的运用,左右键常用,但滚轮这个功能不一定用过...

    在CAD制图过程中,我们通常是左手按键盘,右手握鼠标,两手同时开工,可以说,鼠标是我们制图过程中用得最频繁的工具.那么鼠标的各个键功能,我们是否都常用呢?不一定,有些鼠标键功能可能都没怎么用过,下面以 ...

  7. MFC 给列表控件发送左键单击、双击、以及右键单击消息

    void CTestsetting::SendClickToList() {NMITEMACTIVATE NMItemActive;NMHDR thdr;thdr.code = NM_CLICK; / ...

  8. 检测单击鼠标左键并拖动的消息_计算机视觉OpenCV学习笔记(四):关于鼠标的相关事件函数...

    (7)把鼠标当画笔 本篇目标: 学会使用OpenCV中的鼠标处理的相关事件,事件回调函数怎么去定义,参数有哪些,以及如何注册鼠标监听事件. 7.1 .1 回调函数的定义: 1 def name(eve ...

  9. C#怎么判断是鼠标左键单击还是右键单击?

    C#怎么判断是鼠标左键单击还是右键单击? 判断方法如下: private void MouseClick(object sender, MouseEventArgs e){ if (e.Button ...

最新文章

  1. tp5+linux+apache php7.1.30环境下,上传图片报错:mkdir():permission denied
  2. oracle 查看表是否被锁
  3. spark 调度模块详解及源码分析
  4. 基于Docker搭建Percona XtraDB Cluster数据库集群
  5. C#中ToString格式大全
  6. c创建python虚拟机_cpython大致数据结构实现笔记
  7. 有运气的赚钱,不如有成长的失败
  8. 使用sql语句向SDO_Geometry插入要素
  9. EasyUI-在iframe里获取现阶段选中的tab的标题
  10. jdk StringBuilder实现
  11. 关于php中gettext的用法?
  12. python实现sip协议_SIP协议的常见命令 - HouWeiGui的个人空间 - OSCHINA - 中文开源技术交流社区...
  13. 【python爬虫实战】 001 技术路线图
  14. 自动化测试金字塔与反模式
  15. python公众号教学_Python微信公众号后台开发教程
  16. 详细讲解MySQL索引与联合索引
  17. txt文件批量转换为excel文件
  18. 6. 查询选修了课程名为“信息系统”的学生学号和姓名
  19. JS实现div宽度、高度拉伸
  20. 用计算机控制神舟十号,2010年全国自考操作系统概论模拟试卷(十)

热门文章

  1. Android隐式启动匹配:action,category,data
  2. 通用高性能 Windows Socket 组件 HP-Socket v2.2.1(增加 PULL 模型支持)
  3. Zend Framework实例教程三
  4. Adobe Acrobat 高亮工具使用后无法显示文字Bug解决办法
  5. android numberpicker,NumberPicker实现滑动选择
  6. 如何在Linux中找到您的IP地址
  7. wtf是转换ttf_WTF入门,它是终端的仪表板
  8. 安全和隐私:您知道系统中潜藏着什么吗?
  9. 开源 非开源_打破开源中的怪胎刻板印象
  10. JS_console对象中的一些常用方法