Click here to Skip to main content
15,867,704 members
Articles / Programming Languages / C++
Tip/Trick

How to Bring Window to Top with SetForegroundWindow()

Rate me:
Please Sign up or sign in to vote.
4.90/5 (27 votes)
27 Apr 2010CPOL2 min read 176.2K   38   15
Use SetForegroundWindow() to bring window to the top
In this tip, you will learn how to bypass the limitation of using ::SetForegroundWindow() function.

Introduction

This can help you to bypass limitation of using ::SetForegroundWindow() function.

Before looking at the code, here is something from MSDN:

Quote:

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:

  • The process is the foreground process.
  • The process was started by the foreground process.
  • The process received the last input event.
  • There is no foreground process.
  • The foreground process is being debugged.
  • The foreground is not locked (see LockSetForegroundWindow).
  • The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
  • No menus are active.

An application cannot force a window to the foreground while the user is working with another window. Instead, Foreground and Background Windows will activate the window (see SetActiveWindow) and call the function to notify the user.

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.

The foreground process can disable calls to SetForegroundWindow by calling the LockSetForegroundWindow function.

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.

So, there are two ways:

First, it works like Alt+TAB window switching in Windows:

C++
void SetForegroundWindowInternal(HWND hWnd)
{
	if(!::IsWindow(hWnd)) return;

	BYTE keyState[256] = {0};
	//to unlock SetForegroundWindow we need to imitate Alt pressing
	if(::GetKeyboardState((LPBYTE)&keyState))
	{
		if(!(keyState[VK_MENU] & 0x80))
		{
			::keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
		}
	}

	::SetForegroundWindow(hWnd);

	if(::GetKeyboardState((LPBYTE)&keyState))
	{
		if(!(keyState[VK_MENU] & 0x80))
		{
			::keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
		}
	}
}

And second. In this version, we are attaching the input processing mechanism of our thread to that of active thread.

C++
void SetForegroundWindowInternal(HWND hWnd)
{
	if(!::IsWindow(hWnd)) return;

	//relation time of SetForegroundWindow lock
	DWORD lockTimeOut = 0;
	HWND  hCurrWnd = ::GetForegroundWindow();
	DWORD dwThisTID = ::GetCurrentThreadId(),
	      dwCurrTID = ::GetWindowThreadProcessId(hCurrWnd,0);

	//we need to bypass some limitations from Microsoft :)
	if(dwThisTID != dwCurrTID)
	{
		::AttachThreadInput(dwThisTID, dwCurrTID, TRUE);

		::SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT,0,&lockTimeOut,0);
		::SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT,0,0,SPIF_SENDWININICHANGE | 
                               SPIF_UPDATEINIFILE);

		::AllowSetForegroundWindow(ASFW_ANY);
	}

	::SetForegroundWindow(hWnd);

	if(dwThisTID != dwCurrTID)
	{
		::SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT,0,
          (PVOID)lockTimeOut,SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
		::AttachThreadInput(dwThisTID, dwCurrTID, FALSE);
	}
}

Have a nice day! :)

History

  • 28th April, 2010: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Engineer
Belarus Belarus
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionworked perfectly on windows 10 but with SendInput Pin
rfl.souza9-May-18 4:29
rfl.souza9-May-18 4:29 
SuggestionThere is another approach Pin
Alex Marmer28-Apr-18 23:32
Alex Marmer28-Apr-18 23:32 
QuestionCan we use the same approach in a Windows NT Service? Pin
alamururaja5-Oct-17 3:57
alamururaja5-Oct-17 3:57 
QuestionCan't we have a download sample ? Pin
Frederic GIRARDIN5-Jun-17 21:28
Frederic GIRARDIN5-Jun-17 21:28 
QuestionWhat about admin rights? Pin
xSlavik12-May-17 7:38
xSlavik12-May-17 7:38 
QuestionThank you + bug fix Pin
Axonn Echysttas10-Aug-16 9:05
Axonn Echysttas10-Aug-16 9:05 
AnswerRe: Thank you + bug fix Pin
rfl.souza9-May-18 7:16
rfl.souza9-May-18 7:16 
PraiseVery nice solution Pin
sachin rakate4-Nov-15 20:03
sachin rakate4-Nov-15 20:03 
GeneralMy vote of 5 Pin
gndnet7-Aug-12 22:23
gndnet7-Aug-12 22:23 
QuestionNeed to use GetAsyncKeyState() Pin
varkha25-May-12 12:03
varkha25-May-12 12:03 
General>>The system automatically enables calls to SetForegroundWin... Pin
Naveen13-Dec-10 19:54
Naveen13-Dec-10 19:54 
GeneralThanks for sharing, very helpful. but, if the window is mini... Pin
qiuchengw2-Dec-10 15:29
qiuchengw2-Dec-10 15:29 
Thanks for sharing, very helpful.
but, if the window is minimized, how can you restore and bring it to top?
I have test these messages : WM_ACTIVE/WM_ACTIVEAPP/WM_SYSCOMMAND-SC_RESTORE..
none of them did work! why? please help.
thanks again for your work
GeneralRe: Thanks for sharing, very helpful.but, if the window is mini... Pin
Aster Veigas7-Dec-13 10:13
Aster Veigas7-Dec-13 10:13 
GeneralWorks on Win Server 2008 R2 Pin
Chris at M13-Dec-10 11:48
Chris at M13-Dec-10 11:48 
AnswerRe: Works on Win Server 2008 R2 Pin
Siarhei Boika4-Apr-11 21:06
Siarhei Boika4-Apr-11 21:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.