SetForegroundWindow的正确用法
在SetForegroundWindow之前比较早的时候(比如main函数里)调用一下以下代码:
- DWORD dwTimeout = -1;
- SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)&dwTimeout, 0);
- if (dwTimeout >= 100) {
- SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
- }
就可以了,后果是如果执行到if里面的语句,会因为user profile的更改回写和WM_SETTINGCHANGE的广播而导致这个API调用本身卡两三秒。
MSDN:http://msdn.microsoft.com/en-us/library/ms633539(v=VS.85).aspx 下面是谷歌翻译,有些语句不是很流畅。
SetForegroundWindow函数将创建指定的窗口,并激活到前台窗口的线程 。键盘输入窗口,并为用户更改不同的视觉线索。该系统分配一个优先略高前景的窗口,比它其他线程创建的线程。
语法
BOOL SetForegroundWindow(
HWND HWND );
参数
HWND
[in]应该被激活,并带到前景的窗口句柄。
返回值
如果窗口被带到前台,返回值为非零。
如果窗口不带到前景,返回值是零。
备注
Windows 98/Me的系统限制哪些进程可以设置前台窗口。一个进程可以设置前台窗口,仅当下列条件之一为真 :
这个过程是前台进程。
这个过程是由前台进程的开始。
过程中收到的最后一个输入事件。
没有前台进程。
前台进程正在被调试。
前景不被锁定(见LockSetForegroundWindow)。
前景锁定超时已过期(看到SPI_GETFOREGROUNDLOCKTIMEOUTSystemParametersInfo)。
Windows 2000/XP的:没有菜单处于活动状态。
这一变化,应用程序不能强制一个窗口到前台,而用户是另一个窗口的工作。相反,前台和后台的Windows激活窗口(见 SetActiveWindow)和调用函数通知用户 。然而,在Microsoft Windows 98和Windows Millennium Edition(Windows Me)中,如果一个nonforeground线程调用SetForegroundWindow,并通过一个没有被调用线程创建的窗口的句柄,窗口不闪现在任务栏上。SetForegroundWindow行为相同的,因为它没有在Windows 95和Microsoft Windows NT 4.0,安装应用程序时,更改前景色锁超时值 。这可以从下面的函数调用设置或安装应用程序:
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
这种方法允许在Windows 98/Windows Me和Windows 2000/Windows XPSetForegroundWindow行为作为Windows 95和Windows NT 4.0相同,分别为所有应用程序,。安装应用程序,这样做是使用户是不会改变的行为感到惊讶的用户发出警告。在Windows上的Windows 2000和Windows XP,调用失败,除非调用线程可以改变前台窗口,因此必须从一个安装或修补应用程序调用。欲了解更多信息,请参阅前景和背景窗口。
一个过程,可以设置前台窗口可以使另一个进程通过调用前台窗口AllowSetForegroundWindow功能。dwProcessId和所指定的过程中失去了到前台窗口设置下一次输入用户生成的能力,除非输入是在这个过程中,或在下一次进程调用AllowSetForegroundWindow,除非指定过程。
前台进程可以禁用调用SetForegroundWindow调用的LockSetForegroundWindow函数。
保证SetForegroundWindow成功
在SetForegroundWindow之前比较早的时候(比如main函数里)调用一下以下代码:
DWORD dwTimeout = -1;
SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)&dwTimeout, 0);
if (dwTimeout >= 100) {
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
}

HWND hForeWnd = NULL;
HWND hWnd= FindWindow(NULL, "");
DWORD dwForeID;
DWORD dwCurID; hForeWnd = GetForegroundWindow();
dwCurID = GetCurrentThreadId();
dwForeID = GetWindowThreadProcessId( hForeWnd, NULL );
AttachThreadInput( dwCurID, dwForeID, TRUE);
ShowWindow( hWnd, SW_SHOWNORMAL );
SetWindowPos( hWnd, HWND_TOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE );
SetWindowPos( hWnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOSIZE|SWP_NOMOVE );
SetForegroundWindow( hWnd );
AttachThreadInput( dwCurID, dwForeID, FALSE);

第一段代码:
后果是如果执行到if里面的语句,会因为user profile的更改回写和WM_SETTINGCHANGE的广播而导致这个API调用本身卡两三秒。
第二段代码:
设置当前某窗口为当前窗口,有几个步骤要做:
1.得到窗口句柄FindWindow
2.切换键盘输入焦点AttachThreadInput
3.显示窗口ShowWindow(有些窗口被最小化/隐藏了)
4.更改窗口的Zorder,SetWindowPos使之最上,为了不影响后续窗口的Zorder,改完之后,再还原
5.最后SetForegroundWindow
想必看到上述代码就明白了这个函数失败的原因了吧。
SetForegroundWindow的正确用法的更多相关文章
- Spring MVC中Session的正确用法<转>
Spring MVC是个非常优秀的框架,其优秀之处继承自Spring本身依赖注入(Dependency Injection)的强大的模块化和可配置性,其设计处处透露着易用性.可复用性与易集成性.优良的 ...
- C#中dynamic的正确用法
C#中dynamic的正确用法 http://www.cnblogs.com/qiuweiguo/archive/2011/08/03/2125982.html dynamic是FrameWork4 ...
- C# string.Split对于换行符的分隔正确用法
C# string.Split对于换行符的分隔正确用法 tmpCase "11117144-8c91-4817-9b92-99ec2f9d784a\r\n23D95A26-012C-4332 ...
- 【转】Spring MVC中Session的正确用法之我见
Spring MVC是个非常优秀的框架,其优秀之处继承自Spring本身依赖注入(Dependency Injection)的强大的模块化和可配置性,其设计处处透露着易用性.可复用性与易集成性.优良的 ...
- 转载~kxcfzyk:Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解
Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解 多线程c语言linuxsemaphore条件变量 (本文的读者定位是了解Pthread常用多线程API和Pthread互斥锁 ...
- C#中dynamic的正确用法 以及 typeof(DynamicSample).GetMethod("Add");
dynamic是FrameWork4.0的新特性.dynamic的出现让C#具有了弱语言类型的特性.编译器在编译的时候不再对类型进行检查,编译期默认dynamic对象支持你想要的任何特性.比如,即使你 ...
- 【转】改善C#程序的建议2:C#中dynamic的正确用法 空间
dynamic是FrameWork4.0的新特性.dynamic的出现让C#具有了弱语言类型的特性.编译器在编译的时候不再对类型进行检查,编译期默认dynamic对象支持你想要的任何特性.比如,即使你 ...
- C#中dynamic、ExpandoObject 的正确用法
原文地址:http://www.cnblogs.com/qiuweiguo/archive/2011/08/03/2125982.html dynamic是FrameWork4.0的新特性.dynam ...
- C#中dynamic的正确用法【转】
dynamic是FrameWork4.0的新特性.dynamic的出现让C#具有了弱语言类型的特性.编译器在编译的时候不再对类型进行检查,编译期默认dynamic对象支持你想要的任何特性.比如,即使你 ...
随机推荐
- c#中 xml和json 互相转换
--xml转json XmlDocument doc = new XmlDocument(); doc.LoadXml(result); string json = Newtonsoft.Json.J ...
- Socket实例之客户端向服务端数据库上传文件UI版
http://blog.csdn.net/su20145104009/article/details/52843735 首先实现分析: 1用户注册 客户单选择‘用户注册’,提示要输入用户名,密码,确认 ...
- vue2细节变化的用法
1.v-el和v-ref合并为一个属性:ref 原来:v-el:my-element 现在: ref="myElement", v-ref:my-component 变成了这样: ...
- JavaScript笔记(2)
-->变量的定义 1.取得并使用值是所有程序设计中的要点 2.JS中的变量是没有类型的,在JS中只有值才持有类型,变量所持有的是其对应值的类型. 3.变量的取名要符合标识符的规则: (1)一个J ...
- shutdown---系统关机
shutdown命令用来系统关机命令.shutdown指令可以关闭所有程序,并依用户的需要,进行重新开机或关机的动作. 语法 shutdown(选项)(参数) 选项 -c:当执行“shutdown - ...
- python 数字计算模块 decimal(小数计算)
from decimal import * a = Decimal('0.1')+Decimal('0.1')+Decimal('0.1')+Decimal('0.3') float(a) >& ...
- 微信小程序从零开始开发步骤(五)轮播图
上一章完成页面自定义分享,这一章来说说轮播图,最常见的一个轮播图,中间带小圆点,自动轮播. Swiper是滑动特效插件,面向手机.平板电脑等移动终端.能实现触屏焦点图.触屏Tab切换.触屏多图切换等常 ...
- CODEVS——T 3013 单词背诵
http://codevs.cn/problem/3013/ 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 De ...
- 洛谷P1316 丢瓶盖
题目描述 陶陶是个贪玩的孩子,他在地上丢了A个瓶盖,为了简化问题,我们可以当作这A个瓶盖丢在一条直线上,现在他想从这些瓶盖里找出B个,使得距离最近的2个距离最大,他想知道,最大可以到多少呢? 输入输出 ...
- qtcreator配置
如果是做嵌入式开发,那么宿主机使用的交叉编译的QT版本是必须和目标板上使用的qt版本一致的. 而且在路径上,如果qt使用的库如果不是放在目标板默认的连接库路径的话, 那么目标板qt程序就会到配置编译Q ...