设置活动窗口 AttachThreadInput SetForegroundWindow

原创 2015年11月20日 19:01:04

最近一直在使用RainMeter制作桌面,需要屏蔽Win按键,并使Win按键触发自己的菜单。
在网上没有找到直接适合我用的,后来根据前人的步伐,尝试出来适用于这个情况的方法。
现在我觉得这个方法挺实用的,所以在这里分享一下。


说明

RainMeter,可能有些人听过,一个制作自定义桌面很强大的工具,到底多强大,我这里就不说了,总之就强大。
我用这个工具制作自己的桌面,在RainMeter插件中,使用全局钩子,去屏蔽Win按键,理所当然的简单的几个Win组合快捷键就被屏蔽了,但是Win+L没有屏蔽,这里就不做讨论。在屏蔽了Win按键时,做了处理,使得按Win键弹出自己定义的菜单,并设置菜单为活动窗口,来响应↑↓←→、回车按键。

方法

网上一搜,各种方法,总结一下,无奈就这几个SetFocusShowWindowSetForegroundWindowSetActiveWindow
SwitchToThisWindow,也挺多的。后面连SendMessage都用上了,搞到我头都大了,就差没有直接发送鼠标事件去激活窗口了。

后来发现了用人使用AttachThreadInputSetForegroundWindow的组合来设置活动窗口。
我引用一个别人的——如何将当前窗口带到带到最顶层,并设置为活动窗口

因为我弹出来的菜单完成后,再按一下win键要把菜单隐藏,并把焦点还给弹出菜单前的窗口。用他的方法中,代码窗口就是当前活动窗口,可以设置。
但是在我的情况,代码运行的线程就没有窗口,结果只能完成我的前半步,后半步有问题,有时连前半步都不行。
根据他的方法,去各种尝试,根本触摸不到它系统的怎么跑的,都快吐血了。但是皇天不负有心人啊,最终还是解决了。用的就是这两个函数AttachThreadInputSetForegroundWindow

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

  1. 先把当前线程和活动窗口线程的输入队列连接起来
  2. 再把活动窗口线程的输入队列和待设置为活动窗口的线程连在一起
  3. 调用SetForegroundWindow,把指定窗口设置为前端窗口,并成为活动状态。

焦点的话,有没有在这个上面不太清楚,不过这个设置应该不难,这里不多说。
经过这样,终于把设置活动窗口这一步做好了,告一段落。

不知道你们有没有发现,其实,如果我的菜单是一个Win32窗口,只需要打开一下,设置一个位置,后面关闭菜单,活动窗口就会自动回到上一个窗口,也就不需要那么多设置活动窗口了。
问题就是RainMeter的窗口很奇葩,不能用Win32窗口去衡量,到底是怎么我也不懂,因为我是个菜鸟,对windows的东西还不是太懂。

现在能满足自己的需求就算了,搞了那么多天,终于搞通了,记录一下自己的成果!O(∩_∩)O

后续:2016年1月5日17:31:29
SwitchToThisWindow 这个函数我今天试了一下,可以用的。不知道当时为什么不能用,不知道是不是使用情况不一样,大家在用的时候,可以先考虑这个函数

版权声明:本文为博主原创文章,未经博主允许不得转载。

常用活动界面设置

隐藏标题栏 在项目开发过程中常常需要隐藏掉标题栏,方法如下: 在onCreate方法中加入:requestWindowFeature(Window.FEATURE_NO_TITL); 这句话的意思就是...
  • river_lj
  • river_lj
  • 2015年01月20日 09:44
  • 396

MFC程序多窗口引起的激活和非激活问题

公司的项目一直都是基于MFC开发的,界面上面布满了各种各样的窗口,有时候就会出现一些奇怪的现象。我就是写了这么一篇文章来记录下自己遇到的奇怪现象。 1、在我的程序中,有一个CView的派生类窗口。上面...
  • u011644552
  • u011644552
  • 2015年05月22日 08:55
  • 1644

c# 获取当前活动窗口句柄,获取窗口大小及位置

需调用API函数 需在开头引入命名空间 using System.Runtime.InteropServices; 获取当前窗口句柄:GetForegroundWindow() [DllI...
  • pangwenquan5
  • pangwenquan5
  • 2014年10月20日 21:09
  • 17201

VC获取其它程序窗口焦点方法 AttachThreadInput的用法

1、不同线程的处理方法 如何在2K/xp下使窗口获取焦点 //捕捉并设置当前焦点窗口为我们的窗口 AttachThreadInput(     GetWindowThreadPro...
  • kaizi318
  • kaizi318
  • 2013年04月10日 17:48
  • 11954

无需Windows活动窗口进行音量控制

  • 2013年03月21日 17:51
  • 237KB
  • 下载

a63822322的解决活动窗口按钮被改写的说明

  • 2010年08月27日 14:15
  • 177B
  • 下载

用Delphi做的定时抓取活动窗口

  • 2007年11月24日 18:16
  • 10KB
  • 下载

android四大金刚(组件)之-:Activity(活动窗口)

Activity : 1:应用程序中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。 2:Activity之间通过Intent进行通信。在I...
  • ma20120607
  • ma20120607
  • 2015年04月02日 12:53
  • 326

任务栏中间的活动窗口图标不见了怎么办

任务栏中间的活动窗口图标不见了怎么办? 解决方法如下: 把以下文本另存为xp_taskbar_desktop_fixall_chs.vbs双击运行即可。 'xp_taskbar_desk...
  • chruan
  • chruan
  • 2012年02月22日 14:15
  • 5641

弹出对话框源代码中抓取活动窗口图片

void CAppsnapApp::OnHelpTest() {  // TODO: Add your command handler code here  CBmpSnapTest testD...
  • m372897500
  • m372897500
  • 2011年08月17日 11:49
  • 526
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:设置活动窗口 AttachThreadInput SetForegroundWindow
举报原因:
原因补充:

(最多只允许输入30个字)