SetForegroundWindow (user32)
Last changed: -81.5.16.253

.

Summary

- The SetForegroundWindow API

C# Signature:

    /// <summary>
    ///     Brings the thread that created the specified window into the foreground and activates the window. Keyboard input is
    ///     directed to the window, and various visual cues are changed for the user. The system assigns a slightly higher
    ///     priority to the thread that created the foreground window than it does to other threads.
    ///     <para>See for https://msdn.microsoft.com/en-us/library/windows/desktop/ms633539%28v=vs.85%29.aspx more information.</para>
    /// </summary>
    /// <param name="hWnd">
    ///     C++ ( hWnd [in]. Type: HWND )<br />A handle to the window that should be activated and brought to the foreground.
    /// </param>
    /// <returns>
    ///     <c>true</c> or nonzero if the window was brought to the foreground, <c>false</c> or zero If the window was not
    ///     brought to the foreground.
    /// </returns>
    /// <remarks>
    ///     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:
    ///     <list type="bullet">
    ///     <listheader>
    ///         <term>Conditions</term><description></description>
    ///     </listheader>
    ///     <item>The process is the foreground process.</item>
    ///     <item>The process was started by the foreground process.</item>
    ///     <item>The process received the last input event.</item>
    ///     <item>There is no foreground process.</item>
    ///     <item>The process is being debugged.</item>
    ///     <item>The foreground process is not a Modern Application or the Start Screen.</item>
    ///     <item>The foreground is not locked (see LockSetForegroundWindow).</item>
    ///     <item>The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).</item>
    ///     <item>No menus are active.</item>
    ///     </list>
    ///     <para>
    ///     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.
    ///     </para>
    ///     <para>
    ///     A process that can set the foreground window can enable another process to set the foreground window by
    ///     calling the AllowSetForegroundWindow function. The process specified by dwProcessId loses the ability to set
    ///     the foreground window the next time the user generates input, unless the input is directed at that process, or
    ///     the next time a process calls AllowSetForegroundWindow, unless that process is specified.
    ///     </para>
    ///     <para>
    ///     The foreground process can disable calls to SetForegroundWindow by calling the LockSetForegroundWindow
    ///     function.
    ///     </para>
    /// </remarks>
// For Windows Mobile, replace user32.dll with coredll.dll
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);

VB.NET Signature

<DllImport("user32.dll")> _
Private Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function

VB 6 Signature:

Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As IntPtr) As Long

User-Defined Types:

None.

Notes:

SetForegroundWindow Win32-API not always works on Windows-7 (vista and above).

See Tips & Tricks for a workaround...

Not always works on vista and above workaround:

The trick is to make windows ‘think’ that our process and the target window (hwnd) are related by attaching the threads (using AttachThreadInput API) and using an alternative API: BringWindowToTop.

Here is the code:

private static void ForceForegroundWindow(IntPtr hWnd)

{

    uint foreThread = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);

    uint appThread = GetCurrentThreadId();

    const uint SW_SHOW = 5;

    if (foreThread != appThread)

    {

        AttachThreadInput(foreThread, appThread, true);

        BringWindowToTop(hWnd);

        ShowWindow(hWnd, SW_SHOW);

        AttachThreadInput(foreThread, appThread, false);

    }

    else

    {

        BringWindowToTop(hWnd);

        ShowWindow(hWnd, SW_SHOW);

    }

}

For the full article see:

https://shlomio.wordpress.com/2012/09/04/solved-setforegroundwindow-win32-api-not-always-works/

Tips & Tricks:

This is especially useful for test automation to make sure the Application Under Test (AUT) retains focus before manipulating it.

This may be called several times in an automated test script, so it is best to create a method similar to the example below.

Tips & Tricks:

As mentioned above SetForegroundWindow might not always work as expected but it is actually very well documented why on https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setforegroundwindow

as mentioned there the system restricts which processes can set the foreground window.

One simple workaround would be to go for: A process can set the foreground window if the process received the last input event.

So simply call keybd_event(0, 0, 0, 0); right in front of SetForegroundWindow(IntPtr hWnd);

(Only problem with this approach might be that a key event might be triggered in the second application)

Second approach to gain full control would be to minimize and restore before SetForeground instead of using the keybd_event:

if (MyWrapper.GetForegroundWindow() != targetHWnd) { //Check if the window isnt already in foreground

    MyWrapper.ShowWindow(targetHWnd, 6); //Minimize (ShowWindowCommands.Minimize)
    MyWrapper.ShowWindow(targetHWnd, 9); //Restore (ShowWindowCommands.Restore)

}

MyWrapper.SetForegroundWindow(targetHWnd);

Sample Code (C#):

public static void Main(string[] args)
{
    // test code here...
    CheckAutFocus(myProcess.MainWindowHandle);
    // more test code...
}

public static void CheckAutFocus(hWnd)
{
    if (GetForegroundWindow() != hWnd)
    {
        SetForegroundWindow(hWnd);
    }
}

Sample Code (C#):

        public static bool BringWindowToTop(string windowName, bool wait)
        {
            int hWnd = FindWindow(windowName, wait);
            if (hWnd != 0)
            {
                return SetForegroundWindow((IntPtr)hWnd);
            }
            return false;
        }

        // THE FOLLOWING METHOD REFERENCES THE FindWindowAPI
        public static int FindWindow(string windowName, bool wait)
        {
            int hWnd = FindWindow(null, windowName);
            while (wait && hWnd == 0)
            {
                System.Threading.Thread.Sleep(500);
                hWnd = FindWindow(null, windowName);
            }

            return hWnd;
        }

Native .NET API:

If the window that you have to set in foreground is a .NET form the best thing is to use native code:

http://jorgearimany.blogspot.com/2010/10/win32-setforegroundwindow-equivalent-in.html

Alternative Managed API:

The ManagedWindowsApi project (http://mwinapi.sourceforge.net) provides a static property ManagedWinapi.SystemWindow.ForegroundWindow which can be set.

Documentation

- SetForegroundWindow on MSDN

Here is an alternative Managed API to FindWindow, The article also describes a way to CloseWindow of another process like notepad, not sure if there is such thing in Win32 API, but at least you can do it in .NET! Here is the article:

http://www.mycsharpcorner.com/Post.aspx?postID=32