在SetForegroundWindow之前比较早的时候(比如main函数里)调用一下以下代码:

  1. DWORD dwTimeout = -1;
  2. SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)&dwTimeout, 0);
  3. if (dwTimeout >= 100) {
  4. SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID)0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
  5. }

就可以了,后果是如果执行到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的正确用法的更多相关文章

  1. Spring MVC中Session的正确用法<转>

    Spring MVC是个非常优秀的框架,其优秀之处继承自Spring本身依赖注入(Dependency Injection)的强大的模块化和可配置性,其设计处处透露着易用性.可复用性与易集成性.优良的 ...

  2. C#中dynamic的正确用法

    C#中dynamic的正确用法  http://www.cnblogs.com/qiuweiguo/archive/2011/08/03/2125982.html dynamic是FrameWork4 ...

  3. C# string.Split对于换行符的分隔正确用法

    C# string.Split对于换行符的分隔正确用法 tmpCase "11117144-8c91-4817-9b92-99ec2f9d784a\r\n23D95A26-012C-4332 ...

  4. 【转】Spring MVC中Session的正确用法之我见

    Spring MVC是个非常优秀的框架,其优秀之处继承自Spring本身依赖注入(Dependency Injection)的强大的模块化和可配置性,其设计处处透露着易用性.可复用性与易集成性.优良的 ...

  5. 转载~kxcfzyk:Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解

    Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解   多线程c语言linuxsemaphore条件变量 (本文的读者定位是了解Pthread常用多线程API和Pthread互斥锁 ...

  6. C#中dynamic的正确用法 以及 typeof(DynamicSample).GetMethod("Add");

    dynamic是FrameWork4.0的新特性.dynamic的出现让C#具有了弱语言类型的特性.编译器在编译的时候不再对类型进行检查,编译期默认dynamic对象支持你想要的任何特性.比如,即使你 ...

  7. 【转】改善C#程序的建议2:C#中dynamic的正确用法 空间

    dynamic是FrameWork4.0的新特性.dynamic的出现让C#具有了弱语言类型的特性.编译器在编译的时候不再对类型进行检查,编译期默认dynamic对象支持你想要的任何特性.比如,即使你 ...

  8. C#中dynamic、ExpandoObject 的正确用法

    原文地址:http://www.cnblogs.com/qiuweiguo/archive/2011/08/03/2125982.html dynamic是FrameWork4.0的新特性.dynam ...

  9. C#中dynamic的正确用法【转】

    dynamic是FrameWork4.0的新特性.dynamic的出现让C#具有了弱语言类型的特性.编译器在编译的时候不再对类型进行检查,编译期默认dynamic对象支持你想要的任何特性.比如,即使你 ...

随机推荐

  1. Centos 7 JDK验证 解决java -version 报错: bash: /home/jdk1.8.0_161/bin/java: Permission denied

    2.vim /etc/profile  编辑profile  文件,在里面添加: #set java enviroment JAVA_HOME=/usr/java/jdk1.8.0_144 JRE_H ...

  2. jQuery插件--根据数据加载的进度动画案例

    css: *{ margin:; padding:; } @media screen and (min-width:320px){ html{font-size:12px;}} @media scre ...

  3. chkconfig---检查设置系统服务

    chkconfig命令   chkconfig命令检查.设置系统的各种服务.这是Red Hat公司遵循GPL规则所开发的程序,它可查询操作系统在每一个执行等级中会执行哪些系统服务,其中包括各类常驻服务 ...

  4. 源码安装 ipython

    https://blog.csdn.net/huobanjishijian/article/details/51470898

  5. _00018 Hadoop-2.2.0 + Hbase-0.96.2 + Hive-0.13.1 分布式环境整合,Hadoop-2.X使用HA方式

    博文作者:妳那伊抹微笑 itdog8 地址链接 : http://www.itdog8.com(个人链接) 博客地址:http://blog.csdn.net/u012185296 个性签名:世界上最 ...

  6. Qt程序调试之Q_ASSERT断言(它是一个宏,接受布尔值,当其中的布尔值为真时,便什么也不做)

    在使用Qt开发大型软件时,难免要调试程序,以确保程序内的运算结果符合我们的预期.在不符合预期结果时,就直接将程序断下,以便我们修改. 这就用到了Qt中的调试断言 - Q_ASSERT. 用一个小例子来 ...

  7. IAR FOR STM8 学习笔记 IAR工程的建立

    STM8是ST意法半导体针对工业应用和消费电子开发而推出的8位单片机. 每种MCU都有自身的优点与缺点,与其它8-bit MCU相比,STM8 8-bit MCU最大的特点是: · 内核: o 最高f ...

  8. Linux在应用层读写寄存器的方法。。。

    参考链接:http://blog.csdn.net/liukang325/article/details/26601811 /dev/mem:物理内存的全镜像.可以用来访问物理内存.由于应用运行都在用 ...

  9. 91.生成ini文件并写入和读取ini文件

    写入 WritePrivateProfileStringA("hello money", infx[i].name, money, "1.ini"); 按照字符 ...

  10. 洛谷 P2025 脑力大人之监听电话

    P2025 脑力大人之监听电话 题目背景 画外音: (声明:不要管前面那个,纯属意外,现已经重新编题,绝对原创) 上次海选,我们选出了参赛者中的20%参加本次比赛,现在我们将进行第二轮的筛选,这次的比 ...