场景是使用WPS运行VBA程序,程序过程中会打开和关闭多个文件,然后每次打开文件WPS窗口就会抢夺焦点,使其窗口前置
由于程序运行需时比较长,所以我会同时去操作其他窗口;这种抢焦点就导致本来在其他窗口的操作被应用在WPS窗口中,轻则把内容输入到刚打开的文件中,重则中断了程序,导致要从头运行……
有什么工具可以阻止某进程抢夺焦点吗?最好是按规则指定进程
感觉不如粗暴解决问题,直接开个虚拟桌面试试
试试用ahk设置窗口扩展样式
winset,ExStyle,0x08000000,窗口id
依然会抢,无论是针对 wps.exe 还是 et.exe 获取窗口ID
即使问AI得到代码:
#Persistent
#NoEnv
SetBatchLines, -1
; 定义 WPS 窗口的类名(可能需要调整)
WPS_ClassName := "WordPadClass" ; 示例:WordPadClass(WPS 可能不同,需用 Spy++ 查看)
; 主循环,定期检查并修改 WPS 窗口属性
SetTimer, CheckWPSWindows, 500
return
CheckWPSWindows:
; 查找所有 WPS 窗口
WinGet, WPS_Windows, List, ahk_class %WPS_ClassName%
Loop, %WPS_Windows%
{
hwnd := WPS_Windows%A_Index%
; 检查窗口是否可见(可选)
WinGet, Style, Style, ahk_id %hwnd%
if (Style & 0x10000000) ; WS_VISIBLE
{
; 移除 WS_EX_TOPMOST(防止置顶)
WinSet, AlwaysOnTop, Off, ahk_id %hwnd%
; 使用 DllCall 调用 SetWindowLongPtr(64位兼容)
; 注意:WS_EX_NOACTIVATE = 0x08000000
DllCall("SetWindowLongPtr", "Ptr", hwnd, "Int", -20, "Ptr", (DllCall("GetWindowLongPtr", "Ptr", hwnd, "Int", -20) | 0x08000000))
; 或者直接使用 SetWindowLong(32位兼容,但可能不适用于 64 位系统)
; DllCall("SetWindowLong", "Ptr", hwnd, "Int", -20, "Int", (DllCall("GetWindowLong", "Ptr", hwnd, "Int", -20) | 0x08000000))
}
}
return
也一样,只是让WPS的窗口不在任务量显示按钮,该抢焦点还是会抢焦点
——
——
或者有没办法是让VBA读写Excel文件但不显示所读写文件的窗口的?
你的意思是虚拟机是吧?这会比较折腾……
意思是在 win10\11新建个桌面吧,在新桌面再运行你的vbs,wps应该不至于自己跳到新桌面上吧?
我本来就一直在用Win10虚拟桌面,WPS抢焦点时会直接自动切换回它所在的桌面(应该是Windows 的机制,哪个桌面有窗口弹出就自动切换到该桌面)
- 最小化方式启动
- AHK脚本
#Persistent
SetTimer, WatchForeground, 100
Return
WatchForeground:
WinGet, activeProcess, ProcessName, A
if (activeProcess = "notepad.exe") {
WinMinimize, ahk_exe notepad.exe
}
Return
我怎么记得以前好像是不跳的?还是我记错了。刚试了下,其他软件也跳 ![]()
都用vba了,不如用其他的语言,比如python或者r
或者是一个好想法,但目前来说VBA还是相当方便直观
——
刚才看了下Python的区域复制代码,就挺复杂的,但在AI的回答中还是得到了些启发,就是在主要代码段前后加上:
Application.Visible = False
[main process]
Application.Visible = True
这个运行过程中就不再弹窗(也就不会抢焦点;只是在我的程序中明明所有打开文件的代码都包在中间了,依然会在运行之初先弹几次窗……不解),虽然WPS的“窗框”和任务栏按钮依然会显示,但如果切换到其他窗口再点WPS的任务栏按钮的话,WPS窗口也不会有反应;直到最后运行完成再抢焦点;而且感觉比之前要快(不过程序中设置在任务栏显示运行进度的代码也没效果了)。
反正这对于VBA运行程序抢焦点的问题就算是解决了。
——
但还是希望有能阻止程序抢焦点(使其顶多只能闪任务栏按钮),或者“守护”当前程序焦点状态的工具。
可以考虑这个帖子里面的方法, 另外就是其他的窗口前置的软件应该也可以实现。
但是还是感觉如果你要处理的文件比较多的话, 可以交给python或者R来解决。
这里面介绍的是置顶窗口的方法,并没有守护焦点
有需要的话可以考虑
python 可以直接读取 excel 文件,不需要安装 excel 或者 wps
用虚拟机。
wps使用vba本身就是需要抢进程。
你这是又让马儿跑, 还让马儿不迈腿。 ![]()
根据我的经验有两种可能方案,如果都不行就彻底没戏。
一个是窗口置底(使目标窗口作为桌面的子窗口),一个是令窗口彻底透明。
抢进程没问题,但它抢焦点啊……不过这已经解决了
置底就是一旦发现某窗口是当前窗口,就马上将其发送到窗口序列最后,那也是一种事后应对,只要我按键的时机刚好不是其抢焦点的时刻;彻底透明只不过是皇帝的新窗口…… ![]()
并不是哦,我说的置底是这个:
另外完全透明的窗口是不会抢激活和焦点的,不过问题是有的窗口无法完全透明,你可以试试。
用工具挂起试试