Author: mjansen
Date: Sun Sep 4 14:17:22 2016
New Revision: 72572
URL:
http://svn.reactos.org/svn/reactos?rev=72572&view=rev
Log:
[MSGINA] Implement ShellDimScreen. CORE-11422
Added:
trunk/reactos/dll/win32/msgina/dimmedwindow.cpp (with props)
Modified:
trunk/reactos/dll/win32/msgina/CMakeLists.txt
trunk/reactos/dll/win32/msgina/msgina.h
trunk/reactos/dll/win32/msgina/stubs.c
Modified: trunk/reactos/dll/win32/msgina/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msgina/CMakeList…
==============================================================================
--- trunk/reactos/dll/win32/msgina/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msgina/CMakeLists.txt [iso-8859-1] Sun Sep 4 14:17:22 2016
@@ -1,11 +1,13 @@
+
+set_cpp(WITH_RUNTIME)
include_directories(
- include
+ ${REACTOS_SOURCE_DIR}/sdk/lib/atl
${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine)
spec2def(msgina.dll msgina.spec)
-list(APPEND SOURCE
+list(APPEND C_SOURCE
gui.c
lsa.c
msgina.c
@@ -14,15 +16,19 @@
tui.c
msgina.h)
+list(APPEND CPP_SOURCE
+ dimmedwindow.cpp)
+
add_library(msgina SHARED
- ${SOURCE}
+ ${C_SOURCE}
+ ${CPP_SOURCE}
msgina.rc
${CMAKE_CURRENT_BINARY_DIR}/msgina_stubs.c
${CMAKE_CURRENT_BINARY_DIR}/msgina.def)
-set_module_type(msgina win32dll)
-target_link_libraries(msgina wine)
+set_module_type(msgina win32dll UNICODE)
+target_link_libraries(msgina atlnew wine uuid ${PSEH_LIB})
add_delay_importlibs(msgina secur32)
add_importlibs(msgina advapi32 user32 gdi32 powrprof userenv msvcrt kernel32 ntdll)
-add_pch(msgina msgina.h SOURCE)
+add_pch(msgina msgina.h CPP_SOURCE)
add_cd_file(TARGET msgina DESTINATION reactos/system32 FOR all)
Added: trunk/reactos/dll/win32/msgina/dimmedwindow.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msgina/dimmedwin…
==============================================================================
--- trunk/reactos/dll/win32/msgina/dimmedwindow.cpp (added)
+++ trunk/reactos/dll/win32/msgina/dimmedwindow.cpp [iso-8859-1] Sun Sep 4 14:17:22 2016
@@ -0,0 +1,269 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS msgina.dll
+ * FILE: dll/win32/msgina/dimmedwindow.cpp
+ * PURPOSE: Implementation of ShellDimScreen
+ * PROGRAMMER: Mark Jansen
+ */
+
+#define COM_NO_WINDOWS_H
+#include "msgina.h"
+#include <wingdi.h>
+#include <atlbase.h>
+#include <atlcom.h>
+#include <pseh/pseh2.h>
+
+CComModule gModule;
+
+// Please note: The INIT_TIMER is a workaround because ReactOS does not redraw the
desktop in time,
+// so the start menu is still visible on the dimmed screen.
+#define INIT_TIMER_ID 0x112233
+#define FADE_TIMER_ID 0x12345
+
+class CDimmedWindow :
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ IUnknown
+{
+private:
+ HWND m_hwnd;
+ HDC m_hdc;
+ HBITMAP m_hbitmap;
+ HGDIOBJ m_oldbitmap;
+ LONG m_width;
+ LONG m_height;
+ BITMAPINFO m_bi;
+ UCHAR* m_bytes;
+ int m_step;
+
+ static LRESULT WINAPI Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+public:
+ CDimmedWindow()
+ : m_hwnd(NULL)
+ , m_hdc(NULL)
+ , m_hbitmap(NULL)
+ , m_oldbitmap(NULL)
+ , m_width(0)
+ , m_height(0)
+ , m_bytes(NULL)
+ , m_step(0)
+ {
+ WNDCLASSEXW wndclass = {sizeof(wndclass)};
+ wndclass.lpfnWndProc = Proc;
+ wndclass.hInstance = hDllInstance;
+ wndclass.hCursor = LoadCursor(0, IDC_ARROW);
+ wndclass.lpszClassName = L"DimmedWindowClass";
+
+ if (!RegisterClassExW(&wndclass))
+ return;
+
+ m_width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
+ m_height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
+
+ memset(&m_bi, 0, sizeof(m_bi));
+ m_bi.bmiHeader.biSize = sizeof(m_bi);
+ m_bi.bmiHeader.biWidth = m_width;
+ m_bi.bmiHeader.biHeight = m_height;
+ m_bi.bmiHeader.biPlanes = 1;
+ m_bi.bmiHeader.biBitCount = 32;
+ m_bi.bmiHeader.biCompression = BI_RGB;
+ m_bi.bmiHeader.biSizeImage = m_width * 4 * m_height;
+ m_bytes = new UCHAR[m_width * 4 * m_height];
+
+ LONG x = GetSystemMetrics(SM_XVIRTUALSCREEN);
+ LONG y = GetSystemMetrics(SM_YVIRTUALSCREEN);
+
+ m_hwnd = CreateWindowExW(WS_EX_TOPMOST, L"DimmedWindowClass", NULL,
WS_POPUP,
+ x, y, m_width, m_height,
+ NULL, NULL, hDllInstance, (LPVOID)this);
+ }
+
+ ~CDimmedWindow()
+ {
+ if (m_hwnd)
+ DestroyWindow(m_hwnd);
+ UnregisterClassW(L"DimmedWindowClass", hDllInstance);
+ if (m_oldbitmap)
+ SelectObject(m_hdc, m_oldbitmap);
+ if (m_hbitmap)
+ DeleteObject(m_hbitmap);
+ if (m_hdc)
+ DeleteObject(m_hdc);
+ if (m_bytes)
+ delete[] m_bytes;
+ }
+
+ // This is needed so that we do not capture the start menu while it's closing.
+ void WaitForInit()
+ {
+ MSG msg;
+
+ while (!IsWindowVisible(m_hwnd))
+ {
+ while (::PeekMessage(&msg, m_hwnd, 0, 0, PM_REMOVE))
+ {
+ ::TranslateMessage(&msg);
+ ::DispatchMessage(&msg);
+
+ if (IsWindowVisible(m_hwnd))
+ break;
+ }
+ }
+ }
+
+ void Init()
+ {
+ Capture();
+
+ ShowWindow(m_hwnd, SW_SHOWNA);
+ EnableWindow(m_hwnd, FALSE);
+
+ SetTimer(m_hwnd, FADE_TIMER_ID, 200, NULL);
+ }
+
+ void Capture()
+ {
+ HWND desktopWnd = GetDesktopWindow();
+ HDC desktopDC = GetDC(desktopWnd);
+
+ m_hdc = CreateCompatibleDC(desktopDC);
+
+ m_hbitmap = CreateCompatibleBitmap(desktopDC, m_width, m_height);
+ m_oldbitmap = SelectObject(m_hdc, m_hbitmap);
+ BitBlt(m_hdc, 0, 0, m_width, m_height, desktopDC, 0, 0, SRCCOPY);
+
+ ReleaseDC(desktopWnd, desktopDC);
+ }
+
+ bool Step()
+ {
+ // Stop after 10 steps
+ if (m_step++ > 10 || !m_bytes)
+ return false;
+
+ int lines = GetDIBits(m_hdc, m_hbitmap, 0, m_height, m_bytes, &m_bi,
DIB_RGB_COLORS);
+ if (lines)
+ {
+ for (int xh = 0; xh < m_height; ++xh)
+ {
+ int h = m_width * 4 * xh;
+ for (int w = 0; w < m_width; ++w)
+ {
+ UCHAR b = m_bytes[(h + w * 4) + 0];
+ UCHAR g = m_bytes[(h + w * 4) + 1];
+ UCHAR r = m_bytes[(h + w * 4) + 2];
+
+ // Standard formula to convert a color.
+ int gray = (r * 30 + g * 59 + b * 11) / 100;
+ if (gray < 0)
+ gray = 0;
+
+ // Do not fade too fast.
+ r = (r*2 + gray) / 3;
+ g = (g*2 + gray) / 3;
+ b = (b*2 + gray) / 3;
+
+ m_bytes[(h + w * 4) + 0] = b;
+ m_bytes[(h + w * 4) + 1] = g;
+ m_bytes[(h + w * 4) + 2] = r;
+ }
+ }
+ SetDIBits(m_hdc, m_hbitmap, 0, lines, m_bytes, &m_bi, DIB_RGB_COLORS);
+ }
+ return true;
+ }
+
+ void Blt(HDC hdc)
+ {
+ BitBlt(hdc, 0, 0, m_width, m_height, m_hdc, 0, 0, SRCCOPY);
+ }
+
+ HWND Wnd()
+ {
+ return m_hwnd;
+ }
+
+
+ BEGIN_COM_MAP(CDimmedWindow)
+ COM_INTERFACE_ENTRY_IID(IID_IUnknown, IUnknown)
+ END_COM_MAP()
+
+};
+
+
+LRESULT WINAPI CDimmedWindow::Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch(uMsg)
+ {
+ case WM_NCCREATE:
+ {
+ LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
+ CDimmedWindow* info =
static_cast<CDimmedWindow*>(lpcs->lpCreateParams);
+ SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG)info);
+ SetTimer(hWnd, INIT_TIMER_ID, 50, NULL);
+ break;
+ }
+ case WM_PAINT:
+ {
+ CDimmedWindow* info =
reinterpret_cast<CDimmedWindow*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
+ if (info)
+ {
+ PAINTSTRUCT paint;
+ HDC hdc = BeginPaint(hWnd, &paint);
+ info->Blt(hdc);
+ EndPaint(hWnd, &paint);
+ }
+ return 0;
+ }
+ case WM_TIMER:
+ if (wParam == INIT_TIMER_ID)
+ {
+ CDimmedWindow* info =
reinterpret_cast<CDimmedWindow*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
+ KillTimer(hWnd, INIT_TIMER_ID);
+ info->Init();
+ return 0;
+ }
+ if (wParam == FADE_TIMER_ID)
+ {
+ CDimmedWindow* info =
reinterpret_cast<CDimmedWindow*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
+ if (info && info->Step())
+ InvalidateRect(hWnd, NULL, TRUE);
+ else
+ KillTimer(hWnd, FADE_TIMER_ID);
+ return 0;
+ }
+ break;
+ default:
+ break;
+ }
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+}
+
+
+extern "C"
+HRESULT WINAPI
+ShellDimScreen (void** pUnknown, HWND* hWindow)
+{
+ CComObject<CDimmedWindow> *pWindow;
+ HRESULT hr = CComObject<CDimmedWindow>::CreateInstance(&pWindow);
+ ULONG refcount;
+
+ pWindow->WaitForInit();
+
+ _SEH2_TRY
+ {
+ hr = pWindow->QueryInterface(IID_IUnknown, pUnknown);
+ *hWindow = pWindow->Wnd();
+ hr = S_OK;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ hr = E_INVALIDARG;
+ refcount = pWindow->AddRef();
+ while (refcount)
+ refcount = pWindow->Release();
+ }
+ _SEH2_END
+
+ return hr;
+}
Propchange: trunk/reactos/dll/win32/msgina/dimmedwindow.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/dll/win32/msgina/msgina.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msgina/msgina.h?…
==============================================================================
--- trunk/reactos/dll/win32/msgina/msgina.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msgina/msgina.h [iso-8859-1] Sun Sep 4 14:17:22 2016
@@ -1,5 +1,9 @@
#ifndef _MSGINA_H
#define _MSGINA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
#include <stdarg.h>
@@ -125,4 +129,8 @@
IN PWSTR Domain,
IN PWSTR Password);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
#endif /* _MSGINA_H */
Modified: trunk/reactos/dll/win32/msgina/stubs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msgina/stubs.c?r…
==============================================================================
--- trunk/reactos/dll/win32/msgina/stubs.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msgina/stubs.c [iso-8859-1] Sun Sep 4 14:17:22 2016
@@ -116,10 +116,3 @@
UNIMPLEMENTED;
return FALSE;
}
-
-HRESULT WINAPI
-ShellDimScreen (void* Unknown, HWND* hWindow)
-{
- UNIMPLEMENTED;
- return E_FAIL;
-}