636 lines
23 KiB
C++
636 lines
23 KiB
C++
#include "priv.h"
|
|
#include "CoverWnd.h"
|
|
#include <ginarcid.h>
|
|
|
|
#undef IDB_BACKGROUND_24
|
|
#define IDB_BACKGROUND_24 0x3812
|
|
#undef IDB_FLAG_24
|
|
#define IDB_FLAG_24 0x3813
|
|
|
|
const TCHAR g_szWindowClassName[] = TEXT("CoverWindowClass");
|
|
const TCHAR g_szPleaseWaitName[] = TEXT("PleaseWaitWindowClass");
|
|
|
|
#define CHUNK_SIZE 20
|
|
#define IDT_KILLYOURSELF 1
|
|
#define IDT_UPDATE 2
|
|
#define WM_DESTORYYOURSELF (WM_USER + 0)
|
|
|
|
void DimPixels(ULONG* pulSrc, int cLen, int Amount)
|
|
{
|
|
for (int i = cLen - 1; i >= 0; i--)
|
|
{
|
|
ULONG ulR = GetRValue(*pulSrc);
|
|
ULONG ulG = GetGValue(*pulSrc);
|
|
ULONG ulB = GetBValue(*pulSrc);
|
|
ULONG ulGray = (54 * ulR + 183 * ulG + 19 * ulB) >> 8;
|
|
ULONG ulTemp = ulGray * (0xff - Amount);
|
|
ulR = (ulR * Amount + ulTemp) >> 8;
|
|
ulG = (ulG * Amount + ulTemp) >> 8;
|
|
ulB = (ulB * Amount + ulTemp) >> 8;
|
|
*pulSrc = (*pulSrc & 0xff000000) | RGB(ulR, ulG, ulB);
|
|
|
|
pulSrc++;
|
|
}
|
|
}
|
|
|
|
LRESULT CALLBACK PleaseWaitWndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lParam)
|
|
{
|
|
switch ( msg )
|
|
{
|
|
case WM_CREATE:
|
|
{
|
|
CREATESTRUCT* pCS = (CREATESTRUCT*)lParam;
|
|
SetWindowLongPtr( hwnd, GWLP_USERDATA, (LPARAM) pCS->lpCreateParams );
|
|
HBITMAP hbmBackground = (HBITMAP) pCS->lpCreateParams;
|
|
BITMAP bm;
|
|
if ( GetObject( hbmBackground, sizeof(bm), &bm ) )
|
|
{
|
|
RECT rc;
|
|
HWND hwndParent = GetParent( hwnd );
|
|
GetClientRect( hwndParent, &rc );
|
|
|
|
POINT pt = {0,0};
|
|
HMONITOR hmon = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
|
|
if (hmon)
|
|
{
|
|
MONITORINFO mi = {sizeof(mi)};
|
|
GetMonitorInfo(hmon, &mi);
|
|
rc = mi.rcMonitor;
|
|
MapWindowPoints(HWND_DESKTOP, hwndParent, (LPPOINT)&rc, 2);
|
|
}
|
|
|
|
// Center dialog in the center of the virtual screen
|
|
int x = ( rc.right - rc.left - bm.bmWidth ) / 2;
|
|
int y = ( rc.bottom - rc.top - bm.bmHeight ) / 2;
|
|
|
|
SetWindowPos( hwnd, NULL, x, y, bm.bmWidth, bm.bmHeight, SWP_NOZORDER | SWP_NOACTIVATE );
|
|
}
|
|
}
|
|
return TRUE;
|
|
|
|
case WM_PAINT:
|
|
{
|
|
HBITMAP hbmBackground = (HBITMAP) GetWindowLongPtr( hwnd, GWLP_USERDATA );
|
|
|
|
PAINTSTRUCT ps;
|
|
HDC hdc = BeginPaint( hwnd, &ps );
|
|
|
|
BITMAP bm;
|
|
|
|
if ( hbmBackground )
|
|
{
|
|
DWORD dwLayout = SetLayout(hdc, LAYOUT_BITMAPORIENTATIONPRESERVED);
|
|
if ( GetObject( hbmBackground, sizeof(bm), &bm ) )
|
|
{
|
|
HDC hdcBackground = CreateCompatibleDC( hdc );
|
|
if (hdcBackground)
|
|
{
|
|
HBITMAP hbmOld = (HBITMAP) SelectObject( hdcBackground, hbmBackground );
|
|
BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcBackground, 0, 0, SRCCOPY);
|
|
SelectObject( hdcBackground, hbmOld );
|
|
DeleteDC( hdcBackground );
|
|
}
|
|
}
|
|
SetLayout(hdc, dwLayout);
|
|
|
|
// Don't draw more the once, no one will be on top of us
|
|
DeleteObject(hbmBackground);
|
|
SetWindowLongPtr( hwnd, GWLP_USERDATA, NULL );
|
|
|
|
HFONT hfntSelected = NULL;
|
|
HFONT hfntButton = NULL;
|
|
HINSTANCE hMsGina = LoadLibrary( L"msgina.dll" );
|
|
if ( hMsGina )
|
|
{
|
|
CHAR szPixelSize[ 32 ];
|
|
if (LoadStringA(hMsGina,
|
|
IDS_TURNOFF_TITLE_FACESIZE,
|
|
szPixelSize,
|
|
ARRAYSIZE(szPixelSize)) != 0)
|
|
{
|
|
LOGFONT logFont = { 0 };
|
|
logFont.lfHeight = -MulDiv(atoi(szPixelSize), GetDeviceCaps(hdc, LOGPIXELSY), 72);
|
|
|
|
if (LoadString(hMsGina,
|
|
IDS_TURNOFF_TITLE_FACENAME,
|
|
logFont.lfFaceName,
|
|
LF_FACESIZE) != 0)
|
|
{
|
|
logFont.lfWeight = FW_BOLD;
|
|
logFont.lfQuality = DEFAULT_QUALITY;
|
|
hfntButton = CreateFontIndirect(&logFont);
|
|
|
|
hfntSelected = static_cast<HFONT>(SelectObject(hdc, hfntButton));
|
|
}
|
|
}
|
|
}
|
|
|
|
COLORREF colorButtonText = RGB(255, 255, 255);
|
|
COLORREF colorText = SetTextColor(hdc, colorButtonText);
|
|
int iBkMode = SetBkMode(hdc, TRANSPARENT);
|
|
|
|
WCHAR szText[MAX_PATH];
|
|
szText[0] = 0;
|
|
LoadString((HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), IDS_PLEASEWAIT, szText, ARRAYSIZE(szText));
|
|
RECT rcText;
|
|
RECT rcClient;
|
|
RECT rc;
|
|
|
|
TBOOL(GetClientRect( hwnd, &rcClient ));
|
|
TBOOL(CopyRect(&rcText, &rcClient));
|
|
DWORD dwFlags = DT_HIDEPREFIX | (IS_MIRRORING_ENABLED() ? DT_RTLREADING : 0);
|
|
int iPixelHeight = DrawText( hdc, szText, -1, &rcText, DT_CALCRECT | dwFlags);
|
|
TBOOL(CopyRect(&rc, &rcClient));
|
|
TBOOL(InflateRect(&rc, -((rc.right - rc.left - (rcText.right - rcText.left)) / 2), -((rc.bottom - rc.top - iPixelHeight) / 2)));
|
|
(int)DrawText(hdc, szText, -1, &rc, dwFlags );
|
|
(int)SetBkMode(hdc, iBkMode);
|
|
(COLORREF)SetTextColor(hdc, colorText);
|
|
|
|
if ( hfntButton )
|
|
{
|
|
(HGDIOBJ)SelectObject(hdc, hfntSelected);
|
|
DeleteObject( hfntButton );
|
|
}
|
|
}
|
|
|
|
EndPaint( hwnd, &ps );
|
|
}
|
|
break;
|
|
|
|
case WM_ERASEBKGND:
|
|
return TRUE;
|
|
|
|
default:
|
|
return DefWindowProc( hwnd, msg, wp, lParam );
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
CDimmedWindow::CDimmedWindow (HINSTANCE hInstance) :
|
|
_lReferenceCount(1),
|
|
_hInstance(hInstance)
|
|
{
|
|
WNDCLASSEX wndClassEx;
|
|
|
|
ZeroMemory(&wndClassEx, sizeof(wndClassEx));
|
|
wndClassEx.cbSize = sizeof(wndClassEx);
|
|
wndClassEx.lpfnWndProc = WndProc;
|
|
wndClassEx.hInstance = hInstance;
|
|
wndClassEx.lpszClassName = g_szWindowClassName;
|
|
wndClassEx.hCursor = LoadCursor(NULL, IDC_WAIT);
|
|
_atom = RegisterClassEx(&wndClassEx);
|
|
|
|
wndClassEx.lpszClassName = g_szPleaseWaitName;
|
|
wndClassEx.lpfnWndProc = PleaseWaitWndProc;
|
|
_atomPleaseWait = RegisterClassEx(&wndClassEx);
|
|
}
|
|
|
|
CDimmedWindow::~CDimmedWindow (void)
|
|
{
|
|
if (_hwnd)
|
|
{
|
|
PostMessage(_hwnd, WM_DESTORYYOURSELF, 0, 0);
|
|
}
|
|
|
|
if (_atom != 0)
|
|
{
|
|
TBOOL(UnregisterClass(MAKEINTRESOURCE(_atom), _hInstance));
|
|
}
|
|
|
|
if (_atomPleaseWait != 0 )
|
|
{
|
|
TBOOL(UnregisterClass(MAKEINTRESOURCE(_atomPleaseWait), _hInstance));
|
|
}
|
|
}
|
|
|
|
ULONG CDimmedWindow::AddRef (void)
|
|
{
|
|
return(InterlockedIncrement(&_lReferenceCount));
|
|
}
|
|
|
|
ULONG CDimmedWindow::Release (void)
|
|
{
|
|
LONG lReferenceCount;
|
|
|
|
lReferenceCount = InterlockedDecrement(&_lReferenceCount);
|
|
|
|
ASSERTMSG(lReferenceCount >= 0, "Reference count negative or zero in CDimmedWindow::Release");
|
|
|
|
if (lReferenceCount == 0)
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
return(lReferenceCount);
|
|
}
|
|
|
|
DWORD CDimmedWindow::WorkerThread(IN void *pv)
|
|
{
|
|
ASSERT(pv);
|
|
HWND hwnd = NULL;
|
|
CDimmedWindow* pDimmedWindow = (CDimmedWindow*)pv;
|
|
BOOL fScreenReader;
|
|
bool fNoDebuggerPresent, fNoScreenReaderPresent;
|
|
BOOL fUserTurnedOffWindow = SHRegGetBoolUSValue(SZ_THEMES, L"NoCoverWindow", FALSE, FALSE); // Needed for perf testing
|
|
|
|
fNoDebuggerPresent = !IsDebuggerPresent();
|
|
fNoScreenReaderPresent = ((SystemParametersInfo(SPI_GETSCREENREADER, 0, &fScreenReader, 0) == FALSE) || (fScreenReader == FALSE));
|
|
if (fNoDebuggerPresent &&
|
|
fNoScreenReaderPresent &&
|
|
!fUserTurnedOffWindow)
|
|
{
|
|
int xVirtualScreen = GetSystemMetrics(SM_XVIRTUALSCREEN);
|
|
int yVirtualScreen = GetSystemMetrics(SM_YVIRTUALSCREEN);
|
|
int cxVirtualScreen = GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
|
int cyVirtualScreen = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
|
HWND hwnd = CreateWindowEx(WS_EX_TOPMOST,
|
|
g_szWindowClassName,
|
|
NULL,
|
|
WS_POPUP | WS_CLIPCHILDREN,
|
|
xVirtualScreen, yVirtualScreen,
|
|
cxVirtualScreen, cyVirtualScreen,
|
|
NULL, NULL, pDimmedWindow->_hInstance, NULL);
|
|
if (hwnd != NULL)
|
|
{
|
|
bool fDimmed;
|
|
HBITMAP hbmBackground = NULL;
|
|
|
|
fDimmed = false;
|
|
(BOOL)ShowWindow(hwnd, SW_SHOW);
|
|
TBOOL(SetForegroundWindow(hwnd));
|
|
|
|
(BOOL)EnableWindow(hwnd, FALSE);
|
|
|
|
SetTimer(hwnd, IDT_KILLYOURSELF, pDimmedWindow->_ulKillTimer, NULL);
|
|
|
|
// Now create bitmap with background image and the windows flag
|
|
HINSTANCE hShell32 = LoadLibrary( L"shell32.dll" );
|
|
if ( NULL != hShell32 )
|
|
{
|
|
hbmBackground = (HBITMAP) LoadImage( hShell32, MAKEINTRESOURCE( IDB_BACKGROUND_24 ), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE );
|
|
|
|
if (hbmBackground)
|
|
{
|
|
HDC hdcMem1 = CreateCompatibleDC(NULL);
|
|
if (hdcMem1)
|
|
{
|
|
HDC hdcMem2 = CreateCompatibleDC(NULL);
|
|
if (hdcMem2)
|
|
{
|
|
HBITMAP hbmFlag = (HBITMAP) LoadImage( hShell32, MAKEINTRESOURCE( IDB_FLAG_24 ), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE );
|
|
if (hbmFlag)
|
|
{
|
|
HBITMAP hbmOld1 = (HBITMAP)SelectObject(hdcMem1, hbmBackground);
|
|
HBITMAP hbmOld2 = (HBITMAP)SelectObject(hdcMem2, hbmFlag);
|
|
|
|
BITMAP bm1;
|
|
if (GetObject(hbmBackground, sizeof(bm1), &bm1))
|
|
{
|
|
BITMAP bm2;
|
|
if (GetObject(hbmFlag, sizeof(bm2), &bm2))
|
|
{
|
|
BitBlt(hdcMem1, bm1.bmWidth - bm2.bmWidth - 8, 0, bm2.bmWidth, bm2.bmHeight, hdcMem2, 0, 0, SRCCOPY);
|
|
}
|
|
}
|
|
|
|
SelectObject(hdcMem1, hbmOld1);
|
|
SelectObject(hdcMem2, hbmOld2);
|
|
DeleteObject(hbmFlag);
|
|
}
|
|
DeleteDC(hdcMem2);
|
|
}
|
|
DeleteDC(hdcMem1);
|
|
}
|
|
}
|
|
|
|
FreeLibrary( hShell32 );
|
|
}
|
|
|
|
HWND hwndPleaseWait = CreateWindowEx( 0
|
|
, g_szPleaseWaitName
|
|
, NULL
|
|
, WS_CHILD | WS_VISIBLE | WS_BORDER
|
|
, 0
|
|
, 0
|
|
, 100
|
|
, 100
|
|
, hwnd
|
|
, NULL
|
|
, pDimmedWindow->_hInstance
|
|
, hbmBackground // the window is responsible for freeing it.
|
|
);
|
|
if ( NULL == hwndPleaseWait )
|
|
{
|
|
DeleteObject( hbmBackground );
|
|
}
|
|
|
|
pDimmedWindow->_hwnd = hwnd;
|
|
// This Release matches the addref during ::Create to guarantee that the object does not die before the HWND
|
|
// is created.
|
|
pDimmedWindow->Release();
|
|
|
|
MSG msg;
|
|
while (GetMessage(&msg, NULL, 0, 0))
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
if ((msg.message == WM_DESTORYYOURSELF) && (msg.hwnd == hwnd))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return (hwnd == NULL ? E_FAIL : S_OK);
|
|
}
|
|
|
|
HRESULT CDimmedWindow::Create (UINT ulKillTimer)
|
|
{
|
|
BOOL fSucceeded = FALSE;
|
|
|
|
if (!_hwnd)
|
|
{
|
|
_ulKillTimer = ulKillTimer;
|
|
AddRef();
|
|
fSucceeded = SHCreateThread(CDimmedWindow::WorkerThread, (void *)this, CTF_INSIST, NULL);
|
|
if (!fSucceeded)
|
|
{
|
|
Release();
|
|
}
|
|
}
|
|
|
|
return fSucceeded ? S_OK : E_FAIL;
|
|
}
|
|
|
|
typedef struct
|
|
{
|
|
HDC hdcDimmed;
|
|
HBITMAP hbmDimmed;
|
|
HBITMAP hbmOldDimmed;
|
|
HDC hdcTemp;
|
|
HBITMAP hbmTemp;
|
|
HBITMAP hbmOldTemp;
|
|
ULONG* pulSrc;
|
|
int idxSaturation;
|
|
int idxChunk;
|
|
int idxProgress;
|
|
} DIMMEDWINDOWDATA;
|
|
|
|
LRESULT CALLBACK CDimmedWindow::WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
LRESULT lResult = 0;
|
|
DIMMEDWINDOWDATA *pData;
|
|
|
|
pData = (DIMMEDWINDOWDATA *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_CREATE:
|
|
{
|
|
CREATESTRUCT* pCS = (CREATESTRUCT*)lParam;
|
|
if (pCS)
|
|
{
|
|
pData = new DIMMEDWINDOWDATA;
|
|
if (pData)
|
|
{
|
|
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pData);
|
|
// On remote session we don't gray out the screen, yeah :-)
|
|
if (!GetSystemMetrics(SM_REMOTESESSION))
|
|
{
|
|
HDC hdcWindow = GetDC(hwnd);
|
|
if (hdcWindow != NULL )
|
|
{
|
|
pData->hdcDimmed = CreateCompatibleDC(hdcWindow);
|
|
if (pData->hdcDimmed)
|
|
{
|
|
BITMAPINFO bmi;
|
|
|
|
ZeroMemory(&bmi, sizeof(bmi));
|
|
bmi.bmiHeader.biSize = sizeof(bmi);
|
|
bmi.bmiHeader.biWidth = pCS->cx;
|
|
bmi.bmiHeader.biHeight = pCS->cy;
|
|
bmi.bmiHeader.biPlanes = 1;
|
|
bmi.bmiHeader.biBitCount = 32;
|
|
bmi.bmiHeader.biCompression = BI_RGB;
|
|
bmi.bmiHeader.biSizeImage = 0;
|
|
|
|
pData->hbmDimmed = CreateDIBSection(pData->hdcDimmed, &bmi, DIB_RGB_COLORS, (LPVOID*)&pData->pulSrc, NULL, 0);
|
|
if (pData->hbmDimmed != NULL)
|
|
{
|
|
pData->hbmOldDimmed = (HBITMAP) SelectObject(pData->hdcDimmed, pData->hbmDimmed);
|
|
pData->idxSaturation = 8;
|
|
pData->idxChunk = pCS->cy / CHUNK_SIZE;
|
|
}
|
|
else
|
|
{
|
|
DeleteDC(pData->hdcDimmed);
|
|
pData->hdcDimmed = NULL;
|
|
}
|
|
}
|
|
|
|
pData->hdcTemp = CreateCompatibleDC(hdcWindow);
|
|
if (pData->hdcTemp)
|
|
{
|
|
pData->hbmTemp = CreateCompatibleBitmap(hdcWindow, pCS->cx, pCS->cy);
|
|
if (pData->hbmTemp)
|
|
{
|
|
pData->hbmOldTemp = (HBITMAP) SelectObject(pData->hdcTemp, pData->hbmTemp);
|
|
}
|
|
else
|
|
{
|
|
DeleteDC(pData->hdcTemp);
|
|
pData->hdcTemp = NULL;
|
|
}
|
|
}
|
|
|
|
ReleaseDC(hwnd, hdcWindow);
|
|
}
|
|
}
|
|
|
|
if (pData->hdcDimmed)
|
|
{
|
|
SetTimer(hwnd, IDT_UPDATE, 30, NULL);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WM_DESTORYYOURSELF:
|
|
{
|
|
DestroyWindow(hwnd);
|
|
break;
|
|
}
|
|
|
|
case WM_DESTROY:
|
|
{
|
|
if (pData)
|
|
{
|
|
SetWindowLongPtr(hwnd, GWLP_USERDATA, NULL);
|
|
KillTimer(hwnd, IDT_UPDATE);
|
|
KillTimer(hwnd, IDT_KILLYOURSELF);
|
|
|
|
if (pData->hdcDimmed)
|
|
{
|
|
SelectObject(pData->hdcDimmed, pData->hbmOldDimmed);
|
|
DeleteDC(pData->hdcDimmed);
|
|
pData->hdcDimmed = NULL;
|
|
}
|
|
|
|
if (pData->hbmDimmed)
|
|
{
|
|
DeleteObject(pData->hbmDimmed);
|
|
pData->hbmDimmed = NULL;
|
|
}
|
|
|
|
if (pData->hdcTemp)
|
|
{
|
|
SelectObject(pData->hdcTemp, pData->hbmOldTemp);
|
|
DeleteDC(pData->hdcTemp);
|
|
pData->hdcTemp = NULL;
|
|
}
|
|
|
|
if (pData->hbmTemp)
|
|
{
|
|
DeleteObject(pData->hbmTemp);
|
|
pData->hbmTemp = NULL;
|
|
}
|
|
|
|
delete pData;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WM_TIMER:
|
|
if (pData)
|
|
{
|
|
BOOL fDestroyBitmaps = FALSE;
|
|
|
|
if (wParam == IDT_KILLYOURSELF)
|
|
{
|
|
ShowWindow(hwnd, SW_HIDE);
|
|
|
|
fDestroyBitmaps = TRUE;
|
|
}
|
|
else if (pData->hdcDimmed && pData->hbmDimmed)
|
|
{
|
|
HDC hdcWindow = GetDC(hwnd);
|
|
|
|
BITMAP bm;
|
|
GetObject(pData->hbmDimmed, sizeof(BITMAP), &bm);
|
|
|
|
if (pData->idxChunk >= 0 )
|
|
{
|
|
//
|
|
// In the first couple of passes, we slowly collect the screen
|
|
// into our bitmap. We do this because Blt-ing the whole thing
|
|
// causes the system to hang. By doing it this way, we continue
|
|
// to pump messages, the UI stays responsive and it keeps the
|
|
// mouse alive.
|
|
//
|
|
|
|
int y = pData->idxChunk * CHUNK_SIZE;
|
|
if (pData->hdcTemp)
|
|
{
|
|
BitBlt(pData->hdcTemp, 0, y, bm.bmWidth, CHUNK_SIZE, hdcWindow, 0, y, SRCCOPY);
|
|
BitBlt(pData->hdcDimmed, 0, y, bm.bmWidth, CHUNK_SIZE, pData->hdcTemp, 0, y, SRCCOPY);
|
|
}
|
|
else
|
|
{
|
|
BitBlt(pData->hdcDimmed, 0, y, bm.bmWidth, CHUNK_SIZE, hdcWindow, 0, y, SRCCOPY);
|
|
}
|
|
|
|
pData->idxChunk--;
|
|
if (pData->idxChunk < 0)
|
|
{
|
|
//
|
|
// We're done getting the bitmap, now reset the timer
|
|
// so we slowly fade to grey.
|
|
//
|
|
|
|
SetTimer(hwnd, IDT_UPDATE, 250, NULL);
|
|
pData->idxSaturation = 16;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// In these passes, we are making the image more and more grey and
|
|
// then Blt-ing the result to the screen.
|
|
//
|
|
|
|
DimPixels(pData->pulSrc, bm.bmWidth * bm.bmHeight, 0xd5);
|
|
BitBlt(hdcWindow, 0, 0, bm.bmWidth, bm.bmHeight, pData->hdcDimmed, 0, 0, SRCCOPY);
|
|
|
|
pData->idxSaturation--;
|
|
|
|
if (pData->idxSaturation <= 0) // when we hit zero, kill the timer.
|
|
{
|
|
KillTimer(hwnd, IDT_UPDATE);
|
|
fDestroyBitmaps = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (fDestroyBitmaps)
|
|
{
|
|
if (pData->hdcDimmed)
|
|
{
|
|
SelectObject(pData->hdcDimmed, pData->hbmOldDimmed);
|
|
DeleteDC(pData->hdcDimmed);
|
|
pData->hdcDimmed = NULL;
|
|
}
|
|
|
|
if (pData->hbmDimmed)
|
|
{
|
|
DeleteObject(pData->hbmDimmed);
|
|
pData->hbmDimmed = NULL;
|
|
}
|
|
|
|
if (pData->hdcTemp)
|
|
{
|
|
SelectObject(pData->hdcTemp, pData->hbmOldTemp);
|
|
DeleteDC(pData->hdcTemp);
|
|
pData->hdcTemp = NULL;
|
|
}
|
|
|
|
if (pData->hbmTemp)
|
|
{
|
|
DeleteObject(pData->hbmTemp);
|
|
pData->hbmTemp = NULL;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_WINDOWPOSCHANGING:
|
|
{
|
|
LPWINDOWPOS pwp = (LPWINDOWPOS) lParam;
|
|
pwp->flags |= SWP_NOSIZE | SWP_NOMOVE;
|
|
}
|
|
break;
|
|
|
|
case WM_PAINT:
|
|
{
|
|
HDC hdcPaint;
|
|
PAINTSTRUCT ps;
|
|
|
|
hdcPaint = BeginPaint(hwnd, &ps);
|
|
TBOOL(EndPaint(hwnd, &ps));
|
|
lResult = 0;
|
|
break;
|
|
}
|
|
default:
|
|
lResult = DefWindowProc(hwnd, uMsg, wParam, lParam);
|
|
break;
|
|
}
|
|
|
|
return(lResult);
|
|
}
|
|
|
|
|