怎么可以这么容易地窃取焦点?

时间:2017-09-04 10:23:36

标签: windows focus-stealing

在Windows 7上使用Outlook 2013,我创建了这个宏,只是为了测试它:

Private Sub Application_Reminder(ByVal Item As Object)
        Activeexplorer.Activate
End Sub

每当我处理不同的应用程序并启动Outlook提醒时,Outlook就会成为活动窗口,从我正在处理的应用程序中窃取焦点。

怎么可能?

我的意思是,我认为“Activeexplorer.Activate”方法使用一些Windows api,如“SetForegroundWindow”或者“SetActiveWindow”或其他一些api。

所有这些api禁止窃取焦点,所以我的问题是Outlook vba方法如何能够如此轻松和可怕地窃取焦点?

警报部分撤防,如https://msdn.microsoft.com/it-it/library/windows/desktop/ms633539(v=vs.85).aspx所述,如果“前台锁定超时已过期(参见SystemParametersInfo中的SPI_GETFOREGROUNDLOCKTIMEOUT)”,则SetForegroundWindow可以被不在前台的其他进程使用。“

我将'HKCU:\ Control Panel \ Desktop'中的注册表项'ForegroundLockTimeout'的值从零更改为20000,现在,在我的特定情况下,Outlook不会窃取焦点。

我想知道哪个是'ForegroundLockTimeout'注册表项的最大值,或者换句话说,是否可以永久禁用不在活动应用程序中的前台窃取焦点的任何其他进程。

2 个答案:

答案 0 :(得分:1)

以下是Windows未按预期运行的原因:

  

我将'HKCU:\ Control Panel \ Desktop'中的注册表项'ForegroundLockTimeout'的值从零更改为20000

首先,该值不应为零。您的系统上的某些东西,可能很久以前,必须明确更改此设置才能禁用前景锁定。这与Outlook本身无关。

我建议您将其重新设置为默认值which is 200,000,即200秒。

至于最大值,它必须适合DWORD,所以可能大约49天。如果在内部将其视为签名值,则约为24天。将它设置的时间超过一天可能没什么意义。

答案 1 :(得分:0)

是的,SetForegroundWindow应该尊重前景窗口,只是为后台应用程序闪存任务栏,但有various hacks个人用来欺骗Windows并窃取焦点。

我向用户通知重要事项的首选方法是将窗口置于顶部而不会窃取键盘焦点。棘手的一点是找出要传递的HWND,我无法通过查看MSDN找到ActiveExplorer表单的HWND属性。

Const HWND_TOP = 0
Const SWP_NOSIZE = &H1
Const SWP_NOMOVE = &H2
Const SWP_NOACTIVATE = &H10
Const SWP_SHOWWINDOW = &H40
Private Declare Sub SetWindowPos Lib "User32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long)

...

SetWindowPos ??.hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE

另一个替代方法是调用FlashWindow来刷新任务栏按钮,如果你没有权利抓住焦点,SetForegroundWindow会做什么。