ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 2664|回复: 2

[原创] 解决SetForeGroundWindow“失效”的办法

[复制链接]

TA的精华主题

TA的得分主题

发表于 2018-12-9 16:15 | 显示全部楼层 |阅读模式
在某些情况下,我们希望把某个窗口自动激活,比如,下午3点钟要参加项目调度例会,因此,希望提前10分钟弹出提示窗口并且确保该窗口在最前端显示出来。
这种情况,就需要使用SetForeGroundWindow来激活指定的提示窗口。
但是,很多人试过用SetForeGroundWindow激活指定窗口,发现只能使该窗口的任务栏图标闪烁而不能真正让该窗口激活。
那么,为什么SetForeGroundWindow会“失效”呢?又如何来解决这种问题呢?
查看MSDN对该函数的解释:
The system restricts which processes can set the foreground window. A process can set the foreground window only if one of the following conditions is true:
1、The process is the foreground process.
2、The process was started by the foreground process.
3、The process received the last input event.
4、There is no foreground process.
5、The foreground process is being debugged.
6、The foreground is not locked (see LockSetForegroundWindow).
7、The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
我们可以了解到,要确保SetForeGroundWindow成功,至少要满足上述7个条件中的一个条件。

因此,我们可以把SetForeGroundWindow命令附加到当前活动线程中去使之得到执行,即通过满足条件1来使得该命令成功运行。此种解决方法,需要获取当前前台窗口的线程ID,并给该线程附加输入命令,因此,还需要用到以下4个Win32 API函数:
GetForegroundWindow
GetWindowThreadProcessId
GetCurrentThreadId
AttachThreadInput

具体实现如下(以在EXCEL VBA环境中举例):
  1. #If Win64 Then
  2.     Private Declare PtrSafe Function GetForegroundWindow Lib "user32" () As Long
  3.     Private Declare PtrSafe Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
  4.     Private Declare PtrSafe Function GetCurrentThreadId Lib "kernel32" () As Long
  5.     Private Declare PtrSafe Function AttachThreadInput Lib "user32" (ByVal idAttach As Long, ByVal idAttachTo As Long, ByVal fAttach As Long) As Long
  6.     Private Declare PtrSafe Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
  7. #Else
  8.     Private Declare Function GetForegroundWindow Lib "user32" () As Long
  9.     Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
  10.     Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long
  11.     Private Declare Function AttachThreadInput Lib "user32" (ByVal idAttach As Long, ByVal idAttachTo As Long, ByVal fAttach As Long) As Long
  12.     Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
  13. #End If

  14. Sub 按钮1_单击()
  15.     Application.OnTime Now + TimeValue("00:00:05"), "显r_定时"
  16. End Sub
  17. '求问:
  18. '怎么恢复excel的窗口排在最前面,并显示msgbox窗口

  19. Sub 显r_定时()
  20.     Dim hCurWnd As Long, dwCurID As Long, dwMyID As Long
  21.    
  22.     hCurWnd = GetForegroundWindow() '获取前台窗口句柄
  23.     dwCurID = GetWindowThreadProcessId(hCurWnd, 0) '根据前台窗口句柄,获取其线程ID
  24.     dwMyID = GetCurrentThreadId() '获取本程序的线程ID
  25.     AttachThreadInput dwCurID, dwMyID, True '把本程序的输入命令附加到指定的线程(即台前窗口的线程)
  26.    
  27.     '-------------------------激活指定窗口
  28.     'SetForegroundWindow ThisWorkbook.Windows(1).hwnd
  29.     ThisWorkbook.Activate '在Excel VBA中,ThisWorkbook.Activate等效于SetForegroundWindow ThisWorkbook.Windows(1).hwnd
  30.     MsgBox "答案是可以看见这个窗口"
  31.     '--------------------------
  32.     AttachThreadInput dwCurID, dwMyID, False '切断附加关系。此时,指定的窗口成为真正的前台窗口。
  33. End Sub
复制代码


这里,AttachThreadInput函数很关键,可以说,它就是抢话筒的,雅称“麦霸”。如果没有它,SetForegroundWindow的发言是不被“重视”的,只能让窗口的任务栏图标闪烁一两下而已。

最前端显示.rar (13.66 KB, 下载次数: 100)

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2019-11-23 21:28 | 显示全部楼层
请问,知道程序的标题或者进程如何激活窗口到最前?谢谢!

TA的精华主题

TA的得分主题

发表于 2024-8-30 11:49 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
ndt3 发表于 2019-11-23 21:28
请问,知道程序的标题或者进程如何激活窗口到最前?谢谢!

Sub test()
Dim wsh As Object
Set wsh = CreateObject("wscript.shell")
wsh.AppActivate ("无标题 - 记事本")
wsh.SendKeys "% r" '如窗口最小化时,恢复原来大小。 % x是最大化,% n是最小化
End Sub
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-18 18:41 , Processed in 0.037845 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表