Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Windows's "Safely Remove Hardware" dialog get the "foreground love"?

Raymond has blogged about how programs can get/steal the "foreground love" by using RegisterHotkey, which, when invoked, will transfer the foreground-ness to your application.

Attempts to do this manually fail miserably (e.g. using SetForegroundWindow, SwitchToWindow, etc.), because applications must not be able to steal the focus from a user (so that keypresses don't go to the wrong place).

The trouble is, today I noticed something weird:

  1. I try to Safely Remove an external drive.

  2. There is a ~7-second pause.

  3. During the pause, I am vigorously typing inside a window.

  4. Suddenly, a message box steals the foreground-ness from my app, and my typing goes into the message box instead.

Clearly, this isn't using a hotkey mechanism -- and yet, Windows was able to steal the focus from my app.

I really doubt that there is anything like a "backdoor" being used just for this particular purpose (though please correct me if I'm wrong), so, assuming that isn't the case, there must be a way to do this correctly, without using a hotkey mechanism.

So the question is, how is this accomplished?

Note:

Hans noted that the "backdoor" is AttachInputThread, but I'm not really convinced that's what's happening here -- especially since Raymond says that method can cause hangs. Ideas?

like image 768
user541686 Avatar asked May 23 '12 07:05

user541686


2 Answers

I've done some experimenting, and from what I can see this happens if and only if the new window belongs to Windows Explorer. Certain control panels are implemented within Explorer or as Explorer plugins, for example. I could most easily reproduce it by opening Action Center from the Start Menu (with the Start Menu configured to show Control Panel items in a menu).

I suspect, then, that this behaviour is a consequence of the fact that Windows Explorer owns the desktop window, which the GUI treats as a special case.

The only slightly odd thing is that I couldn't reproduce this behaviour with the USB dialog you're talking about, which (when I tried it) was generated by a separate process (an instance of rundll32.exe). That might depend on other factors, though.

like image 125
Harry Johnston Avatar answered Oct 29 '22 17:10

Harry Johnston


I can't think of a way to test this that isn't more complicated than I have time for right now, but looking closely at the SetForegroundWindow docs, http://msdn.microsoft.com/en-us/library/ms633539(VS.85).aspx , one of the conditions listed under the remarks concerning processes that can set the foreground is:

  • The process received the last input event.

Unless I'm mistaken, Windows Explorer receives all input events in order to check for Hotkeys, other such focus-stealing keypresses, and mouse clicks outside the bounds of the current window, etc.

Because of its permanent "received the last input event" status, Explorer qualifies as something that can set the foreground and can thus cause a MessageBox it causes to be shown to become the foreground without any special functionality or undocumented behaviors.

like image 1
MikeBMcL Avatar answered Oct 29 '22 18:10

MikeBMcL