How to reliably steal/regain focus for MFC/desktop app on Windows 8.1/10?

老子叫甜甜 提交于 2019-12-10 04:34:03

问题


OK, I get it: focus stealing is evil. Or at least it is 99.9% of the time. But I really need to steal the focus reliably on Windows 8, and so far I'm thwarted by the hordes of people insisting focus stealing is always evil.

Scenario: we run a custom application on an ordinary PC running Windows 8.1 (soon to be Windows 10). The screen, keyboard and mouse sit roughly 5m off the ground up some stairs that the forklift operator really shouldn't climb. The one input device they have is a numeric keypad on an extender cable down at their level. Everything they need to do they can do from that keypad... so long as some evil program hasn't stolen our application's focus, or some remote user hasn't logged out and left another application with focus.

The application is essentially a maximised desktop application - it fills the screen (but is not strictly a "full screen" or "topmost" application), and therefore allows other applications to appear in front of it when required. But when the mouse goes idle, we want this application to resume its "normal" position in front of all other applications so that it gets focus and the numeric keypad input will work reliably.

On Windows 7, using SetForegroundWindow() (enabled by AllowSetForegroundWindow() works fine - the application can be brought back to the front and resume focus. On Windows 8, SetForegroundWindow() only results in the taskbar icon flashing, but the application does not regain focus, forcing our user to climb the stairs... where the full keyboard and mouse is too tempting for them not to press buttons they shouldn't, and chaos typically ensues.

So please sir: can our (MFC, desktop) application steal back the focus once the mouse has gone idle for 1 minute, because it is more or less the only application that should normally be running anyway. If that is permitted, how do we steal it reliably?


回答1:


Configure hotkeys on numeric keypad (RegisterHotKey).

Pressing a registered hotkey gives you the foreground activation love by Raymond Chen

After you call the RegisterHotKey function to register a hotkey, the window manager will send you a WM_HOTKEY message when the user presses that hotkey, and along with it, you will get the foreground love. If you call SetForegroundWindow from inside your hotkey handler, the foreground window will change according to your instructions.




回答2:


Possible solution (with major limitations): do nothing extra; wait.

One of our service technicians observed that on the third or fourth attempt to regain focus using AllowSetForegroundWindow() and SetForegroundWindow() as had been working on Windows 7, Windows 8 finally allowed our application to regain focus. It is not clear what the conditions are that make this work, or if it works reliably, but we have now observed our application regaining focus from beneath Chrome, from beneath another (self-developed) MFC application, and from beneath a third party application - all desktop applications. Approximately 3-4 minutes needed to elapse in each case before focus was surrendered back to our (desktop) application.

However, we have not witnessed it regain focus from beneath metro applications, and nor do we expect it (e.g. hit the Windows key and leave the system lingering on the Start screen).

In our (restricted) situation, we are willing to take the gamble that our users will not launch a metro application that obscures our desktop application, at least not without restoring our application, since their business relies on it. Our main concern is that one of our busy service technicians will log in remotely, get distracted, and carelessly leave one of our desktop utilities with the focus. Waiting 3-4 minutes appears to be a solution to this specific scenario.




回答3:


I would try it in this way:

  1. Setup a timer in you application. That checks GetForegroundWindow on a regular basis.
  2. If GetForgroundWindow does not belong to your process (GetWindowThreadProcessId)
  3. If a different process onws the foreground window use AttachThreadInput and attach your input queue to the input queue of the other process.
  4. Now use SetForegoundWindow and detach the thread input again.
  5. Now you can use SetFocus as needed to control the input focus of your program.


来源:https://stackoverflow.com/questions/52285448/how-to-reliably-steal-regain-focus-for-mfc-desktop-app-on-windows-8-1-10

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!