ScreenSaverWnd.cpp
上传用户:szxyd1688
上传日期:2007-06-08
资源大小:1440k
文件大小:7k
源码类别:

屏幕保护

开发平台:

Visual C++

  1. // ScreenSaverWnd.cpp : implementation file
  2. //
  3. #include "StdAfx.h"
  4. #include "ScreenSaverWnd.h"
  5. #ifdef _DEBUG
  6. #define new DEBUG_NEW
  7. #undef THIS_FILE
  8. static char THIS_FILE[] = __FILE__;
  9. #endif
  10. /////////////////////////////////////////////////////////////////////////////
  11. IMPLEMENT_DYNAMIC(CScreenSaverWnd, CWnd)
  12. BEGIN_MESSAGE_MAP(CScreenSaverWnd, CWnd)
  13. //{{AFX_MSG_MAP(CScreenSaverWnd)
  14. ON_WM_CREATE()
  15. ON_WM_ERASEBKGND()
  16. ON_WM_PAINT()
  17. ON_WM_PALETTECHANGED()
  18. ON_WM_QUERYNEWPALETTE()
  19. //}}AFX_MSG_MAP
  20. END_MESSAGE_MAP()
  21. /* static */ CScreenSaverWnd* CScreenSaverWnd::sm_pTheScreenSaver = NULL;
  22. CScreenSaverWnd::CScreenSaverWnd()
  23. {
  24. sm_pTheScreenSaver = this;
  25. m_bAutoBlack = TRUE;
  26. m_pPalette = NULL;
  27. }
  28. CScreenSaverWnd::~CScreenSaverWnd()
  29. {
  30. sm_pTheScreenSaver = NULL;
  31. }
  32. /////////////////////////////////////////////////////////////////////////////
  33. //
  34. // Setting up the new screen saver window.
  35. //
  36. int CScreenSaverWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  37. {
  38. if (CWnd::OnCreate(lpCreateStruct) == -1)
  39. return -1;
  40. #ifdef _DEBUG
  41. // Screen savers should be TOPMOST to block out any other windows,
  42. // such as other topmost windows created previously.  However, if you
  43. // are trying to debug a screen saver, it can get in the way.
  44. // We remove the topmost status from this window only if we're _DEBUG.
  45. // 
  46. SetWindowPos(&CWnd::wndNoTopMost,
  47. 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
  48. #endif
  49. RestoreOptions();
  50. OnInitialUpdate();
  51. return 0;
  52. }
  53. void CScreenSaverWnd::OnInitialUpdate()
  54. {
  55. // Base version does nothing.
  56. // A derived class can set up basic data structures.
  57. }
  58. void CScreenSaverWnd::SaveOptions()
  59. {
  60. // Base version does nothing.
  61. // A derived class can store options in the registry or ini files.
  62. }
  63. void CScreenSaverWnd::RestoreOptions()
  64. {
  65. // Base version does nothing.
  66. // A derived class can retrieve options from the registry or ini files.
  67. }
  68. /////////////////////////////////////////////////////////////////////////////
  69. //
  70. // The screen saver is made to paint.  We support OnDraw(), just like CView
  71. // does, as a matter of convenience.
  72. //
  73. // Also for convenience, by the time an override of OnDraw() is called, the
  74. // background has been blacked (if m_bAutoBlack), and the palette in
  75. // m_pPalette has been realized properly.  These are optional.
  76. //
  77. BOOL CScreenSaverWnd::OnEraseBkgnd(CDC* pDC) 
  78. {
  79. if (m_bAutoBlack)
  80. {
  81. CRect rcClient;
  82. GetClientRect(&rcClient);
  83. pDC->FillSolidRect(&rcClient, RGB(0, 0, 0));
  84. }
  85. return TRUE;
  86. }
  87. void CScreenSaverWnd::OnPaint() 
  88. {
  89. CPaintDC dc(this);
  90. if (m_pPalette)
  91. {
  92. dc.SelectPalette(m_pPalette, FALSE);
  93. dc.RealizePalette();
  94. }
  95. OnDraw(&dc);
  96. }
  97. void CScreenSaverWnd::OnDraw(CDC*pDC)
  98. {
  99. // Base version does nothing.
  100. // A derived class can use the DC to paint in any manner on the screen.
  101. }
  102. /////////////////////////////////////////////////////////////////////////////
  103. //
  104. // There is nothing about CScreenSaverWnd which requires using a CPalette.
  105. // As a convenience, it can hold onto a CPalette and realize it at the proper
  106. // times according to WM_QUERYNEWPALETTE and WM_PALETTECHANGED notifications.
  107. //
  108. // Separately, a derived class can turn on and off the automatic black
  109. // background behavior which is handled in OnEraseBkgnd(). When it is off,
  110. // all of the user's windows will still be visible when the screen saver
  111. // starts its OnDraw().
  112. //
  113. CPalette* CScreenSaverWnd::GetPalette() const
  114. {
  115. return m_pPalette;
  116. }
  117. CPalette* CScreenSaverWnd::SetPalette(CPalette* pPalette)
  118. {
  119. // At no time does the CScreenSaverWnd take 'ownership' of a palette
  120. // object; i.e., it will never delete or create them.  It's just holding.
  121. //
  122. CPalette* pOldPalette = m_pPalette;
  123. m_pPalette = pPalette;
  124. OnQueryNewPalette();
  125. return pOldPalette;
  126. }
  127. BOOL CScreenSaverWnd::OnQueryNewPalette() 
  128. {
  129. if (!m_pPalette)
  130. return FALSE;
  131. CClientDC dc(this);
  132. dc.SelectPalette(m_pPalette, FALSE);
  133. UINT uChanged=dc.RealizePalette();
  134. return TRUE;
  135. }
  136. void CScreenSaverWnd::OnPaletteChanged(CWnd* pFocusWnd) 
  137. {
  138. if (pFocusWnd == this)
  139. return;
  140. OnQueryNewPalette();
  141. }
  142. BOOL CScreenSaverWnd::IsAutoBlack() const
  143. {
  144. return m_bAutoBlack;
  145. }
  146. void CScreenSaverWnd::SetAutoBlack(BOOL bAutoBlack /* = TRUE */)
  147. {
  148. m_bAutoBlack = bAutoBlack;
  149. }
  150. /////////////////////////////////////////////////////////////////////////////
  151. //
  152. // The message routing for screen saver windows is nonstandard.  Calling the
  153. // regular default window proc is not appropriate.  These overrides will
  154. // route the messages properly.
  155. //
  156. // For example, when the user hits a key or moves the mouse, if it's not
  157. // handled by the screen saver in some way, it should go to the default
  158. // ::DefScreenSaverProc() which will end the screen saver cleanly.
  159. //
  160. LRESULT CScreenSaverWnd::WindowProc(UINT uMsg,
  161.                                     WPARAM wParam,
  162.                                     LPARAM lParam)
  163. {
  164. return CWnd::WindowProc(uMsg, wParam, lParam);
  165. }
  166. LRESULT CScreenSaverWnd::DefWindowProc(UINT uMsg,
  167.                                        WPARAM wParam,
  168.                                        LPARAM lParam)
  169. {
  170. return ::DefScreenSaverProc(m_hWnd, uMsg, wParam, lParam);
  171. }
  172. /////////////////////////////////////////////////////////////////////////////
  173. // ::ScreenSaverProc():
  174. // This API must be exported to be recognized as a screen saver.  This serves
  175. // as the window message proc called by Windows to display the screen saver
  176. // window.  Not all messages that go to the window actually get sent to our
  177. // proc.
  178. //
  179. LRESULT WINAPI ScreenSaverProc(HWND hWnd, UINT uMsg,
  180.                                WPARAM wParam, LPARAM lParam)
  181. {
  182. // There should be one global instance of a CScreenSaverWnd derivative.
  183. ASSERT(CScreenSaverWnd::sm_pTheScreenSaver);
  184. if (!CScreenSaverWnd::sm_pTheScreenSaver)
  185. return 0L;
  186. // Since we don't have a CWinApp object, we need to initialize the MFC
  187. // internals ourselves, and terminate them when the window is destroyed.
  188. if (!CScreenSaverWnd::sm_pTheScreenSaver->m_hWnd)
  189. {
  190. AfxWinInit((HINSTANCE)::GetWindowLong(hWnd, GWL_HINSTANCE),
  191.            NULL, "", SW_SHOWNORMAL);
  192. CScreenSaverWnd::sm_pTheScreenSaver->Attach(hWnd);
  193. }
  194. LRESULT lResult =
  195. ::AfxCallWndProc(
  196. CScreenSaverWnd::sm_pTheScreenSaver,
  197. CScreenSaverWnd::sm_pTheScreenSaver->m_hWnd,
  198. uMsg, wParam, lParam);
  199. if (uMsg == WM_NCDESTROY)
  200. {
  201. ASSERT(!CScreenSaverWnd::sm_pTheScreenSaver ||
  202.        !CScreenSaverWnd::sm_pTheScreenSaver->m_hWnd);
  203. AfxWinTerm();
  204. }
  205. return lResult;
  206. }
  207. /////////////////////////////////////////////////////////////////////////////