设置活动窗口 AttachThreadInput SetForegroundWindow
2015-11-20 19:01
417 查看
最近一直在使用RainMeter制作桌面,需要屏蔽Win按键,并使Win按键触发自己的菜单。
在网上没有找到直接适合我用的,后来根据前人的步伐,尝试出来适用于这个情况的方法。
现在我觉得这个方法挺实用的,所以在这里分享一下。
说明
方法
AttachThreadInput
SetForegroundWindow
解决方案
我用这个工具制作自己的桌面,在RainMeter插件中,使用全局钩子,去屏蔽Win按键,理所当然的简单的几个Win组合快捷键就被屏蔽了,但是Win+L没有屏蔽,这里就不做讨论。在屏蔽了Win按键时,做了处理,使得按Win键弹出自己定义的菜单,并设置菜单为活动窗口,来响应↑↓←→、回车按键。
SwitchToThisWindow,也挺多的。后面连SendMessage都用上了,搞到我头都大了,就差没有直接发送鼠标事件去激活窗口了。
后来发现了用人使用AttachThreadInput和SetForegroundWindow的组合来设置活动窗口。
我引用一个别人的——如何将当前窗口带到带到最顶层,并设置为活动窗口
因为我弹出来的菜单完成后,再按一下win键要把菜单隐藏,并把焦点还给弹出菜单前的窗口。用他的方法中,代码窗口就是当前活动窗口,可以设置。
但是在我的情况,代码运行的线程就没有窗口,结果只能完成我的前半步,后半步有问题,有时连前半步都不行。
根据他的方法,去各种尝试,根本触摸不到它系统的怎么跑的,都快吐血了。但是皇天不负有心人啊,最终还是解决了。用的就是这两个函数AttachThreadInput和SetForegroundWindow。
我的代码中,当前线程不是活动窗口,所以我用了两次AttachThreadInput。
先把当前线程和活动窗口线程的输入队列连接起来
再把活动窗口线程的输入队列和待设置为活动窗口的线程连在一起
调用SetForegroundWindow,把指定窗口设置为前端窗口,并成为活动状态。
焦点的话,有没有在这个上面不太清楚,不过这个设置应该不难,这里不多说。
经过这样,终于把设置活动窗口这一步做好了,告一段落。
不知道你们有没有发现,其实,如果我的菜单是一个Win32窗口,只需要打开一下,设置一个位置,后面关闭菜单,活动窗口就会自动回到上一个窗口,也就不需要那么多设置活动窗口了。
问题就是RainMeter的窗口很奇葩,不能用Win32窗口去衡量,到底是怎么我也不懂,因为我是个菜鸟,对windows的东西还不是太懂。
现在能满足自己的需求就算了,搞了那么多天,终于搞通了,记录一下自己的成果!O(∩_∩)O
后续:2016年1月5日17:31:29
SwitchToThisWindow 这个函数我今天试了一下,可以用的。不知道当时为什么不能用,不知道是不是使用情况不一样,大家在用的时候,可以先考虑这个函数
在网上没有找到直接适合我用的,后来根据前人的步伐,尝试出来适用于这个情况的方法。
现在我觉得这个方法挺实用的,所以在这里分享一下。
说明
方法
AttachThreadInput
SetForegroundWindow
解决方案
说明
RainMeter,可能有些人听过,一个制作自定义桌面很强大的工具,到底多强大,我这里就不说了,总之就强大。我用这个工具制作自己的桌面,在RainMeter插件中,使用全局钩子,去屏蔽Win按键,理所当然的简单的几个Win组合快捷键就被屏蔽了,但是Win+L没有屏蔽,这里就不做讨论。在屏蔽了Win按键时,做了处理,使得按Win键弹出自己定义的菜单,并设置菜单为活动窗口,来响应↑↓←→、回车按键。
方法
网上一搜,各种方法,总结一下,无奈就这几个SetFocus、ShowWindow、SetForegroundWindow、SetActiveWindow、SwitchToThisWindow,也挺多的。后面连SendMessage都用上了,搞到我头都大了,就差没有直接发送鼠标事件去激活窗口了。
后来发现了用人使用AttachThreadInput和SetForegroundWindow的组合来设置活动窗口。
我引用一个别人的——如何将当前窗口带到带到最顶层,并设置为活动窗口
因为我弹出来的菜单完成后,再按一下win键要把菜单隐藏,并把焦点还给弹出菜单前的窗口。用他的方法中,代码窗口就是当前活动窗口,可以设置。
但是在我的情况,代码运行的线程就没有窗口,结果只能完成我的前半步,后半步有问题,有时连前半步都不行。
根据他的方法,去各种尝试,根本触摸不到它系统的怎么跑的,都快吐血了。但是皇天不负有心人啊,最终还是解决了。用的就是这两个函数AttachThreadInput和SetForegroundWindow。
AttachThreadInput
AttachThreadInput 的使用方法我就直接百度百科SetForegroundWindow
——百度百科解决方案
先上我自己的代码,这个是在钩子钩Win按键处理的:/* 弹出dalong菜单 */ static HWND previousFocusWnd = NULL; static HWND rmWnd = NULL; if ( previousFocusWnd && rmWnd == GetForegroundWindow() ) { SendMessage( rmWnd, WM_KILLFOCUS, 0, 0 ); AttachThreadInput( GetWindowThreadProcessId( rmWnd, NULL ), GetCurrentThreadId(), TRUE ); AttachThreadInput( GetWindowThreadProcessId( previousFocusWnd, NULL ), GetWindowThreadProcessId( rmWnd, NULL ), TRUE ); SetForegroundWindow( previousFocusWnd ); AttachThreadInput( GetWindowThreadProcessId( previousFocusWnd, NULL ), GetWindowThreadProcessId( rmWnd, NULL ), FALSE ); AttachThreadInput( GetWindowThreadProcessId( rmWnd, NULL ), GetCurrentThreadId(), FALSE ); previousFocusWnd = NULL; rmWnd = NULL; return(TRUE); }else { previousFocusWnd = GetForegroundWindow(); //菜单窗口句柄 rmWnd = FindWindowA( "", "" ); AttachThreadInput( GetWindowThreadProcessId( previousFocusWnd, NULL ), GetCurrentThreadId(), TRUE ); AttachThreadInput( GetWindowThreadProcessId( previousFocusWnd, NULL ), GetWindowThreadProcessId( rmWnd, NULL ), TRUE ); SendMessage( rmWnd, WM_SETFOCUS, 0, 0 ); SetForegroundWindow( rmWnd ); AttachThreadInput( GetWindowThreadProcessId( previousFocusWnd, NULL ), GetWindowThreadProcessId( rmWnd, NULL ), FALSE ); AttachThreadInput( GetWindowThreadProcessId( previousFocusWnd, NULL ), GetCurrentThreadId(), FALSE ); }
我的代码中,当前线程不是活动窗口,所以我用了两次AttachThreadInput。
先把当前线程和活动窗口线程的输入队列连接起来
再把活动窗口线程的输入队列和待设置为活动窗口的线程连在一起
调用SetForegroundWindow,把指定窗口设置为前端窗口,并成为活动状态。
焦点的话,有没有在这个上面不太清楚,不过这个设置应该不难,这里不多说。
经过这样,终于把设置活动窗口这一步做好了,告一段落。
不知道你们有没有发现,其实,如果我的菜单是一个Win32窗口,只需要打开一下,设置一个位置,后面关闭菜单,活动窗口就会自动回到上一个窗口,也就不需要那么多设置活动窗口了。
问题就是RainMeter的窗口很奇葩,不能用Win32窗口去衡量,到底是怎么我也不懂,因为我是个菜鸟,对windows的东西还不是太懂。
现在能满足自己的需求就算了,搞了那么多天,终于搞通了,记录一下自己的成果!O(∩_∩)O
后续:2016年1月5日17:31:29
SwitchToThisWindow 这个函数我今天试了一下,可以用的。不知道当时为什么不能用,不知道是不是使用情况不一样,大家在用的时候,可以先考虑这个函数
相关文章推荐
- JAVA架构师
- 树状数组+dp(不太懂) Codeforces 597C
- java 类文件类型
- socket与TCP/IP协议族的关系
- AngularJS进阶(七)实现根据不同条件显示不同控件
- 几个python语法知识(一)
- AngularJS进阶(七)实现根据不同条件显示不同控件
- 【面试】Handler机制与通信的实现
- VS2013和VS2008项目的互通
- 判断两个时间段是否重合
- 使用libtomcrypt时候出现无法找到rijndael_enc_desc问题解决方法
- Supporting Python 3(支持python3)——语言区别和暂时解决方法
- OC基本语法
- python之倒序字符串
- 计算机视觉领域的一些牛人博客,超有实力的研究机构等的网站链接
- ELK日志管理之——elasticsearch部署
- 一个研究生导师的肺腑直言
- 麻省理工公开课:线性代数_学习笔记02
- h5 播放音频文件
- ELK日志管理之——elasticsearch部署