I have a small Windows Forms program (agent) running in the Systray. The purpose of this agent written in C#
is to start other programs, focus them and putting them into the foreground.
This agent receives the commands to start other programs from the browser and reports the successful start back to it. This means the browser is always up and running.
Starting external programs from the agent is working fine, but I have much trouble to get the focus and foreground topic to work. It seems like the browser is always in focus and the programs started from the agent are moved right behind the browser window.
I have tried the following methods from the User32.dll
without success:
SetForegroundWindow(IntPtr handle)
SwitchToThisWindow(IntPtr hWnd, bool fAltTab)
The strange thing is that if I am running the agent in my Visual Studio the focus works perfect!
Help is much appreciated, since I am new to windows internals.
Update 1: I noticed if for instance a powershell window (could be anything arbitrary) lays over the browser window, focusing the started process window works as expected.
Update 2: I was able to get the right focus by calling
SetWindowPos(browserProcess.MainWindowHandle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
on the browser process window and
SetWindowPos(process.MainWindowHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
on the started process window. But I think this is a bad approach since the browser window may vanish behind other open windows. I have also tried
SetWindowPos(browserProcess.MainWindowHandle, process.MainWindowHandle, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
to switch the Z order of the browser window and the process window, but without success.
Question: How I can switch the Z order of the browser process and the started process?
Seems like
SendKeys.SendWait("%");
was the magic I needed.%
is the ALT key.From the documentation of
LockSetForegroundWindow
Calling
AllowSetForegroundWindow
returnedFALSE
in the first place so I was not able to set the foreground window. A call toGetLastError
revealed the error codeERROR_ACCESS_DENIED
. CallingSendKeys.SendWait("%")
beforeUser32dll.SetForegroundWindow(windowHandle)
enables calls toSetForegroundWindow
to be successful.To put it together it looks like this:
If the window is minimized, using
User32dll.ShowWindow(windowHandle, User32dll.SW_RESTORE)
is sufficient.