www.gusucode.com > 一个有创意的VC++屏幕保护源码源码程序 > 一个有创意的VC++屏幕保护源码源码程序\code\ScreenSaverWnd.cpp
// ScreenSaverWnd.cpp : implementation file // Download by http://www.NewXing.com #include "StdAfx.h" #include "ScreenSaverWnd.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// IMPLEMENT_DYNAMIC(CScreenSaverWnd, CWnd) BEGIN_MESSAGE_MAP(CScreenSaverWnd, CWnd) //{{AFX_MSG_MAP(CScreenSaverWnd) ON_WM_CREATE() ON_WM_ERASEBKGND() ON_WM_PAINT() ON_WM_PALETTECHANGED() ON_WM_QUERYNEWPALETTE() //}}AFX_MSG_MAP END_MESSAGE_MAP() /* static */ CScreenSaverWnd* CScreenSaverWnd::sm_pTheScreenSaver = NULL; CScreenSaverWnd::CScreenSaverWnd() { sm_pTheScreenSaver = this; m_bAutoBlack = TRUE; m_pPalette = NULL; } CScreenSaverWnd::~CScreenSaverWnd() { sm_pTheScreenSaver = NULL; } ///////////////////////////////////////////////////////////////////////////// // // Setting up the new screen saver window. // int CScreenSaverWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; #ifdef _DEBUG // Screen savers should be TOPMOST to block out any other windows, // such as other topmost windows created previously. However, if you // are trying to debug a screen saver, it can get in the way. // We remove the topmost status from this window only if we're _DEBUG. // SetWindowPos(&CWnd::wndNoTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); #endif RestoreOptions(); OnInitialUpdate(); return 0; } void CScreenSaverWnd::OnInitialUpdate() { // Base version does nothing. // A derived class can set up basic data structures. } void CScreenSaverWnd::SaveOptions() { // Base version does nothing. // A derived class can store options in the registry or ini files. } void CScreenSaverWnd::RestoreOptions() { // Base version does nothing. // A derived class can retrieve options from the registry or ini files. } ///////////////////////////////////////////////////////////////////////////// // // The screen saver is made to paint. We support OnDraw(), just like CView // does, as a matter of convenience. // // Also for convenience, by the time an override of OnDraw() is called, the // background has been blacked (if m_bAutoBlack), and the palette in // m_pPalette has been realized properly. These are optional. // BOOL CScreenSaverWnd::OnEraseBkgnd(CDC* pDC) { if (m_bAutoBlack) { CRect rcClient; GetClientRect(&rcClient); pDC->FillSolidRect(&rcClient, RGB(0, 0, 0)); } return TRUE; } void CScreenSaverWnd::OnPaint() { CPaintDC dc(this); if (m_pPalette) { dc.SelectPalette(m_pPalette, FALSE); dc.RealizePalette(); } OnDraw(&dc); } void CScreenSaverWnd::OnDraw(CDC*pDC) { // Base version does nothing. // A derived class can use the DC to paint in any manner on the screen. } ///////////////////////////////////////////////////////////////////////////// // // There is nothing about CScreenSaverWnd which requires using a CPalette. // As a convenience, it can hold onto a CPalette and realize it at the proper // times according to WM_QUERYNEWPALETTE and WM_PALETTECHANGED notifications. // // Separately, a derived class can turn on and off the automatic black // background behavior which is handled in OnEraseBkgnd(). When it is off, // all of the user's windows will still be visible when the screen saver // starts its OnDraw(). // CPalette* CScreenSaverWnd::GetPalette() const { return m_pPalette; } CPalette* CScreenSaverWnd::SetPalette(CPalette* pPalette) { // At no time does the CScreenSaverWnd take 'ownership' of a palette // object; i.e., it will never delete or create them. It's just holding. // CPalette* pOldPalette = m_pPalette; m_pPalette = pPalette; OnQueryNewPalette(); return pOldPalette; } BOOL CScreenSaverWnd::OnQueryNewPalette() { if (!m_pPalette) return FALSE; CClientDC dc(this); dc.SelectPalette(m_pPalette, FALSE); UINT uChanged=dc.RealizePalette(); return TRUE; } void CScreenSaverWnd::OnPaletteChanged(CWnd* pFocusWnd) { if (pFocusWnd == this) return; OnQueryNewPalette(); } BOOL CScreenSaverWnd::IsAutoBlack() const { return m_bAutoBlack; } void CScreenSaverWnd::SetAutoBlack(BOOL bAutoBlack /* = TRUE */) { m_bAutoBlack = bAutoBlack; } ///////////////////////////////////////////////////////////////////////////// // // The message routing for screen saver windows is nonstandard. Calling the // regular default window proc is not appropriate. These overrides will // route the messages properly. // // For example, when the user hits a key or moves the mouse, if it's not // handled by the screen saver in some way, it should go to the default // ::DefScreenSaverProc() which will end the screen saver cleanly. // LRESULT CScreenSaverWnd::WindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) { return CWnd::WindowProc(uMsg, wParam, lParam); } LRESULT CScreenSaverWnd::DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) { return ::DefScreenSaverProc(m_hWnd, uMsg, wParam, lParam); } ///////////////////////////////////////////////////////////////////////////// // ::ScreenSaverProc(): // This API must be exported to be recognized as a screen saver. This serves // as the window message proc called by Windows to display the screen saver // window. Not all messages that go to the window actually get sent to our // proc. // LRESULT WINAPI ScreenSaverProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { // There should be one global instance of a CScreenSaverWnd derivative. ASSERT(CScreenSaverWnd::sm_pTheScreenSaver); if (!CScreenSaverWnd::sm_pTheScreenSaver) return 0L; // Since we don't have a CWinApp object, we need to initialize the MFC // internals ourselves, and terminate them when the window is destroyed. if (!CScreenSaverWnd::sm_pTheScreenSaver->m_hWnd) { AfxWinInit((HINSTANCE)::GetWindowLong(hWnd, GWL_HINSTANCE), NULL, "", SW_SHOWNORMAL); CScreenSaverWnd::sm_pTheScreenSaver->Attach(hWnd); } LRESULT lResult = ::AfxCallWndProc( CScreenSaverWnd::sm_pTheScreenSaver, CScreenSaverWnd::sm_pTheScreenSaver->m_hWnd, uMsg, wParam, lParam); if (uMsg == WM_NCDESTROY) { ASSERT(!CScreenSaverWnd::sm_pTheScreenSaver || !CScreenSaverWnd::sm_pTheScreenSaver->m_hWnd); AfxWinTerm(); } return lResult; } /////////////////////////////////////////////////////////////////////////////