www.pudn.com > SaveScreen.rar > ScreenSaver.cpp, change:2000-09-18,size:13256b


 
#include "stdafx.h" 
#include "resource.h" 
#include <scrnsave.h> 
#include <regstr.h> 
#include "ScreenSaver.h" 
 
// Function definition of PwdChangePassword and helper struct for 
// Windows 95. Helper structure (also found in pwdspi.h) 
typedef struct _CHANGEPWDINFO 
{ 
  LPSTR lpUsername; 
  LPSTR lpPassword; 
  DWORD cbPassword; 
} CHANGEPWDINFOA, FAR *LPCHANGEPWDINFOA; 
 
typedef DWORD (WINAPI *LPPWDCHANGEPASSWORDA)(LPCSTR, HWND, DWORD, LPCHANGEPWDINFOA); 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
// Implementation 
 
CScreenSaverCommandLineInfo::CScreenSaverCommandLineInfo() 
{ 
	m_nShellCommand = ShowConfigureDialog; 
	m_hParentWnd = 0; 
} 
 
CScreenSaverCommandLineInfo::~CScreenSaverCommandLineInfo() 
{ 
} 
 
void CScreenSaverCommandLineInfo::ParseParam(LPCTSTR pszParam, BOOL /*bFlag*/, BOOL /*bLast*/) 
{ 
	if( (lstrcmpi(pszParam, _T("c")) == 0) || 
		(lstrcmpi(pszParam, _T("C")) == 0) ) 
		m_nShellCommand = ShowConfigureDialog; 
	else if ( (lstrcmpi(pszParam, _T("p")) == 0) || 
		(lstrcmpi(pszParam, _T("P")) == 0) ) 
		m_nShellCommand = PreviewMode; 
	else if ( (lstrcmpi(pszParam, _T("s")) == 0) || 
		(lstrcmpi(pszParam, _T("S")) == 0) ) 
		m_nShellCommand = ScreenSaverMode; 
	else if ( (lstrcmpi(pszParam, _T("a")) == 0) || 
		(lstrcmpi(pszParam, _T("A")) == 0) ) 
		m_nShellCommand = ShowChangePasswordDialog; 
	else if ((_tcsstr(pszParam, _T("a:")) ||     //Handle the undocumented format of /a namely "/a:HWND" 
		_tcsstr(pszParam, _T("A:"))) && 
		_tcslen(pszParam) > 2)               
	{ 
		m_nShellCommand = ShowChangePasswordDialog; 
		m_hParentWnd = (HWND) _ttoi(pszParam+2); 
	} 
	else if ((_tcsstr(pszParam, _T("c:")) ||     //Handle the undocumented format of /c namely "/c:HWND" 
		_tcsstr(pszParam, _T("C:"))) && 
		_tcslen(pszParam) > 2)               
	{ 
		m_nShellCommand = ShowConfigureDialog; 
		m_hParentWnd = (HWND) _ttoi(pszParam+2); 
	} 
	else 
	{ 
		//Convert the parameter to a window handle 
		m_hParentWnd = (HWND) _ttoi(pszParam); 
	} 
} 
 
IMPLEMENT_DYNCREATE(CScreenSaverWnd, CWnd) 
 
BEGIN_MESSAGE_MAP(CScreenSaverWnd, CWnd) 
	//{{AFX_MSG_MAP(CScreenSaverWnd) 
	ON_WM_SYSCOMMAND() 
	ON_WM_SETCURSOR() 
	ON_WM_ACTIVATE() 
	ON_WM_ACTIVATEAPP() 
	ON_WM_MOUSEMOVE() 
	ON_WM_LBUTTONDOWN() 
	ON_WM_RBUTTONDOWN() 
	ON_WM_MBUTTONDOWN() 
	ON_WM_KEYDOWN() 
	ON_WM_SYSKEYDOWN() 
	ON_WM_PAINT() 
	ON_WM_CLOSE() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
CScreenSaverWnd::CScreenSaverWnd() 
{ 
	m_bGotCursorPos = FALSE; 
	m_bPreview = FALSE; 
	m_bPasswordProtected = FALSE; 
	m_bDialogUp = FALSE; 
	m_hPasswordCpl = NULL; 
 
	//Determine if the screen saver is password protected  
	//Note: this only applies to Win9x as NT handles password 
	//protected screen savers itself. 
	OSVERSIONINFO osvi; 
	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 
	if (GetVersionEx(&osvi) && osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) 
	{ 
		HKEY hKey; 
		LONG nError = RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_SCREENSAVE, 0, KEY_ALL_ACCESS, &hKey); 
		if (nError == ERROR_SUCCESS)  
		{ 
			DWORD dwSize = sizeof(BOOL); 
			RegQueryValueEx(hKey, REGSTR_VALUE_USESCRPASSWORD, 0, NULL, (LPBYTE) &m_bPasswordProtected, &dwSize); 
			RegCloseKey(hKey); 
		} 
 
		//Also make sure we have the function pointer to allow validation of the screen saver password 
		if (m_bPasswordProtected) 
		{ 
			//Load up the Verify Screen saver function in the password dll 
			m_hPasswordCpl = LoadLibrary(_T("Password.cpl")); 
			if (m_hPasswordCpl) 
			{ 
				m_lpfnVerifyScreenSavePwd = (LPVERIFYSCREENSAVEPWD) GetProcAddress(m_hPasswordCpl, "VerifyScreenSavePwd"); 
				m_bPasswordProtected = (m_lpfnVerifyScreenSavePwd != NULL); 
			} 
		} 
	} 
 
	//Disable Alt-Tabbing if required 
	if (m_bPasswordProtected) 
	{ 
		int nPrev=0; 
		SystemParametersInfo(SPI_SCREENSAVERRUNNING, TRUE, &nPrev, 0); 
	} 
} 
 
CScreenSaverWnd::~CScreenSaverWnd() 
{ 
	//Free up the Password.cpl file if loaded 
	if (m_hPasswordCpl) 
		FreeLibrary(m_hPasswordCpl); 
 
	if (m_bPasswordProtected) 
	{ 
		//Reenable Alt-Tabbing if required       
		int nPrev=0; 
		SystemParametersInfo(SPI_SCREENSAVERRUNNING, FALSE, &nPrev, 0); 
	} 
} 
 
CRect CScreenSaverWnd::GetBoundingRect(BOOL bChild, CWnd* pParentWnd) 
{ 
	CRect r; 
	if (bChild) 
		pParentWnd->GetClientRect(&r); 
	else 
	{ 
		//Get the bounding rect of the screen, This 
		//will also handle the case of multiple monitors 
		HDC hScreenDC = ::GetDC(NULL); 
		::GetClipBox(hScreenDC, r); 
		::ReleaseDC(NULL, hScreenDC); 
	} 
	return r; 
} 
 
DWORD CScreenSaverWnd::GetWindowStyle(BOOL bChild, CWnd* /*pParentWnd*/) 
{ 
	//Calculate the window and extended window styles 
	DWORD dwStyle=0; 
	if (bChild) 
		dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; 
	else 
		dwStyle = WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; 
 
	return dwStyle; 
} 
 
DWORD CScreenSaverWnd::GetExtendedWindowStyle(BOOL bChild, CWnd* /*pParentWnd*/) 
{ 
	DWORD dwExStyle=0; 
	if (!bChild) 
	{ 
		//For testing purposes, do not make the window topmost 
		#ifndef _DEBUG 
			dwExStyle = WS_EX_TOPMOST; 
		#endif 
	} 
 
	return dwExStyle; 
} 
 
BOOL CScreenSaverWnd::Create(BOOL bChild, CWnd* pParentWnd) 
{ 
	//Register a class with an empty cursor and a black background 
	HCURSOR hCursor = LoadCursor(NULL, IDC_ARROW); 
	LPCTSTR pszClassName = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, hCursor, (HBRUSH) GetStockObject(BLACK_BRUSH)); 
 
	//Create the window, use the virtual functions to allow further customisation 
	return CWnd::CreateEx(GetExtendedWindowStyle(bChild, pParentWnd), 
		pszClassName,AfxGetApp()->m_pszAppName,GetWindowStyle(bChild,pParentWnd), 
		GetBoundingRect(bChild, pParentWnd), pParentWnd, 0); 
} 
 
void CScreenSaverWnd::OnSysCommand(UINT nID, LPARAM lParam)  
{ 
	if ((nID != SC_SCREENSAVE) && (nID != SC_CLOSE)) 
		CWnd::OnSysCommand(nID, lParam); 
} 
 
void CScreenSaverWnd::PostNcDestroy() 
{ 
	// default for screen saver windows is to allocate them on the heap 
	// the default post-cleanup is to 'delete this'. 
	// never explicitly call 'delete' on a CScreenSaverWnd, use DestroyWindow instead 
	delete this; 
} 
 
BOOL CScreenSaverWnd::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)  
{ 
	if (m_bPreview || m_bDialogUp) 
		return CWnd::OnSetCursor(pWnd, nHitTest, message); 
	else 
	{ 
		SetCursor(NULL);	 
		return TRUE; 
	} 
} 
 
void CScreenSaverWnd::OnActivateApp(BOOL bActive, HTASK hTask)  
{ 
  if (!bActive) 
  { 
    if (!m_bPreview && !m_bDialogUp) 
  	  PostMessage(WM_CLOSE); 
  } 
  else 
  	CWnd::OnActivateApp(bActive, hTask); 
} 
 
void CScreenSaverWnd::OnMouseMove(UINT /*nFlags*/, CPoint point)  
{ 
	if (m_bGotCursorPos) 
	{ 
		int nDeltaX = point.x - m_LastPos.x; 
		if (nDeltaX < 0) 
			nDeltaX *= -1; 
		int nDeltaY = point.y - m_LastPos.y; 
		if (nDeltaY < 0) 
			nDeltaY *= -1; 
		m_LastPos = point;   
 
		if (((nDeltaX + nDeltaY) > 3) && !m_bPreview && !m_bDialogUp) 
			PostMessage(WM_CLOSE); 
	} 
	else 
	{ 
		m_bGotCursorPos = TRUE; 
		m_LastPos = point; 
	} 
} 
 
void CScreenSaverWnd::OnKeyDown(UINT /*nChar*/, UINT /*nRepCnt*/, UINT /*nFlags*/)  
{ 
	if (!m_bPreview && !m_bDialogUp) 
		PostMessage(WM_CLOSE); 
} 
 
void CScreenSaverWnd::OnSysKeyDown(UINT /*nChar*/, UINT /*nRepCnt*/, UINT /*nFlags*/)  
{ 
	if (!m_bPreview && !m_bDialogUp) 
		PostMessage(WM_CLOSE); 
} 
 
void CScreenSaverWnd::OnPaint()  
{ 
	CPaintDC dc(this);  
	dc.SetTextColor(RGB(255, 255, 255)); 
	dc.SetBkMode(TRANSPARENT); 
	dc.TextOut(0, 0, _T("You need to override CScreenSaverWnd::OnPaint")); 
} 
 
void CScreenSaverWnd::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)  
{ 
	if (nState == WA_INACTIVE) 
	{ 
		if (!m_bPreview && !m_bDialogUp) 
			PostMessage(WM_CLOSE); 
	} 
	else 
		CWnd::OnActivate(nState, pWndOther, bMinimized); 
} 
 
void CScreenSaverWnd::OnLButtonDown(UINT /*nFlags*/, CPoint /*point*/)  
{ 
	if (!m_bPreview && !m_bDialogUp) 
		PostMessage(WM_CLOSE); 
} 
 
void CScreenSaverWnd::OnRButtonDown(UINT /*nFlags*/, CPoint /*point*/)  
{ 
	if (!m_bPreview && !m_bDialogUp) 
		PostMessage(WM_CLOSE); 
} 
 
void CScreenSaverWnd::OnMButtonDown(UINT /*nFlags*/, CPoint /*point*/)  
{ 
	if (!m_bPreview && !m_bDialogUp) 
		PostMessage(WM_CLOSE); 
} 
 
void CScreenSaverWnd::OnClose()  
{ 
	if (m_bPasswordProtected) 
	{ 
		//Return immediately if a dialog is already up 
		if (m_bDialogUp) 
			return; 
 
		//Call the "VerifyScreenSavePwd" funtion to validate the screen saver password 
		m_bDialogUp = TRUE; 
		BOOL bVerified = m_lpfnVerifyScreenSavePwd(GetSafeHwnd()); 
		m_bDialogUp = FALSE; 
		m_bGotCursorPos = FALSE; 
 
		//Only allow the screen saver to be closed if the password was verified 
		if (bVerified) CWnd::OnClose(); 
	} 
	else 
		CWnd::OnClose(); 
} 
 
BEGIN_MESSAGE_MAP(CScreenSaverApp, CWinApp) 
	//{{AFX_MSG_MAP(CScreenSaverApp) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
CScreenSaverApp::CScreenSaverApp() 
{ 
	m_pRuntimeScreenSaverWnd = NULL; 
} 
 
CScreenSaverApp::~CScreenSaverApp() 
{ 
} 
 
void CScreenSaverApp::SetScreenSaverTemplate(CRuntimeClass* pRuntimeScreenSaverWnd) 
{ 
	ASSERT(pRuntimeScreenSaverWnd); 
	ASSERT(pRuntimeScreenSaverWnd->IsDerivedFrom(RUNTIME_CLASS(CScreenSaverWnd))); 
	m_pRuntimeScreenSaverWnd = pRuntimeScreenSaverWnd; 
} 
 
void CScreenSaverApp::ShowConfigureDialog(CWnd* pParentWnd) 
{ 
	CString sMsg(_T("You need to override CScreenSaverApp::ShowConfigureDialog to allow your screen saver to be configured")); 
	if (pParentWnd) 
		::MessageBox(pParentWnd->GetSafeHwnd(), sMsg, m_pszAppName, MB_OK); 
	else 
		::MessageBox(NULL, sMsg, m_pszAppName, MB_OK); 
} 
 
void CScreenSaverApp::ChangePassword(CWnd* pParentWnd) 
{ 
	//Load the MPR dll and ask it to do the change in the "SCRSAVE" password provider 
	HINSTANCE hMpr = LoadLibrary(_T("mpr.dll")); 
	if (hMpr) 
	{ 
		// Must get PwdChangePasswordA because in Windows 95 we are using the ascii version of the exported function 
		LPPWDCHANGEPASSWORDA lpfnPwdChangePasswordA = (LPPWDCHANGEPASSWORDA) GetProcAddress(hMpr, "PwdChangePasswordA"); 
 
		// Call PwdChangePassword specifying "SCRSAVE" as network provider. 
		CHANGEPWDINFOA PwdInfo; 
		ZeroMemory(&PwdInfo, sizeof(CHANGEPWDINFOA)); 
		DWORD dwResult = lpfnPwdChangePasswordA("SCRSAVE", pParentWnd ? pParentWnd->GetSafeHwnd(): NULL, 0, &PwdInfo); 
 
		FreeLibrary(hMpr); 
	} 
} 
 
BOOL CScreenSaverApp::ProcessShellCommand(CScreenSaverCommandLineInfo& rCmdInfo) 
{ 
	BOOL bResult = FALSE; 
	switch (rCmdInfo.m_nShellCommand) 
	{ 
		case CScreenSaverCommandLineInfo::ScreenSaverMode: 
		{ 
			ASSERT(m_pRuntimeScreenSaverWnd); 
			CScreenSaverWnd* pMainWnd = (CScreenSaverWnd*) m_pRuntimeScreenSaverWnd->CreateObject(); 
			ASSERT(pMainWnd->IsKindOf(RUNTIME_CLASS(CScreenSaverWnd))); 
			pMainWnd->SetPreviewFlag(FALSE); 
			if (!pMainWnd->Create(FALSE, NULL)) 
			{ 
				TRACE(_T("Failed to create screen saver window, Error:%d\n"), GetLastError()); 
				return TRUE; 
			}   
			m_pMainWnd = pMainWnd; 
			bResult = TRUE; 
			break; 
		} 
 
		case CScreenSaverCommandLineInfo::PreviewMode: 
		{ 
			ASSERT(m_pRuntimeScreenSaverWnd); 
			CScreenSaverWnd* pMainWnd = (CScreenSaverWnd*) m_pRuntimeScreenSaverWnd->CreateObject(); 
			ASSERT(pMainWnd->IsKindOf(RUNTIME_CLASS(CScreenSaverWnd))); 
			pMainWnd->SetPreviewFlag(TRUE); 
			CWnd wndParent; 
			wndParent.Attach(rCmdInfo.m_hParentWnd); 
			if (!pMainWnd->Create(TRUE, &wndParent)) 
			{ 
				TRACE(_T("Failed to create screen saver window, Error:%d\n"), GetLastError()); 
				return TRUE; 
			}   
			m_pMainWnd = pMainWnd; 
			wndParent.Detach(); 
			bResult = TRUE; 
			break; 
		} 
 
		case CScreenSaverCommandLineInfo::ShowConfigureDialog: 
		{ 
			if (rCmdInfo.m_hParentWnd) 
			{ 
				CWnd wndParent; 
				wndParent.Attach(rCmdInfo.m_hParentWnd); 
				ShowConfigureDialog(&wndParent); 
				wndParent.Detach();         
			} 
			else 
				ShowConfigureDialog(CWnd::GetActiveWindow()); 
			bResult = FALSE; 
			break; 
		} 
 
		case CScreenSaverCommandLineInfo::ShowChangePasswordDialog: 
		{ 
			if (rCmdInfo.m_hParentWnd) 
			{ 
				CWnd wndParent; 
				wndParent.Attach(rCmdInfo.m_hParentWnd); 
				ChangePassword(&wndParent); 
				wndParent.Detach(); 
			} 
			else 
				ChangePassword(CWnd::GetActiveWindow()); 
			bResult = FALSE; 
			break; 
		} 
 
		default: 
			ASSERT(FALSE); 
			break; 
	} 
	return bResult; 
} 
 
void CScreenSaverApp::ParseCommandLine(CScreenSaverCommandLineInfo& rCmdInfo) 
{ 
	for (int i = 1; i < __argc; i++) 
	{ 
#ifdef _UNICODE 
		LPCTSTR pszParam = __wargv[i]; 
#else 
		LPCTSTR pszParam = __argv[i]; 
#endif 
		BOOL bFlag = FALSE; 
		BOOL bLast = ((i + 1) == __argc); 
		if (pszParam[0] == _T('-') || pszParam[0] == _T('/')) 
		{ 
			// remove flag specifier 
			bFlag = TRUE; 
			++pszParam; 
		} 
		rCmdInfo.ParseParam(pszParam, bFlag, bLast); 
	} 
} 
 
BOOL CScreenSaverApp::InitInstance() 
{ 
	CString sDescription; 
	VERIFY(sDescription.LoadString(IDS_DESCRIPTION)); 
	ASSERT(sDescription.GetLength()<25); 
	free((void*)m_pszAppName); 
	m_pszAppName = _tcsdup(sDescription); 
 
	HICON hIcon = LoadIcon(ID_APP); 
	VERIFY(hIcon); 
	DestroyIcon(hIcon); 
 
	CScreenSaverCommandLineInfo cmdInfo; 
	ParseCommandLine(cmdInfo); 
	return ProcessShellCommand(cmdInfo); 
}