/********************************************************************************************** MFC screen dim test :: oystein :: November 2010 Creates a simple window - click it to toggle whether a translucent black "dimmer" window is shown. The dimmer-window covers the entire screen, but the taskbar ("superbar" in Windows 7) will jump on top of it if clicked - it seems. Simple suggestions to fix that are welcome. Should work on Windows 2000 and later. Disclaimer: This is my first MFC program ever, so if anything seems wrong, it probably is. I have previously only coded with pure Win32 API, and hacked this together using online tutorials. Code provided "as-is" with no guarantees - I can not be held responsible for anything bad that happens if you run this program. ***********************************************************************************************/ #include "stdafx.h" #undef WINVER #define WINVER 0x500 // Windows 2000 & above, because of layered windows // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // // Black window used to dim everything else // class CDimWnd : public CFrameWnd { public: CDimWnd() { // Get screen res into rect RECT rc; GetDesktopWindow()->GetWindowRect(&rc); CreateEx(WS_EX_LAYERED | // Layered window for translucency WS_EX_TRANSPARENT | // Click through WS_EX_TOPMOST | // Always on top WS_EX_TOOLWINDOW, // Do not appear in taskbar & similar NULL, TEXT(""), WS_POPUP, // No frame/borders - though there is // still some border left - we'll remove // it with regions 0, 0, rc.right + 10, rc.bottom + 10, // Make the window 10px larger // than screen resolution in both // directions - it is still positioned // at 0,0 NULL, NULL); // Grab a part of the window the size of the desktop - but 5px into it // Because the window is larger than the desktop res, the borders are removed CRgn rgn; rgn.CreateRectRgn(rc.left + 5, rc.top + 5, rc.right + 5, rc.bottom + 5); SetWindowRgn((HRGN)rgn, FALSE); rgn.Detach(); // We have to reposition window - (0,0) of window has not changed SetWindowPos(NULL, -5, -5, 0, 0, SWP_NOSIZE | SWP_NOZORDER); // This is where we set the opacity of the window: 0-255 SetLayeredWindowAttributes(RGB(0,0,0), 150, LWA_ALPHA); } void Close() { CFrameWnd::OnClose(); } BOOL CDimWnd::OnEraseBkgnd(CDC* pDC); // Set BKG color DECLARE_MESSAGE_MAP() }; BOOL CDimWnd::OnEraseBkgnd(CDC* pDC) { // Set brush to desired background color CBrush backBrush(RGB(0, 0, 0)); // Save old brush CBrush* pOldBrush = pDC->SelectObject(&backBrush); CRect rect; pDC->GetClipBox(&rect); // Erase the area needed pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY); pDC->SelectObject(pOldBrush); return TRUE; } BEGIN_MESSAGE_MAP(CDimWnd, CFrameWnd) ON_WM_ERASEBKGND() END_MESSAGE_MAP() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Global variable - is screen dimmed? bool g_bIsDimmed = false; // The main window class CMainWnd : public CFrameWnd { // Contains a CDimWnd - I'm not sure if this is the "MFC way" of doing things CDimWnd dimmer; public: CMainWnd() { Create(NULL, TEXT("Screen dimmer - Press left mouse button on window to toggle"), WS_OVERLAPPEDWINDOW, CRect(50, 50, 400, 250)); } // Left mouse button toggles dimming afx_msg void OnLButtonDown(UINT Flags, CPoint Point) { if(!g_bIsDimmed) { dimmer.ShowWindow(SW_SHOW); dimmer.BringWindowToTop(); g_bIsDimmed = true; } else { dimmer.ShowWindow(SW_HIDE); g_bIsDimmed = false; } } DECLARE_MESSAGE_MAP() }; BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd) ON_WM_LBUTTONDOWN() END_MESSAGE_MAP() // The app class CApp : public CWinApp { public: virtual BOOL InitInstance(); }; BOOL CApp::InitInstance() { m_pMainWnd = new CMainWnd(); m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CApp HelloApp;