mirror of
https://github.com/reactos/reactos.git
synced 2024-12-30 19:14:31 +00:00
[MSGINA] Implement ShellDimScreen. CORE-11422
svn path=/trunk/; revision=72572
This commit is contained in:
parent
6a5543002e
commit
87a716926b
4 changed files with 289 additions and 13 deletions
|
@ -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 @@ list(APPEND SOURCE
|
|||
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)
|
||||
|
|
269
reactos/dll/win32/msgina/dimmedwindow.cpp
Normal file
269
reactos/dll/win32/msgina/dimmedwindow.cpp
Normal file
|
@ -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;
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
#ifndef _MSGINA_H
|
||||
#define _MSGINA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
|
@ -125,4 +129,8 @@ CreateProfile(
|
|||
IN PWSTR Domain,
|
||||
IN PWSTR Password);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* _MSGINA_H */
|
||||
|
|
|
@ -116,10 +116,3 @@ WlxGetConsoleSwitchCredentials(
|
|||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HRESULT WINAPI
|
||||
ShellDimScreen (void* Unknown, HWND* hWindow)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue