Index: dll/win32/msgina/CMakeLists.txt =================================================================== --- dll/win32/msgina/CMakeLists.txt (revision 71643) +++ dll/win32/msgina/CMakeLists.txt (working copy) @@ -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) Index: dll/win32/msgina/dimmedwindow.cpp =================================================================== --- dll/win32/msgina/dimmedwindow.cpp (nonexistent) +++ dll/win32/msgina/dimmedwindow.cpp (working copy) @@ -0,0 +1,232 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS msgina.dll + * FILE: lib/msgina/dimmedwindow.c + * PURPOSE: msgina.dll stubs + * PROGRAMMER: Mark Jansen + */ + +#define COM_NO_WINDOWS_H +#include "msgina.h" +#include +#include +#include +#include + + +class DimmedWindow : + public CComObjectRootEx, + 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: + DimmedWindow() + : 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); + ShowWindow(m_hwnd, SW_SHOW); + EnableWindow(m_hwnd, FALSE); + } + + ~DimmedWindow() + { + 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; + } + + 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(DimmedWindow) + COM_INTERFACE_ENTRY_IID(IID_IUnknown, IUnknown) + END_COM_MAP() + +}; + + +LRESULT WINAPI DimmedWindow::Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) + { + case WM_NCCREATE: + { + LPCREATESTRUCT lpcs = reinterpret_cast(lParam); + DimmedWindow* info = static_cast(lpcs->lpCreateParams); + SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG)info); + if (info) + info->Capture(); + SetTimer(hWnd, 0x12345, 200, NULL); + break; + } + case WM_PAINT: + { + DimmedWindow* info = reinterpret_cast(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 == 0x12345) + { + DimmedWindow* info = reinterpret_cast(GetWindowLongPtr(hWnd, GWLP_USERDATA)); + if (info && info->Step()) + InvalidateRect(hWnd, NULL, TRUE); + else + KillTimer(hWnd, 0x12345); + return 0; + } + break; + default: + break; + } + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + +CComModule gModule; + + +extern "C" +HRESULT WINAPI +ShellDimScreen (void** pUnknown, HWND* hWindow) +{ + CComObject *pWindow; + HRESULT hr = CComObject::CreateInstance(&pWindow); + ULONG refcount; + + _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; +} Property changes on: dll/win32/msgina/dimmedwindow.cpp ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: dll/win32/msgina/msgina.h =================================================================== --- dll/win32/msgina/msgina.h (revision 71643) +++ dll/win32/msgina/msgina.h (working copy) @@ -1,6 +1,10 @@ #ifndef _MSGINA_H #define _MSGINA_H +#ifdef __cplusplus +extern "C" { +#endif + #include #define WIN32_NO_STATUS @@ -125,4 +129,8 @@ IN PWSTR Domain, IN PWSTR Password); +#ifdef __cplusplus +} // extern "C" +#endif + #endif /* _MSGINA_H */ Index: dll/win32/msgina/stubs.c =================================================================== --- dll/win32/msgina/stubs.c (revision 71643) +++ dll/win32/msgina/stubs.c (working copy) @@ -116,10 +116,3 @@ UNIMPLEMENTED; return FALSE; } - -HRESULT WINAPI -ShellDimScreen (void* Unknown, HWND* hWindow) -{ - UNIMPLEMENTED; - return E_FAIL; -} Index: dll/win32/shell32/dialogs/dialogs.cpp =================================================================== --- dll/win32/shell32/dialogs/dialogs.cpp (revision 71643) +++ dll/win32/shell32/dialogs/dialogs.cpp (working copy) @@ -713,6 +713,7 @@ } + /************************************************************************* * ConfirmDialog [internal] * @@ -728,7 +729,28 @@ return MessageBoxW(hWndOwner, Prompt, Title, MB_YESNO|MB_ICONQUESTION) == IDYES; } +typedef HRESULT (__stdcall *tShellDimScreen) (IUnknown** Unknown, HWND* hWindow); +BOOL +CallShellDimScreen(IUnknown** pUnknown, HWND* hWindow) +{ + static tShellDimScreen ShellDimScreen; + static BOOL Initialized = FALSE; + if (!Initialized) + { + HMODULE mod = LoadLibrary(TEXT("msgina.dll")); + ShellDimScreen = (tShellDimScreen)GetProcAddress(mod, MAKEINTRESOURCEA(16)); + Initialized = TRUE; + } + + HRESULT hr = E_FAIL; + if (ShellDimScreen) + hr = ShellDimScreen(pUnknown, hWindow); + return SUCCEEDED(hr); +} + + + /************************************************************************* * RestartDialogEx [SHELL32.730] */ @@ -737,8 +759,13 @@ { TRACE("(%p)\n", hWndOwner); + CComPtr fadeHandler; + HWND parent; + if (!CallShellDimScreen(&fadeHandler, &parent)) + parent = hWndOwner; + /* FIXME: use lpwstrReason */ - if (ConfirmDialog(hWndOwner, IDS_RESTART_PROMPT, IDS_RESTART_TITLE)) + if (ConfirmDialog(parent, IDS_RESTART_PROMPT, IDS_RESTART_TITLE)) { HANDLE hToken; TOKEN_PRIVILEGES npr; @@ -799,7 +826,12 @@ EXTERN_C int WINAPI LogoffWindowsDialog(HWND hWndOwner) { - DialogBox(shell32_hInstance, MAKEINTRESOURCE(IDD_LOG_OFF), hWndOwner, LogOffDialogProc); + CComPtr fadeHandler; + HWND parent; + if (!CallShellDimScreen(&fadeHandler, &parent)) + parent = hWndOwner; + + DialogBox(shell32_hInstance, MAKEINTRESOURCE(IDD_LOG_OFF), parent, LogOffDialogProc); return 0; } @@ -870,12 +902,17 @@ TRACE("(%p)\n", hWndOwner); + CComPtr fadeHandler; + HWND parent; + if (!CallShellDimScreen(&fadeHandler, &parent)) + parent = hWndOwner; + /* If the DLL cannot be found for any reason, then it simply uses a dialog box to ask if the user wants to shut down the computer. */ if(!msginaDll) { TRACE("Unable to load msgina.dll.\n"); - ExitWindowsDialog_backup(hWndOwner); + ExitWindowsDialog_backup(parent); return; } @@ -884,7 +921,7 @@ if(pShellShutdownDialog) { /* Actually call the function */ - DWORD returnValue = pShellShutdownDialog(hWndOwner, NULL, FALSE); + DWORD returnValue = pShellShutdownDialog(parent, NULL, FALSE); switch(returnValue) { @@ -937,6 +974,6 @@ /* If the function cannot be found, then revert to using the backup solution */ TRACE("Unable to find the 'ShellShutdownDialog' function"); FreeLibrary(msginaDll); - ExitWindowsDialog_backup(hWndOwner); + ExitWindowsDialog_backup(parent); } }