-1

Using Outlook 2013 on Windows 7, I created this Macro, just to test it:

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

Whenever I am working on a different application and an Outlook reminder fires, Outlook becomes the active window stealing focus from the application I am working at.

How can it be possible??

I mean, I think that the “Activeexplorer.Activate” method uses some Windows api like “SetForegroundWindow” or maybe “SetActiveWindow” or some other api.

All these apis forbid to steal focus, so my question is how the Outlook vba method can so easily and horrifyingly able to steal focus?

The alarm is partially disarmed, as stated at https://msdn.microsoft.com/it-it/library/windows/desktop/ms633539(v=vs.85).aspx, SetForegroundWindow can be used by other processes not in the foreground if “The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).”

I changed the value of the registry key 'ForegroundLockTimeout' at 'HKCU:\Control Panel\Desktop' from zero to 20000 and now, in my specific case, Outlook won’t steal the focus.

I wonder which is the maximum value for the 'ForegroundLockTimeout' registry key, or, in other words, if it is possible to permanently disable any other process not in the foreground stealing focus from the active application.

Evolve_or_Die
  • 119
  • 2
  • 9

2 Answers2

1

Here's the reason Windows was not behaving as expected:

I changed the value of the registry key 'ForegroundLockTimeout' at 'HKCU:\Control Panel\Desktop' from zero to 20000

The value shouldn't have been zero in the first place. Something on your system, possibly a long time ago, must have explicitly changed this setting in order to disable the foreground lock. This has nothing to do with Outlook per se.

I recommend you set it back to the default, which is 200,000, i.e., 200 seconds.

As for the maximum, well, it has to fit into a DWORD, so probably about 49 days. If it is treated as a signed value internally, about 24 days. There's probably little point in setting it longer than a day.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
0

Yes, SetForegroundWindow is supposed to respect the foreground window and just flash the taskbar for background applications but there are various hacks people use to trick Windows and steal the focus.

My preferred method of notifying the user about something important is to bring the window to the top without stealing the keyboard focus. The tricky bit would be to figure out which HWND to pass, I could not really find the HWND property of the ActiveExplorer form just by looking on MSDN.

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

Another alternative is to call FlashWindow to flash the taskbar button which is what SetForegroundWindow would do if you don't have the right to grab focus.

Carl Reinke
  • 345
  • 2
  • 12
Anders
  • 97,548
  • 12
  • 110
  • 164
  • I am not interested in “hacks”, the one in my post is not a hack, it is a standard vba method, in my point of view this shouldn’t be possible, Microsoft shouldn’t have allowed stealing focus so easily. – Evolve_or_Die Sep 04 '17 at 10:40
  • The only way to find out if Outlook uses the hack would be to debug the Activate method. – Anders Sep 04 '17 at 12:40
  • Your hack to bring a window to the top of the z list without activating is not working, that is, other than making it topmost without activating it and, after that, making it non topmost without activating it I know no other way to put a window to the top of non topmost windows without activating it: SetWindowPos hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE Or SWP_NOACTIVATE SetWindowPos hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE Or SWP_NOACTIVATE – Evolve_or_Die Sep 04 '17 at 14:21