2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS msgina.dll
4 * FILE: dll/win32/msgina/dimmedwindow.cpp
5 * PURPOSE: Implementation of ShellDimScreen
6 * PROGRAMMER: Mark Jansen
9 #define COM_NO_WINDOWS_H
14 #include <pseh/pseh2.h>
18 // Please note: The INIT_TIMER is a workaround because ReactOS does not redraw the desktop in time,
19 // so the start menu is still visible on the dimmed screen.
20 #define INIT_TIMER_ID 0x112233
21 #define FADE_TIMER_ID 0x12345
24 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
38 static LRESULT WINAPI
WndProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
51 WNDCLASSEXW wndclass
= {sizeof(wndclass
)};
52 wndclass
.lpfnWndProc
= WndProc
;
53 wndclass
.hInstance
= hDllInstance
;
54 wndclass
.hCursor
= LoadCursor(0, IDC_ARROW
);
55 wndclass
.lpszClassName
= L
"DimmedWindowClass";
57 if (!RegisterClassExW(&wndclass
))
60 m_width
= GetSystemMetrics(SM_CXVIRTUALSCREEN
);
61 m_height
= GetSystemMetrics(SM_CYVIRTUALSCREEN
);
63 memset(&m_bi
, 0, sizeof(m_bi
));
64 m_bi
.bmiHeader
.biSize
= sizeof(m_bi
);
65 m_bi
.bmiHeader
.biWidth
= m_width
;
66 m_bi
.bmiHeader
.biHeight
= m_height
;
67 m_bi
.bmiHeader
.biPlanes
= 1;
68 m_bi
.bmiHeader
.biBitCount
= 32;
69 m_bi
.bmiHeader
.biCompression
= BI_RGB
;
70 m_bi
.bmiHeader
.biSizeImage
= m_width
* 4 * m_height
;
71 m_bytes
= new UCHAR
[m_width
* 4 * m_height
];
73 LONG x
= GetSystemMetrics(SM_XVIRTUALSCREEN
);
74 LONG y
= GetSystemMetrics(SM_YVIRTUALSCREEN
);
76 m_hwnd
= CreateWindowExW(WS_EX_TOPMOST
,
90 DestroyWindow(m_hwnd
);
91 UnregisterClassW(L
"DimmedWindowClass", hDllInstance
);
93 SelectObject(m_hdc
, m_oldbitmap
);
95 DeleteObject(m_hbitmap
);
102 // This is needed so that we do not capture the start menu while it's closing.
107 while (!IsWindowVisible(m_hwnd
) && IsWindow(m_hwnd
))
109 while (::PeekMessage(&msg
, m_hwnd
, 0, 0, PM_REMOVE
))
111 ::TranslateMessage(&msg
);
112 ::DispatchMessage(&msg
);
114 if (IsWindowVisible(m_hwnd
))
124 ShowWindow(m_hwnd
, SW_SHOW
);
125 SetForegroundWindow(m_hwnd
);
126 EnableWindow(m_hwnd
, FALSE
);
128 SetTimer(m_hwnd
, FADE_TIMER_ID
, 200, NULL
);
133 HWND desktopWnd
= GetDesktopWindow();
134 HDC desktopDC
= GetDC(desktopWnd
);
136 m_hdc
= CreateCompatibleDC(desktopDC
);
138 m_hbitmap
= CreateCompatibleBitmap(desktopDC
, m_width
, m_height
);
139 m_oldbitmap
= SelectObject(m_hdc
, m_hbitmap
);
140 BitBlt(m_hdc
, 0, 0, m_width
, m_height
, desktopDC
, 0, 0, SRCCOPY
);
142 ReleaseDC(desktopWnd
, desktopDC
);
147 // Stop after 10 steps
148 if (m_step
++ > 10 || !m_bytes
)
151 int lines
= GetDIBits(m_hdc
, m_hbitmap
, 0, m_height
, m_bytes
, &m_bi
, DIB_RGB_COLORS
);
154 for (int xh
= 0; xh
< m_height
; ++xh
)
156 int h
= m_width
* 4 * xh
;
157 for (int w
= 0; w
< m_width
; ++w
)
159 UCHAR b
= m_bytes
[(h
+ w
* 4) + 0];
160 UCHAR g
= m_bytes
[(h
+ w
* 4) + 1];
161 UCHAR r
= m_bytes
[(h
+ w
* 4) + 2];
163 // Standard formula to convert a color.
164 int gray
= (r
* 30 + g
* 59 + b
* 11) / 100;
168 // Do not fade too fast.
169 r
= (r
*2 + gray
) / 3;
170 g
= (g
*2 + gray
) / 3;
171 b
= (b
*2 + gray
) / 3;
173 m_bytes
[(h
+ w
* 4) + 0] = b
;
174 m_bytes
[(h
+ w
* 4) + 1] = g
;
175 m_bytes
[(h
+ w
* 4) + 2] = r
;
178 SetDIBits(m_hdc
, m_hbitmap
, 0, lines
, m_bytes
, &m_bi
, DIB_RGB_COLORS
);
185 BitBlt(hdc
, 0, 0, m_width
, m_height
, m_hdc
, 0, 0, SRCCOPY
);
194 BEGIN_COM_MAP(CDimmedWindow
)
195 COM_INTERFACE_ENTRY_IID(IID_IUnknown
, IUnknown
)
201 LRESULT WINAPI
CDimmedWindow::WndProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
207 LPCREATESTRUCT lpcs
= reinterpret_cast<LPCREATESTRUCT
>(lParam
);
208 CDimmedWindow
* info
= static_cast<CDimmedWindow
*>(lpcs
->lpCreateParams
);
209 SetWindowLongPtrW(hWnd
, GWLP_USERDATA
, (LONG_PTR
)info
);
210 SetTimer(hWnd
, INIT_TIMER_ID
, 50, NULL
);
216 CDimmedWindow
* info
= reinterpret_cast<CDimmedWindow
*>(GetWindowLongPtrW(hWnd
, GWLP_USERDATA
));
220 BeginPaint(hWnd
, &ps
);
229 if (wParam
== INIT_TIMER_ID
)
231 CDimmedWindow
* info
= reinterpret_cast<CDimmedWindow
*>(GetWindowLongPtrW(hWnd
, GWLP_USERDATA
));
232 KillTimer(hWnd
, INIT_TIMER_ID
);
235 else if (wParam
== FADE_TIMER_ID
)
237 CDimmedWindow
* info
= reinterpret_cast<CDimmedWindow
*>(GetWindowLongPtrW(hWnd
, GWLP_USERDATA
));
238 if (info
&& info
->Step())
239 InvalidateRect(hWnd
, NULL
, TRUE
);
241 KillTimer(hWnd
, FADE_TIMER_ID
);
250 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);
256 ShellDimScreen(void** pUnknown
, HWND
* hWindow
)
258 CComObject
<CDimmedWindow
> *pWindow
;
259 HRESULT hr
= CComObject
<CDimmedWindow
>::CreateInstance(&pWindow
);
262 pWindow
->WaitForInit();
264 if (!IsWindow(pWindow
->Wnd()))
266 refcount
= pWindow
->AddRef();
268 refcount
= pWindow
->Release();
275 hr
= pWindow
->QueryInterface(IID_IUnknown
, pUnknown
);
276 *hWindow
= pWindow
->Wnd();
279 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
282 refcount
= pWindow
->AddRef();
284 refcount
= pWindow
->Release();