I've got an app that runs in the system tray to capture keypresses by the user. I'm only concerned with the windows button and F12 combination. When this happens, I'd like to bring a specific app (that's open) to the front, on top of all other windows. I've read a bunch of SO articles and have been able to capture the key combination but am not having luck bringing the app to the front.
MainForm.cs code:
[DllImport("user32.dll")]
internal static extern IntPtr SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
readonly KeyboardHook hook = new KeyboardHook();
public MainForm()
{
InitializeComponent();
hook.AutoRepeat = true;
hook.SetKeys(new KeyCombination(KeysEx.WinLogo | KeysEx.F12));
hook.Pressed += hook_Pressed;
hook.Engage();
}
void hook_Pressed(object sender, EventArgs e)
{
Action a = () =>
{
Process[] currentProcess = Process.GetProcessesByName("Whiteboard");
if (currentProcess.Length > 0)
{
IntPtr hWnd = currentProcess[0].MainWindowHandle;
if (hWnd != IntPtr.Zero)
{
SetForegroundWindow(hWnd);
ShowWindow(hWnd, (int)ShowWindowCommands.SW_MAXIMIZE);
return;
}
}
};
Task.Run(a);
}
The KeyboardHook
class/project was taken from this Refactorsaurus Rex article and the full source on GitHub.
The ShowWindowCommands
class looks like this:
public static class Enums
{
public enum ShowWindowCommands : uint
{
//Hides the window and activates another window.
SW_HIDE = 0,
//Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time.
SW_SHOWNORMAL = 1,
//Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time.
SW_NORMAL = 1,
//Activates the window and displays it as a minimized window.
SW_SHOWMINIMIZED = 2,
//Activates the window and displays it as a maximized window.
SW_SHOWMAXIMIZED = 3,
//Maximizes the specified window.
SW_MAXIMIZE = 3,
//Displays a window in its most recent size and position. This value is similar to <see cref="ShowWindowCommands.SW_SHOWNORMAL"/>, except the window is not activated.
SW_SHOWNOACTIVATE = 4,
//Activates the window and displays it in its current size and position.
SW_SHOW = 5,
//Minimizes the specified window and activates the next top-level window in the z-order.
SW_MINIMIZE = 6,
//Displays the window as a minimized window. This value is similar to <see cref="ShowWindowCommands.SW_SHOWMINIMIZED"/>, except the window is not activated.
SW_SHOWMINNOACTIVE = 7,
//Displays the window in its current size and position. This value is similar to <see cref="ShowWindowCommands.SW_SHOW"/>, except the window is not activated.
SW_SHOWNA = 8,
//Activates and displays the window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when restoring a minimized window.
SW_RESTORE = 9
}
}
And this was copied from PInvoke.net.
I know it finds the app that I wish to open and it appears to set "focus" to it, but not bring it to the front. Here's an example:
You can see that one of the small windows has been "moved" to the back but the Whiteboard app remains the same, except it appears to have the focus. So how can I get my app to bring the "Whiteboard" window to be at the front (top-most)?
UPDATE
If I run my app in a normal window state (not minimized to the system tray), then it will bring that window to the front.