Disable window from calling SetForegroundWindow - c++

I have a serious problem on my work machine with a third party software window stealing keyboard focus, using a winapi monitor tool i detect that whenever the windows steal focus it first call SetForegroundWindow.
While searching about, i have found the winapi LockSetForegroundWindow, wow i thought i had solved the problem, however, LockSetForegroundWindow blocks me from activating any other window.
I also found that would be possible to 'block' the window from calling SetForegroundWindow using a hook, but i have no knowledge about hooking, would like to ask if there's something else i could try.

Usually calling SetForegroundWindow() isn't bad. Since Windows XP, there is a lock that no program do this without being allowed to do this. Read the docs: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setforegroundwindow
This are the exceptions:
The process is the foreground process.
The process was started by the foreground process.
The process received the last input event.
There is no foreground process.
The process is being debugged.
The foreground process is not a Modern Application or the Start Screen.
The foreground is not locked (see LockSetForegroundWindow).
The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
No menus are active.
But when the third party tools uses AttachThreadInput(), it bypasses all these checks.
Just delete this "bad" software. Contact the developers.

Related

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

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?
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.
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.
I would try it in this way:
Setup a timer in you application. That checks GetForegroundWindow on a regular basis.
If GetForgroundWindow does not belong to your process (GetWindowThreadProcessId)
If a different process onws the foreground window use AttachThreadInput and attach your input queue to the input queue of the other process.
Now use SetForegoundWindow and detach the thread input again.
Now you can use SetFocus as needed to control the input focus of your program.

How to get mouse events on screen with c++ mfc

everyone.
Now, I'm developing desktop window apps with c++ mfc.
I wanna get the mouse move and down event on the desktop background.
Why I want these, this app requires all windows move and resize event, and also mouse position.
After so many googling, I don't search things as a right solution.
Someone suggests that global mouse hooks is helpful, but I don't really know how to use this.
What is your idea about this?
Please help me to find a right solution.
Best Regards
Falcon
You're looking for the windows low level global input hook api SetWindowsHookEx
You can find more information here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx
Specifically, you're looking to use the "low level" mouse hook like so:
HHOOK mousehook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, NULL, 0);
You'll need to use this with a windows message queue per this link:
Why must SetWindowsHookEx be used with a windows message queue
The low-level hooks, WH_KEYBOARD_LL and WH_MOUSE_LL are different from all the other hooks. They don't require a DLL to be injected into the target process. Instead, Windows calls your hook callback directly, inside your own process. To make that work, a message loop is required. There is no other mechanism for Windows to make callbacks on your main thread, the callback can only occur when you've called Get/PeekMessage() so that Windows is in control.
A global hook like WH_KEYBOARD is very different. It requires a DLL and the callback occurs within the process that processes the keyboard message. You need some kind of inter-process communication to let your own program be aware of this. Named pipes are the usual choice. Which otherwise of course requires that this injected process pumps a message loop. It wouldn't get keyboard messages otherwise.
Favor a low-level hook, they are much easier to get going. But do pump or it won't work. And beware of timeouts, if you're not responsive enough then Windows will kill your hook without notice.

C++ winAPI basics - switching through windows

Not very sure how to explain it in a clear way. Basicaly, the thing is that I'm looking for a method to change a current active window ( Self-produced def., hope it'll be understandable enough ) - window, where the text is directly typed right now. Whooh.
What have I allready discovered is msdn help and SetFocus() or SetActiveWindow(), but it doesn't solve my problem ( or, what is also possible, I'm just using it in a wrong way ).
Simply:
HWND Dest = GetFocus();
... //Some moving around on the 'alt-tab level' :-|
SetFocus(Dest);
Doesn't set the Dest window active again.
Please, excuse for the newbie questions, hope it won't take much time from you. Thanx!
SetFocus() does not bring a window to the top. It just sets the keyboard focus.
SetActiveWindow() on the other hand brings the specific window on top, but only if the application that calls it is also the application that owns it. ( according to the documentation).
When you say you did try SetActiveWindow() what do you mean? How did it fail? What results did it produce?
Another function you can try is SetForegroundWindow() in case you want to activate a window belonging to another application but this has its problems as you see from below (directly from the documentation):
The system restricts which processes can set the foreground window. A
process can set the foreground window only if one of the following
conditions is true:
The process is the foreground process.
The process was started by the foreground process.
The process received the last input event.
There is no foreground process.
The foreground process is being debugged.
The foreground is not locked (see LockSetForegroundWindow).
The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
No menus are active.
Try using the SetForegroundWindow function.
Do however note that there are limitations on this, which are explained on the MSDN page remarks sections and I've copied here.
The system restricts which processes can set the foreground window. A
process can set the foreground window only if one of the following
conditions is true:
The process is the foreground process. The process was started by the foreground process.
The process received the last input event.
There is no foreground process.
The foreground process is being debugged.
The foreground is not locked (see LockSetForegroundWindow).
The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
No menus are active.
An application cannot force a window to the foreground while the user
is working with another window. Instead, Windows flashes the taskbar
button of the window to notify the user.
What that means is that if you don't own the current foreground process (which is probably the case when the user tabs around) then you can't set a new foreground window.
There are several hacks around (google SetForegroundWindow and you will find them) but they are hacks and not a good idea - let the user decide what is in the foreground! (also as Raymond Chen explains on his blog here the hacks can often cause a program to hang)

Qt Need to bring Qt application to foreground called from win32 application

I have a simple win32 application that uses the createProcess method to call Qt application.
The problem is that I like to bring the Qt application to the foreground.
Who is responsible for this? The parent win32 app or the Qt application?
The application that currently has the foreground focus is the only one that is allowed to change the foreground focus. You need to use the SetForegroundWindow function to exercise this right.
The "Remarks" section in the documentation contains an applicable list of restrictions:
The system restricts which processes can set the foreground window. A process can set the foreground window only if one of the following conditions is true:
The process is the foreground process.
The process was started by the foreground process.
The process received the last input event.
There is no foreground process.
The foreground process is being debugged.
The foreground is not locked (see LockSetForegroundWindow).
The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
No menus are active.
An application cannot force a window to the foreground while the user is working with another window. Instead, Windows flashes the taskbar button of the window to notify the user.
The real question is why you need to do this at all. Changing the foreground application is very likely to get you into trouble, either with all of the restrictions that Windows places on it, or with your users. It's a very user-hostile action, which is one of the reasons why Windows has tightened up the restrictions on it in recent years.
Get the window handle of the Qt application and call SetForegroundWindow
http://msdn.microsoft.com/en-us/library/ms633539.aspx
You probably want to do it from the parent process. The cleanest/most dependable way to use SetForegroundWindow is to call it from the process that's currently in the foreground.

WM_SETFOCUS, get app that just lost focus

When my WTL C++ application is activated or gets the keyboard focus I need to determine the window handle of the application that was previously activated/had focus. However, the window handles (LPARAM) of both the WM_SETFOCUS and WM_ACTIVATE messages are both NULL (XP, 32 bit).
How can I determine the application that just lost focus when my application is activated? Is there a simple way to do this or will I need to roll a special CBT hook?
An easy way to see exactly what messages are being sent and what their parameters are is to fire up Spy++ and set it to Log Messages while you Alt+Tab to another window.
Consistent with what you've discovered, the lParam for both WM_SETFOCUS and WM_ACTIVATE will be NULL when the previously active window (or the window being active) is not in the same thread.
You might have more luck with WM_ACTIVATEAPP, as David suggested. Once you get the thread identifier, you can try calling the GetGUIThreadInfo function to determine the active window for that thread. This function will work even if the active window is not owned by the calling process.
If your app is anything other than a small utility that the user is not expected to keep open and running for very long, I would shy away from using a CBT hook if at all possible, given the potential performance implications. Unfortunately, interaction like this across process boundaries is difficult.
If you're not afraid of using things that may break with future versions of Windows, you could investigate the RegisterShellHookWindow function. I can't tell you much about it, having never used it myself, but it's an easier way to get the shell messages you would otherwise only receive by installing a hook.
It was around as far back as Windows 2000, but wasn't included in the SDK until XP SP1. It still exists in Windows Vista and 7, as far as I can tell.