如何防止屏幕键盘聚焦于最后一个最小化的窗口

如何防止屏幕键盘聚焦于最后一个最小化的窗口

我很喜欢使用屏幕键盘,但是有一个烦人的问题。

如果我使用 Google Chrome(例如)并使用屏幕键盘将其最小化,然后最小化屏幕键盘并打开另一个程序(如记事本)(屏幕键盘应该保持聚焦在记事本上)它会最大化 Google Chrome,所以我必须再次单击记事本。

似乎屏幕键盘控制打开的窗口顺序,并且当我单击屏幕键盘以最大化时,屏幕键盘焦点会停留在最后一个最小化的窗口上,而不是集中在最后一个窗口上。

我该如何解决这个问题?

答案1

我已经将这个极其烦人的错误一直追溯到 Windows XP,所以这实际上是一个 17 年前的错误,仍然尚未修复 (!)。

这个错误也在这里讨论,但是线程已被锁定,您无法进一步讨论这个问题:

https://answers.microsoft.com/en-us/windows/forum/windows8_1-desktop/how-to-prevent-on-screen-keyboard-from-focus-on/2e6c7d6b-f59e-4b95-b37e-487ff33dbda3

osk.exe我设法通过加载到 x64dbg、分析问题所在,然后使用调试器修补代码来创建一个简单的修复程序(请参阅下面的说明)。

所发生的情况是,它osk.exe会持续存储最后一个活动窗口,以便在鼠标悬停在 OSK 上或用户恰好激活 OSK 时聚焦此窗口。这样会始终将焦点放在最后一个活动窗口上,从而确保使用 OSK 键入时输入会到达应在的位置。

问题是osk.exe当 OSK 最小化时停止存储活动窗口。

这就是错误所在。

现在,当您恢复最小化的 OSK 时,它会失去记忆,只记得最小化之前的最后一个活动窗口。因此,现在它将聚焦这个旧窗口,而不是之前真正的活动窗口。

我使用的“修复”只是防止 OSK 强制任何窗口获得焦点。您只需osk.exe为此修复修补一个字节,这就是我选择它的原因。否则,任何其他修补程序都会非常复杂。

在 x64dbg 中,您只需搜索对 的所有引用。此 Win32 方法只有两次调用。第一个引用是要修补的引用。在对 的调用之前SetForegroundWindow有一条指令。只需用替换,保存为,然后用这个修补版本替换原始版本即可。push eaxSetForegroundWindowpush eaxretosk.exeosk.exe

osk.exe 的 x64dbg 视图

问题解决了。

这不是一个 100% 的解决方案,因为 OSK 自动激活的便利性消失了,但这样还是比较好,没有原来的烦恼。可以使用 AutoHotKey 恢复自动激活。

在这里留言,如果有人需要,我会发布脚本。使用补丁 + AHK 脚本,您将拥有一个完全正常工作的 OSK,而没有烦人的原始错误。

答案2

适用于 Windows 10 Pro x64 版本 2004

非常感谢@Casper 的回答。我不知道如何使用 x64dbg 搜索引用,但发现在附加到osk.exe、执行bp SetForegroundWindow并继续执行最小化/恢复 osk 后,断点处发现了两个事件,但 osk 代码看起来与@Casper 的不同。将两个调用替换为 0x90(NOOP)解决了该问题。每个调用都是 7 个字节,因此运行 7 个 NOP 指令两次即可解决问题。

我选择将 osk.exe 复制到我自己的文件夹中,而不是破解 C:\Windows\System32 中的文件夹,因为在某些扫描仪看来,这个文件夹可能看起来像病毒。

请注意,osk.exe 会自行切换为管理员,并且 x64dbg 在连接到它时会要求以管理员身份重新启动。根据您的 ValidateAdminCodeSignatures 策略,这还可能导致在启动修补副本时出现“从服务器返回引用”错误。右键单击修补后的 osk.exe,选择属性、兼容性、“以管理员身份运行此程序”可解决此问题。

区别如下:

D:\Utils>fc /b osk.exe "osk - Copy.exe"
Comparing files osk.exe and OSK - COPY.EXE
0000921A: 90 48
0000921B: 90 FF
0000921C: 90 15
0000921D: 90 87
0000921E: 90 5E
0000921F: 90 01
00009220: 90 00
0000A56E: 90 48
0000A56F: 90 FF
0000A570: 90 15
0000A571: 90 33
0000A572: 90 4B
0000A573: 90 01
0000A574: 90 00

使用十六进制编辑器,您可以编辑 osk.exe 并转到这些偏移量,如果第二列中的字节与文件中的字节匹配,则只需将其替换为 90(十六进制)。由于 @Casper 只修补了第一个调用(带有 ret),因此可能只需要前 7 个 NOOP,但在我的例子中,所有 14 个都是必需的。两个 SetForegroundWindow 调用彼此非常接近,因此如果它们之间没有 ret,NOOP 允许整个函数正常运行,仅跳过 SetForegroundWindow 调用。

通过这种破解,键盘在恢复(未最小化)时具有焦点,而不是您想要输入的应用程序,因此仍然不完美。

编辑:仅更改第二个调用,从偏移量 A56E 开始的最后 7 个字节似乎有效。

答案3

正在寻找同样的东西,偶然发现了这个。

https://www.sevenforums.com/general-discussion/263571-unwanted-behavior-screen-keyboard-bug.html

显然,这个漏洞至少从 2013 年就已被发现。我认为目前还没有修复方案。

答案4

对于这个烦人的错误,对我来说最简单的解决方案是将屏幕键盘快捷键固定到任务栏,然后关闭它而不是最小化它。然后要在另一个窗口上重新打开虚拟键盘,我只需再次单击任务栏中的快捷方式,因为它的效果与单击最小化按钮相同。最小化而不是关闭它没有任何实际必要或优势。

相关内容