//bSwap:BOOL型

//为TRUE为切换左右键功能,为FALSE为恢复原左右键功能

::SwapMouseButton(bSwap);

可以使用RegisterHotKey()注册一个热键,在需要时切换。但是还得知道该传入TRUE还是FALSE到SwapMouseButton(),那么可以使用GetSystemMetrics(SM_SWAPBUTTON)查询鼠标当前左右键功能是否反转了:

//返回TRUE表示鼠标左右键功能反转了,FALSE表示正常

::GetSystemMetrics(SM_SWAPBUTTON);

最后可以让程序每次自动启动,需要右键的时候按一下热键就可以了,使用完了再切换回来。问题是,这样每次使用时,在左右键之间来回切换很麻烦。

下面在全局鼠标钩子中模拟鼠标右键单击。当按Ctrl+鼠标左键时,相当于点击右键。这里所说的鼠标左键与右键都是用SwapMouseButton(TRUE)切换过的,也就是说,我的真实的鼠标左键已坏,实际上只有鼠标右键可以使用,现在我把鼠标右键当左键用,但又添加右键本身的功能(就是加按Ctrl时相当于原来的右键)。未特殊说明,则下同。

1、使用SetWindowsHookEx安装钩子。

HHOOK CUtil::InstallMouseHook(HINSTANCE hInstance)

{

HHOOK hhkMouseHook;

hhkMouseHook = SetWindowsHookEx(

WH_MOUSE_LL,                        // hook type

CUtil::LowLevelMouseProc,        // hook procedure

hInstance,                                    // handle to application instance

0                                                // thread identifier:为0表示全局钩子

);

if(hhkMouseHook==NULL)

MessageBox(NULL,"安装MouseHook失败!","InstallMouseHook()",MB_OK);

return hhkMouseHook;

}

在应用程序的InitInstance()中调用:

//m_hInstance为应用程序实例句柄

HHOOK hhkLowLevelKybd = InstallMouseHook(m_hInstance):

2、编写全局鼠标钩子回调函数LowLevelMouseProc:

//当按下"Ctrl+鼠标左键" 或 "数字键盘减号键 + 鼠标左键"时,模拟鼠标右键

LRESULT CALLBACK

CUtil::LowLevelMouseProc(int nCode,

WPARAM wParam,

LPARAM lParam)

{

if(nCode == HC_ACTION){

//左Ctrl键按下

BOOL bLeftCtrlDown =

(GetAsyncKeyState(VK_LCONTROL) & 0x8000) != 0;

//数字键盘减号"-"键按下

BOOL bNumpadSubtractDown =

(GetAsyncKeyState(VK_SUBTRACT) & 0x8000) != 0;

//当按下"Ctrl+鼠标左键" 或 "数字键盘减号键+鼠标左键"时,模拟鼠标右键

if( (wParam == WM_LBUTTONDOWN) &&

(bLeftCtrlDown || bNumpadSubtractDown) )

{

const INPUT_SIZE = 2;

INPUT input[INPUT_SIZE];

ZeroMemory( &input, sizeof(INPUT)*INPUT_SIZE);//初始化INPUT结构体

//鼠标右键按下

input[0].type = INPUT_MOUSE;

input[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;

//鼠标右键弹起

input[1].type = INPUT_MOUSE;

input[1].mi.dwFlags = MOUSEEVENTF_LEFTUP;

//发送鼠标右键单击

SendInput(

INPUT_SIZE,                // count of input events

input,                    // array of input events

sizeof(INPUT)            // size of structure

);

//发送模拟的鼠标右键单击后,不再响应鼠标左键单击消息

return 1;

}

}

//如果不是"Ctrl+鼠标左键"按下,则向后传递鼠标消息。

return CallNextHookEx(NULL,nCode,wParam,lParam);

}

LowLevelMouseProc()有几点要注意的地方:

a)、LowLevelMouseProc()应声明为static,因为在一个类中,只有static函数才能作为回调函数。

b)、wParam == WM_LBUTTONDOWN一句原来写的是WM_LBUTTONUP,结果点击后右键菜单出来了,但无法完成复制。所以应为WM_LBUTTONDOWN就不会有问题了。

c)、只用使用VK_LCONTROL而不是VK_CONTROL是因为Ctrl+鼠标左键单击在选择多个文件时已被使用。所以把VK_RCONTROL留给选择多个文件等其它用途时使用,而用数字键盘中的减号代替VK_RCONTROL。也就是说,当按下"Ctrl+鼠标左键" 或 "数字键盘减号键+鼠标左键"时,模拟鼠标右键。

d)、input[i].mi.dwFlags中不用MOUSEEVENTF_ABSOLUTE,代表input[i].mi.dx或input[i].mi.dx中的坐标是相对于上一次鼠标事件时的坐标,而dx和dy都已被初始化为0,即在原地显示鼠标右键菜单;

e)、也可以在input[i].mi.dwFlags中使用MOUSEEVENTF_ABSOLUTE,此时是绝对坐标,input[i].mi.dx和input[i].mi.dx的计算如下(而不是直接使用当前鼠标位置,具体原因请查看MSDN):

PMSLLHOOKSTRUCT pllh = (PMSLLHOOKSTRUCT)lParam;//鼠标坐标等信息

int cx=GetSystemMetrics(SM_CXSCREEN);//得到屏幕宽度

int cy=GetSystemMetrics(SM_CYSCREEN);//得到屏幕高度

LONG dx = pllh->pt.x * 65535 / cx;

LONG dy = pllh->pt.y * 65535 / cy;

input[0].mi.dx = dx;

input[0].mi.dy = dy;

input[1].mi.dx = dx;

input[1].mi.dy = dy;

f)、在发送完模拟的鼠标右键事件后,需要return 1;来阻止消息的继续传递,而不是return CallNextHookEx(NULL,nCode,wParam,lParam);,不然会出现不正确的右键行为。

g)、需要发送鼠标右键按下和弹起两个事件,不然会出现不正确的右键行为。

h)、WM_LBUTTONDOWN映射的是逻辑鼠标按键,wParam == WM_LBUTTONDOWN表示鼠标左键按下。而MOUSEEVENTF_LEFTDOWN映射的是物理鼠标按键,input[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN对应已切换功能的真实鼠标左键,所以实际表示发送的是鼠标右键消息。MOUSEEVENTF_LEFTUP意义相仿。

3、在应用程序的ExitInstance()中卸载全局鼠标钩子:

UnhookWindowsHookEx(hhkMouseHook);

这样就完成了所需要的功能。当按下"Ctrl+鼠标左键" 或 "数字键盘减号键 + 鼠标左键"时,相当于按了右键。

posted on 2009-03-28 15:55 天堂露珠 阅读(2204) 评论(0)  编辑  收藏 所属分类: C++

java vk减号_[原]在全局鼠标钩子中模拟鼠标右键单击相关推荐

  1. java鼠标事件_Java 模拟鼠标事件

    导读热词 下面是编程之家 jb51.cc 通过网络收集整理的代码片段. 编程之家小编现在分享给大家,也给大家做个参考. @H_502_5@/** * Clicks in a given area of ...

  2. Windows下C/C++模拟鼠标点击,PC端没有鼠标设备也能够获取鼠标坐标、移动鼠标坐标、模拟鼠标点击事件,方法一 亲测有效

    ------- [ 转载请保留 ] ------- 作者:西_瓜_瓜 博客:https://blog.csdn.net/xi_gua_gua/article/details/105773298 --- ...

  3. java vk减号_Vue入门经常使用指令

    一.Vue 介绍 ​ Vue (读音 /vjuː/,相似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不一样的是,Vue 被设计为能够自底向上逐层应用.Vue 的核心库只关注视图层 ...

  4. java恋爱代码_陷入与代码的恋爱中:终生的爱情故事

    java恋爱代码 by Daragh Byrne 达拉·伯恩(Daragh Byrne) 陷入与代码的恋爱中:终生的爱情故事 (Falling in and out of love with code ...

  5. mac电脑配置java环境变量_教你在Mac系统中配置JAVA环境变量的方法

    Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承.指针等概念,因此Java语言具有功能强大和简单易用两个特征.下面向大家介绍Mac电脑上如何配置Java ...

  6. java input属性_如何在h:inputText中指定命令属性?

    我有一个函数,我在我的经理中derclare bean,我想在inputText中返回值,但是当我将函数的名称放在inputText标记的value属性中时,如下所示: 出现此错误: Etat HTT ...

  7. java绘制流程图_如何才能更好地绘制计算机毕业设计中各种图表

    " 毕设论文中的各种图表是不可或缺的,如果只是单纯的文字,或者图表较少,达不到要求的话,最终是通过不了答辩审核的!" 目前绘制图表的软件很多,比如VISIO等,切记尽量不要使用wo ...

  8. python控制鼠标_如何使用Python在Mac中控制鼠标?

    尝试this page的代码.它定义了几个函数,mousemove和mouseclick,它们融合了Apple与Python平台的Quartz库之间的集成. 这段代码适用于10.6,我在10.7上使用 ...

  9. java关闭服务_实现优雅地关闭Docker中的java服务

    时至今日,Docker在项目中的应用越来越普遍了,但往往会遭遇一些麻烦,比如说,有几个请求至Docker中的服务,发起了事务处理业务,但每个事务完成可能需要1-5分钟,而此时我们正要将Docker停机 ...

最新文章

  1. fedora mysql 客户端_fedora mysql 安装
  2. 比较简单的c语言编辑器,大佬们,小菜鸟想问一问用vc编译器做简易画图软件
  3. python - os模块
  4. 2.5 隐藏委托关系
  5. leetcode 977. 有序数组的平方(双指针)
  6. uC/OS-II源码分析(二)
  7. 关于shiro授权 This subject is anonymous - it does not have any identifying principals and authorization
  8. angular 实现无限极联动下拉
  9. Github Page搜索工具更新 - 收藏,手气不错
  10. Atitit 云计算体系树.docx Atitit 云计算之道 attilax著 艾龙 著 serverless bomb 1. 什么才是云计算的根本特征.. 2 2. 云计算体系 2 3. “云
  11. php header带session,PHP接口跨域header头以及Session跨域方法
  12. 计算机病毒鬼畜,[原创]彩虹猫病毒的逆向
  13. 【统计学】分类数据分析 相关分析 方差分析 比较 研究思路 spss
  14. 计算机关机又自动重启,电脑关机后自动重启是什么原因?Win10关机变重启原因及解决方法...
  15. 石家庄地铁选站系统进度报告
  16. oCPC和oCPM的本质区别是什么?
  17. 华三模拟器之OSPF实验
  18. 7-3 打印九九口诀表
  19. 命令行导入 .dmp文件,亲测可行
  20. wsl1升级到 wsl2 后高cpu占用解决方案

热门文章

  1. java 蓝牙指定连接失败_java – 蓝牙:服务发现失败
  2. 少了很多东西的生活……
  3. 语音识别学习资料入门整理
  4. FusionCharts基本属性
  5. Java Swing+Mysql实现汽车租赁系统
  6. java去掉cdata_Java XmlCDATA类代码示例
  7. Excel2016打开文件空白
  8. Orientdb基本操作
  9. OrientDB基本使用
  10. grub和grub2区别