Source code for C_ActivateWindow
Download
The source files for this module are listed below. You can also download the module C_ActivateWindow as a zip archive; this archive contains all the source files and documentation.
Description
ActivateWindow allows you to activate a window so that the user notices it; either by making the window the foreground window or if that fails by flashing the taskbar button.
Information
This source code also uses our C_DesktopWaiter module. You can also download it at our website.
Since Windows 98 and Windows 2000, Windows has become more strict in which applications can bring their window to the foreground. The consequence of this is that calling e.g. SetForegroundWindow, ActivateWindow and BringWindowToTop doesn't guarantee your window will be on top of all other windows with the input focus on it. See the MSDN information on SetForegroundWindow for all the circumstances and exclusions. There are some 'hacks' floating around the Internet that rely on the function AttachThreadInput, the ('deprecated') function SwitchToThisWindow and the function SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT). But I feel uncomfortable using some of these and/or I didn't even get them to work reliably on my Windows XP SP3 box; it seems Windows is enforcing the rules more and more every day.
Another complication is that when the user is currently not logged on to the computer, SetForegroundWindow will not flash the taskbar window! This is at least true on my Windows XP SP3 machine. So before you can call SetForegroundWindow, you first have to check if the user is logged in (on Windows NT, XP and Vista systems).
In order to reliably show a window in the user's face when possible, and let the taskbar button flash otherwise, you can use the function ActivateWindow. It takes two parameters: the window to activate and a utility window (they can be the same). The utility window is needed when the code runs on a Windows NT, XP or Vista system while the user is interacting with another desktop than the one your application is running on (this could be the logon desktop or a totally different desktop that was created by a "multiple desktop" application). In this situation the embedded CDesktopWaiter object needs a Window to attach a timer to in order to poll for desktop changes.
Notes / todo's
- This code is not tested on other systems than Windows XP; if you have tested it on another system, please tell me the results!
- I explicitly didn't resort to hacks to get my window in the front with the input focus; that's why I rely on SetForegroundWindow and friends.
Files
Each file belonging to this source code module is listed below.
ActivateWindow.h
/*******************************************************************************
Version: 1
Author: Carl Colijn, TwoLogs
Contact: c.colijn@twologs.com
Source: http://www.twologs.com/en/resources/sourcecode.asp
This code is freely distributable, as long as this comment remains intact.
If you find this source useful, you may use this code in your own projects
free of charge, but some acknowledgement to the author of this code is always
appreciated :)
The source is however distributed 'as is' without waranty and/or support, and
may not be fit for each and every application. Use it at your own discretion
and at your own risk.
The source already has undergone testing. This doesn't mean however that all
bugs are removed from this piece of code. If you find one of them, please
contact me about it. I can however not guarantee when and if the bug will be
fixed.
More information about this module can be found in the accompanying HTML file.
*******************************************************************************/
#ifndef INCLUDE_TWOLOGS_COMMON_ACTIVATEWINDOW_H
#define INCLUDE_TWOLOGS_COMMON_ACTIVATEWINDOW_H
#include <windows.h>
// Activates the given window
// If needed, the given utility window will be used to attach a Windows timer to
// by a DesktopWaiter object; you can use the same window if you like
void ActivateWindow(HWND hWindow, HWND hUtilityWindow);
#endif // INCLUDE_TWOLOGS_COMMON_ACTIVATEWINDOW_H
ActivateWindow.cpp
#include "ActivateWindow.h"
#include "..\C_DesktopWaiter\DesktopWaiter.h"
// Window activator
class CWindowActivator:
public CSlot<CUserOnOurDesktopEvent> {
public:
// Constructor
CWindowActivator();
// The desktop waiter to use
CDesktopWaiter m_oDesktopWaiter;
// Activates the given window
void Activate(HWND hWindow, HWND hUtilityWindow);
private:
// The window to activate
HWND m_hWindow;
// Activates the window
void Activate();
// Events
bool OnEvent(CUserOnOurDesktopEvent& oEvent);
};
static CWindowActivator g_oWindowActivator;
// Constructor
CWindowActivator::CWindowActivator():
m_hWindow(NULL) {
// Connect to our desktop waiter
CSlot<CUserOnOurDesktopEvent>::Connect(&m_oDesktopWaiter);
}
// Events
bool CWindowActivator::OnEvent(CUserOnOurDesktopEvent& oEvent) {
Activate();
return true;
}
// Activates the given window
void CWindowActivator::Activate(HWND hWindow, HWND hUtilityWindow) {
// Note the window to activate
m_hWindow = hWindow;
// Let the desktop waiter wait till the logon desktop is gone (if possible and
// needed)
bool bPostponedActivation = false;
if (m_oDesktopWaiter.CanWait()) {
bPostponedActivation = m_oDesktopWaiter.StartWaiting(hUtilityWindow);
}
// Look if we have postponed the activation
if (!bPostponedActivation) {
// No -> do so now
Activate();
}
}
// Activates the window
void CWindowActivator::Activate() {
// Restore the window correctly
if (IsIconic(m_hWindow)) {
ShowWindow(m_hWindow, SW_RESTORE);
} else {
ShowWindow(m_hWindow, SW_SHOW);
}
// And force the window to get attention
BringWindowToTop(m_hWindow);
SetForegroundWindow(m_hWindow);
SetActiveWindow(m_hWindow);
}
// Activates the given window
// If needed, the given utility window will be used to attach a Windows timer to
// by a DesktopWaiter object; you can use the same window if you like
void ActivateWindow(HWND hWindow, HWND hUtilityWindow) {
g_oWindowActivator.Activate(hWindow, hUtilityWindow);
}

Products
Overview
C_ActivateWindow