- WINSCR: Based on feedback from WCG about the screensaver lock-up

problem attempt to provoke Windows into redrawing the primary
        display.  It turns out that the screensaver image is a ghost
        image, so create a blank top-most window and close it after
        the graphics application has been terminated.
        
    clientscr/
        screensaver_win.cpp, .h

svn path=/trunk/boinc/; revision=24013
This commit is contained in:
Rom Walton 2011-08-18 09:56:11 +00:00
parent ad73c56c9d
commit 16b2a83b41
3 changed files with 154 additions and 0 deletions

View File

@ -4916,3 +4916,13 @@ Charlie 12 Aug 2011
mac_installer/
AddRemoveUser.cpp
PostInstall.cpp
Rom 18 Aug 2011
- WINSCR: Based on feedback from WCG about the screensaver lock-up
problem attempt to provoke Windows into redrawing the primary
display. It turns out that the screensaver image is a ghost
image, so create a blank top-most window and close it after
the graphics application has been terminated.
clientscr/
screensaver_win.cpp, .h

View File

@ -91,6 +91,13 @@ INT WINAPI WinMain(
BOINCTRACE("WinMain - Cleanup Screensaver Resources\n");
BOINCSS.Cleanup();
// Resetting the primary display. We need to do this because abnormally
// terminating grtaphics applications can sometimes leave a ghosted image
// on the primary display which leaves users believing that their machines
// are locked up.
BOINCTRACE("WinMain - Reset Primary Display\n");
BOINCSS.ResetPrimaryDisplay();
// Cleanup the Windows sockets interface.
BOINCTRACE("WinMain - Cleanup Winsock Resources\n");
WSACleanup();
@ -1227,6 +1234,71 @@ HRESULT CScreensaver::CreateSaverWindow() {
// Register and create the appropriate window(s)
//
HRESULT CScreensaver::ResetPrimaryDisplay() {
// Register an appropriate window class for the primary display
WNDCLASS cls;
cls.hCursor = LoadCursor(NULL, IDC_ARROW);
cls.hIcon = LoadIcon(m_hInstance, MAKEINTRESOURCE(IDI_MAIN_ICON));
cls.lpszMenuName = NULL;
cls.lpszClassName = _T("BOINCPrimaryResetWndClass");
cls.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
cls.hInstance = m_hInstance;
cls.style = CS_VREDRAW|CS_HREDRAW;
cls.lpfnWndProc = ResetProcStub;
cls.cbWndExtra = 0;
cls.cbClsExtra = 0;
RegisterClass(&cls);
// Create the window
INTERNALMONITORINFO* pMonitorInfo;
pMonitorInfo = &m_Monitors[0];
pMonitorInfo->hWnd = CreateWindowEx(
NULL,
_T("BOINCPrimaryResetWndClass"),
m_strWindowTitle,
WS_VISIBLE | WS_POPUP,
pMonitorInfo->rcScreen.left,
pMonitorInfo->rcScreen.top,
pMonitorInfo->rcScreen.right - pMonitorInfo->rcScreen.left,
pMonitorInfo->rcScreen.bottom - pMonitorInfo->rcScreen.top,
NULL,
NULL,
m_hInstance,
this
);
if (pMonitorInfo->hWnd == NULL) {
return E_FAIL;
}
SetTimer(pMonitorInfo->hWnd, 2, 250, NULL);
if (m_hWnd == NULL) {
return E_FAIL;
}
// Message pump
BOOL bGotMsg;
MSG msg;
msg.message = WM_NULL;
while (msg.message != WM_QUIT) {
bGotMsg = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
if (bGotMsg) {
TranslateMessage(&msg);
DispatchMessage(&msg);
} else {
Sleep(10);
}
}
return S_OK;
}
// Run the screensaver graphics - may be preview, test or full-on mode
//
HRESULT CScreensaver::DoSaver() {
@ -1578,6 +1650,61 @@ LRESULT CScreensaver::GenericSaverProc(
// Handle window messages for resetting the primary display.
//
LRESULT CScreensaver::ResetProc(
HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
) {
DWORD dwMonitor = 0;
#ifdef _DEBUG
for(DWORD iIndex = 0; iIndex < m_dwNumMonitors; iIndex++) {
if (hWnd == m_Monitors[iIndex].hWnd ) {
dwMonitor = iIndex;
}
}
BOINCTRACE(_T("CScreensaver::ResetProc [%d] hWnd '%d' uMsg '%X' wParam '%d' lParam '%d'\n"), dwMonitor, hWnd, uMsg, wParam, lParam);
#endif
switch (uMsg) {
case WM_TIMER:
BOINCTRACE(_T("CScreensaver::ResetProc Received WM_TIMER\n"));
switch (wParam) {
case 1:
KillTimer(hWnd, 1);
CloseWindow(hWnd);
return 0;
break;
}
break;
case WM_PAINT:
PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
RECT rc;
GetClientRect(hWnd,&rc);
FillRect(ps.hdc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
EndPaint(hWnd, &ps);
return 0;
break;
case WM_CLOSE:
BOINCTRACE(_T("CScreensaver::ResetProc Received WM_CLOSE\n"));
break;
}
if (WM_SETTIMER == uMsg) {
BOINCTRACE(_T("CScreensaver::ResetProc Received WM_SETTIMER\n"));
// All initialization messages have gone through. Allow
// 500ms of idle time, then proceed with initialization.
SetTimer(hWnd, 1, 250, NULL);
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
DWORD CScreensaver::ConvertSliderPositionToTime( DWORD dwPosition ) {
return dwTableSliderPositionToTime[dwPosition];
}
@ -1738,6 +1865,18 @@ LRESULT CALLBACK CScreensaver::GenericSaverProcStub(
// This function forwards all window messages to ResetProc, which has
// access to the "this" pointer.
//
LRESULT CALLBACK CScreensaver::ResetProcStub(
HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
) {
return gspScreensaver->ResetProc(hWnd, uMsg, wParam, lParam);
}
INT_PTR CALLBACK CScreensaver::ConfigureDialogProcStub(
HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
) {

View File

@ -213,6 +213,9 @@ protected:
//
// Presentation layer
//
public:
HRESULT ResetPrimaryDisplay();
protected:
HRESULT CreateSaverWindow();
VOID UpdateErrorBox();
@ -225,6 +228,7 @@ protected:
VOID DoPaint( HWND hwnd, HDC hdc, LPPAINTSTRUCT lpps );
LRESULT SaverProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
LRESULT GenericSaverProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
LRESULT ResetProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
DWORD ConvertSliderPositionToTime( DWORD dwPosition );
DWORD ConvertTimeToSliderPosition( DWORD dwMinutes );
@ -235,6 +239,7 @@ protected:
static LRESULT CALLBACK SaverProcStub( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
static LRESULT CALLBACK GenericSaverProcStub( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
static LRESULT CALLBACK ResetProcStub( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
static INT_PTR CALLBACK ConfigureDialogProcStub( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
protected: