Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Aetopia/1581b40f00cc0cadc93a0e8ccb65dc8c to your computer and use it in GitHub Desktop.
Save Aetopia/1581b40f00cc0cadc93a0e8ccb65dc8c to your computer and use it in GitHub Desktop.
Bypassing SetForegroundWindow(HWND hWnd) Restrictions

Bypassing SetForegroundWindow(HWND hWnd) Restrictions

Aim

I wanted to list/document the various methods use by people to bypass restrictions within Windows for the function SetForegroundWindow(HWND hWnd).

What does SetForegroundWindow(HWND hWnd) do and what restrictions are set it in place for it?

SetForegroundWindow(HWND hWnd) brings the specified window into the foreground, activates it and keyboard input is direct towards that window.

SetForegroundWindow(HWND hWnd) also has the following criteria either of which must be fulfilled to call the function.

Bypassing The Restrictions

Using AllowSetForegroundWindow(DWORD dwProcessId)

This function allows the specified process to call SetForegroundWindow(HWND hWnd).

Note:

  • This function can only be called by a process that has the ability to set the foreground window.

Using AllocConsole() & FreeConsole()

Brief creation of a console window allows a process to call SetForegroundWindow(HWND hWnd).

AllocConsole();
FreeConsole();
SetForegroundWindow(hWnd);

Notes:

  • This method may fail if a menu is active.
  • This method seems to work consistently if a window is active.

Using AttachThreadInput(DWORD idAttach, DWORD idAttachTo, BOOL fAttach)

Attaching the window thread to the foreground window thread allows a process to call SetForegroundWindow(HWND hWnd).

AttachThreadInput(WindowThreadId, ForegroundWindowThreadId, TRUE);
SetForegroundWindow(hWnd);
AttachThreadInput(WindowThreadId, ForegroundWindowThreadId, FALSE);

The foreground window will have the last input event prior to any foreground window change.
This means having a process' window thread attach to the foreground window thread allows us to call SetForegroundWindow(HWND hWnd).

Notes:

  • This method fulfills the "The process received the last input event." criterion.
  • This method will not work with a thread that doesn't have a message queue.
    Example: Console Windows.
  • This method will also not work if the foreground window is on another desktop.

Using SendInput(UINT cInputs, LPINPUT pInputs, int cbSize)

According to the Remarks section of LockSetForegroundWindow(UINT uLockCode), pressing the [ALT] key causes Windows itself to enable calls to SetForegroundWindow(HWND hWnd).

INPUT pInputs[] = {{.type = INPUT_KEYBOARD, .ki.wVk = VK_MENU, .ki.dwFlags = 0},
                   {.type = INPUT_KEYBOARD, .ki.wVk = VK_MENU, .ki.dwFlags = KEYEVENTF_KEYUP}};
SendInput(2, pInputs, sizeof(INPUT));
SetForegroundWindow(hWnd);

Here's what is being done:

  1. Setting up an array of INPUT structure to emulate an [ALT] key press.
  2. Using SendInput(UINT cInputs, LPINPUT pInputs, int cbSize) to send keyboard input to Windows.
  3. Finally setting the foreground window.

Note:

  • Out of all the specified methods here, this one is 100% reliable considering Windows is the one to enable calls to SetForegroundWindow(HWND hWnd).
  • The process that wants to set the foreground window doesn't need to fulfill any of the following criteria.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment