Is it possible to prevent an application from being activated (brought to front) without using DLL injection? - winapi

I need to write application A, which intercepts the WM_ACTIVATE message to a window of application B in order to prevent B from becoming top-most application.
Is it possible to do this without DLL injection (add a hook on that message, process and "neutralize" it with a series of WinAPI calls) ?

I think this is what you're after:
LockSetForegroundWindow
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633532(v=vs.85).aspx
Remarks
The system automatically enables calls to SetForegroundWindow if the user presses the ALT key or takes some action that causes the system itself to change the foreground window (for example, clicking a background window).
This function is provided so applications can prevent other applications from making a foreground change that can interrupt its interaction with the user.
Just don't forget to unlock :)
Edit:
Try SetWinEventHook as described here:
Is there Windows system event on active window changed?
Then when the unwanted window comes to the front you can send it to the background.

Related

Stop application stealing input

I have a third party application (I'll call it GreedyApp for brevity), which holds the mouse and keyboard input hostage when its window gets focus i.e. it hides the standard mouse cursor and replaces it with it's own cursor, and confines the cursor to its window. The only way to get input to other windows is to ALT+TAB away from GreedyApp.
I need to allow the user free use of all of the components of the system (the delivered system will be purely touch-screen), so at the minute the rest of the system becomes unusable once GreedyApp gets focus.
So far, I've hijacked user32.dll for GreedyApp, hooked SetCursor, ShowCursor and ClipCursor, and disabled them. The result is that GreedyApp no longer hides the cursor, and the cursor is free to roam wherever the user moves it, but...
The problem I'm left with, is that no matter where on the screen the cursor is pressed, or what keys on the keyboard are pressed (except ALT+TAB), the input is still directed into GreedyApp, and other windows don't receive any input.
I'm not sure how GreedyApp is achieving this, and therefore I don't yet know which API calls to hook to stop it. I though it might have been using hooks itself, but I've hooked and disabled SetWindowsHookEx, but the problem persists.
So my question is this:
Either:
A) Is there a (relatively straight-forward) way to find out what API calls an application is making at runtime?
or
B) What method is GreedyApp likely to be using to stop other windows from receiving input?
The application was using RegisterRawInputDevices to get raw mouse and keyboard input, and using the flag RIDEV_CAPTUREMOUSE to stop other applications getting focus.
I've hooked the API call and remove the flag before passing the parameters to the Windows API to process. The user now has control over the system :)

Win32API How can my window follow to existing window

To all Win32 professionals. Let's say we have completed existing application with window. The task is to write another application with (my) window. My window must always align its left edge to existing window right edge while user moves existing window across the screen (my window not allowed to move by user).
Precondition: a) Existing window can not be subclassed b) Windows hooks are not a case.
Yes, looks right. I'd not asked this question if it not become a problem. Forgot to say that OS is Vista 2, application is IE. I try to make an application that follows IE main window, align it edge. Subclassing of IE not allowed, and SetWindowsHook not works correctly under regular user (when user have admin privileges application works normally). Such way as all of you talking about works under Windows prior to Vista.
And looks like there is no trivial way to solve this task. Thank you all.
I think you can't without a hook. SetWindowLong allows you to set a WndProc, but this won't work if the window belongs to a different application.
If you dont want/cant subclass or set global hooks, you can look into the following:
Implement your code in a DLL
Call CreateRemoteThread on LoadLibrary's address and your DLL's name to inject your DLL into the target process
In the DLL's DllMain, you can SetWindowHook just on the thread that owns the window. This is a local hook and doesn't require special privileges and is very nice to the system.
In your hook function, process WM_WINDOWPOSCHANGED on the main window's HWND and adjust your window accordingly.

VB6 ActiveX exe loses focus when launched from a third party app

I have a VB6 ActiveX exe that is launched from a third-party CRM App. On launch, the main form opens but it starts to flash and then loses focus. If you move the form, you'll see a server busy screen with the Switch To, Retry button.
I've tried using SetFocus and the SetFocusAPI in the OnActivate event of the form, but that doesn't work. Are there any suggestions on how I can have this form have focus when launched from the other app?
Additional Info:
The OnLoad event calls the SetWindowPos API in order to center the app over the calling app and sets HWND_TOPMOST.
Additional Info:
The Active Window is the correct window(but it's clearly not in focus)
The foreground window is the calling application. SetForegroundWindow switches the foreground window, but immediately returns back to the calling app. It's not until I click on the form that the form is in the foreground. I'm attempting all of this within a loop in the module that calls the form (and not in the calling app).
The CRM application has to call AllowSetForegroundWindow to "authorize" the ActiveX ProcessID to "steal" the focus from the current process.
Have you tried setting the tab order on the form? Your user control should have a tab order of 0 so it gets the focus.
Also, where does the focus go after it is launched?

How to overcome full-screen app if I want to show my app

There are cases when one needs to start a process based on some events not involving activity of the mouse of keyboard (from hardware or time-based). It works with ShellExecute and ShellExecuteEx generally, but if there's a full-screen app (the one, created borderless with exactly the dimensions of the screen), this launched application don't become active or even visible. Is there a technique to bring such application to top over this full-screen app? I'm aware about ShellExecuteEx and hProcess manipulation, but it seems it involves very recent api (GetProcessId) and seems that this function has some limitations related to user rights.
Thanks
You can use
SystemParametersInfo (SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (PVOID)0,
SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
to do so before the process start, but you should do this temporary like described in How to ensure process window launched by Process.Start(ProcessStartInfo) has focus of all Forms?.
Please do this only you really need to start a process on top.

Is it possible to create a sub window which will not deactivate the parent?

Normally when creating a sub window (WS_POPUP), the child window will become activate and the parent will become deactivated. However, with menus, both remain active. At least I am assuming the menu is active, it at least has focus.
Example: Click on the file menu in notepad, the menu appears, yet the notepad window still looks active.
Is it possible to mirror this behavior with either a window style or responding to a particular message?
Thanks
Another example: Combo boxes seem to show a subwindow, yet do not deactivate the window. And you can click on that subwindow, while still maintaining an activate main window. Any ideas on how to grab the class /style of that window?
The list dropdown in a combobox is a bit of a hack, it is both a popup and a child window, I can't recommend that approach (Undocumented style combination, and IIRC, it is a bit buggy to do this with a "normal" floating window/toolbar)
This leaves you with two options:
WS_EX_NOACTIVATE (Main window will stay active, floating window is not active)
Handle activate messages (Both windows will look active)
I am surprised that creating a new popup window activates it. Normally you'd need to call SetActiveWindow. However check out WM_ACTIVATE and WM_NCACTIVATE on how to stop the window becoming deactivated.
A fact that a lot of people miss is that windows does not have a separate window manager component :- most of the window management duties are performed by each window - usually in DefWindowProc.
Most window positioning and activation / de-activation is done - ultimately - via a call to SetWindowPos - which always sends a WM_WINDOWPOSCHANGING message allowing the window to have a final say on what happens.
DefWindowProc also activate its own window in response to mouse clicks and so on.
The result of all this is, it is quite possible to create windows that never accept activation - it does require an extensive understanding of what messages and situations might have led to an activation.
Ultimately I can say that it is VERY handy to have a debugging setup configured for remote debugging - so that you can interact with your debugger without effecting the activation state of the system - and hence drop a breakpoint into the window in questions WM_ACTIVATE handler and simply debug any situation leading to an unwanted activation.
If You want to handle keyboard focus as well, it might be trickier - normally focus is given to an activated window - but again its usually the DefWindowProc responsible for assigning both. I just see it dangerous as having one window, still obviously activated, and another with focus. This will confuse any assistive software greatly.
I'd be tempted to perform a message loop level message hook - Similar to IsDialogMessage - to filter keystrokes intended for the popup window.
If you create your popup window with WS_EX_NOACTIVATE it will not be activated by user input (You could still activate it programatically) and therefore your main application window will still remain active.

Resources