Someone posted a question in Q&A recently, asking how to create the semi-transparent "blackout" window on the screen in the same way
that Windows does when it asks you whether to allow a program to proceed or not. I responded by saying that all you need is another window on top of the original, and a dialog box
with the question. Having thought a bit more about the problem I wondered whether that would actually work or not. After some investigation I found the answer was actually fairly simple,
once I had figured out how to create and manage the secondary window.
Using the code
The code below is fairly self-explanatory but a few notes may help:
- First we need to register a new
Windows class with the following attributes:
- No special class styles, this window does nothing much.
DefWindowProc as its message handler, as our code will not deal with any messages.
- Set the backgound colour to the system colour value
COLOR_DESKTOP, which is black on my system.
- Get the dimensions of the caller's window (see note below) and create a Window of our new class with the following attributes:
- Extended style of
WS_EX_LAYERED, this is a layered window with no frame borders.
- Styles of
WS_VISIBLE | WS_POPUP, this is a visible popup.
- The same size and position as the caller's window.
- Its parent must be the caller's Window, to make the parent inaccessible.
- Next we call
SetLayeredWindowAttributes to make the overlay completely obscure the parent window.
- Sleep for half a second. Yes, this is fluff.
SetLayeredWindowAttributes again to make the overlay semi-transparent.
- Show a dialog: I have used the system
TaskDialog to display the user's message text.
- When complete, destroy the window, unregister the class and return the response to the caller.
In my code, if the caller does not provide a Window handle then we get the handle of the Desktop Window and completely cover the screen.
BOOL StopDialog(HWND hParentWnd,
int nButton = IDNO;
wndClass.cbSize = sizeof wndClass;
wndClass.style = 0;
wndClass.lpfnWndProc = DefWindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = GetModuleHandle(NULL);
wndClass.hIcon = NULL;
wndClass.hCursor = NULL;
wndClass.hbrBackground = GetSysColorBrush(COLOR_DESKTOP);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = _T("Blackout");
wndClass.hIconSm = NULL;
if (hParentWnd == NULL)
hParentWnd = GetDesktopWindow();
int nWidth = rectParent.right - rectParent.left;
int nHeight = rectParent.bottom - rectParent.top;
hStopWnd = CreateWindowEx(
WS_VISIBLE | WS_POPUP,
SetLayeredWindowAttributes(hStopWnd, 0, 255, ULW_ALPHA);
SetLayeredWindowAttributes(hStopWnd, 0, 196, ULW_ALPHA);
HRESULT hResult = TaskDialog(hStopWnd,
TDCBF_YES_BUTTON | TDCBF_NO_BUTTON,
if (hResult != S_OK)
nButton = IDNO;
return nButton == IDYES ? TRUE : FALSE;
- Initial post 27 October 2013
- Cosmetic changes: 20 November 2013
- Added sample image: 20 November 2013.