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

屏幕保护

开发平台:

Visual C++

  1. // MfcSaver.cpp : Defines the class behaviors for the application.
  2. //
  3. #include "StdAfx.h"
  4. #include "MfcSaver.h"
  5. #include "MfcSaverDlg.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. //
  13. // The screen saver controls a number of icon graphics that bounce around
  14. // on a black background.  Set some basic defaults and initialize the random
  15. // number generator with srand().  Later, our RestoreOptions() will be called
  16. // to recall earlier option settings.
  17. //
  18. BEGIN_MESSAGE_MAP(CMfcSaver, CScreenSaverWnd)
  19. //{{AFX_MSG_MAP(CMfcSaver)
  20. ON_WM_TIMER()
  21. //}}AFX_MSG_MAP
  22. END_MESSAGE_MAP()
  23. // As required of CScreenSaverWnd-based screen savers, these are the two
  24. // global instances of screen saver objects.  One is the saver itself,
  25. // and one is the dialog for configuring the options of the screen saver.
  26. //
  27. // Unlike most MFC applications, there is no instance of any CWinApp object.
  28. //
  29. CMfcSaver theSaver;
  30. CMfcSaverDlg theSaverDialog;
  31. CMfcSaver::CMfcSaver()
  32. {
  33. m_nIcons = 6;
  34. m_nSpeed = 100;
  35. srand(time(NULL));
  36. }
  37. CMfcSaver::~CMfcSaver()
  38. {
  39. }
  40. /////////////////////////////////////////////////////////////////////////////
  41. //
  42. // The CMfcSaverDlg will need to be able to access our customizable
  43. // attributes.  We call OnInitialUpdate() again to reorganize internally if
  44. // any of these change.
  45. //
  46. // The options need to be saved and restored between runs.
  47. // Probably the biggest thing you might miss from having no CWinApp object
  48. // will be CWinApp::WriteProfileInt() which saves things to the registry
  49. // without complicated registry code.
  50. //
  51. // For simplicity, we just create an mfcsaver.ini file with the options.
  52. //
  53. int CMfcSaver::GetIconCount() const
  54. {
  55. return m_nIcons;
  56. }
  57. void CMfcSaver::SetIconCount(int nIcons)
  58. {
  59. m_nIcons = nIcons;
  60. OnInitialUpdate();
  61. }
  62. int CMfcSaver::GetIconSpeed() const
  63. {
  64. return m_nSpeed;
  65. }
  66. void CMfcSaver::SetIconSpeed(int nSpeed)
  67. {
  68. m_nSpeed = nSpeed;
  69. OnInitialUpdate();
  70. }
  71. void CMfcSaver::SaveOptions()
  72. {
  73. CString s;
  74. s.Format("%d", GetIconCount());
  75. ::WritePrivateProfileString(
  76. "MfcSaver", "Count", s, "mfcsaver.ini");
  77. s.Format("%d", GetIconSpeed());
  78. ::WritePrivateProfileString(
  79. "MfcSaver", "Speed", s, "mfcsaver.ini");
  80. }
  81. void CMfcSaver::RestoreOptions()
  82. {
  83. SetIconCount(::GetPrivateProfileInt(
  84. "MfcSaver", "Count", 8, "mfcsaver.ini"));
  85. SetIconSpeed(::GetPrivateProfileInt(
  86. "MfcSaver", "Speed", 8, "mfcsaver.ini"));
  87. }
  88. /////////////////////////////////////////////////////////////////////////////
  89. //
  90. // While this is just demonstrating how to override the virtual functions of
  91. // CScreenSaverWnd, it also shows something about using CImageList to
  92. // draw from a library of simple images.
  93. //
  94. // When our timer goes off, we just invalidate the window.  The OnDraw()
  95. // override will be called appropriately when the system has some free cycles
  96. // to spend on drawing.  Remember:  a screen saver should share the CPU, so
  97. // the computer can work on other tasks like downloading or numbercrunching.
  98. //
  99. void CMfcSaver::OnInitialUpdate()
  100. {
  101. if (!m_hWnd)
  102. return;
  103. // Flush all the icons we have, if any.
  104. m_aIcon.RemoveAll();
  105. if (m_ilIcons.m_hImageList)
  106. m_ilIcons.DeleteImageList();
  107. // Set up for the desired number of icons.
  108. m_aIcon.SetSize(m_nIcons);
  109. m_ilIcons.Create(IDB_ICONS, 32, 0, RGB(128, 0, 128));
  110. int i;
  111. for (i = 0; i < m_nIcons; i++)
  112. SetupMfcSaverIcon(i);
  113. m_nSpeed = max(1, m_nSpeed);
  114. SetTimer(1, 2000 / m_nSpeed, NULL);
  115. }
  116. void CMfcSaver::OnDraw(CDC* pDC)
  117. {
  118. int i;
  119. for (i = 0; i < m_nIcons; i++)
  120. {
  121. EraseMfcSaverIcon(i, pDC);
  122. UpdateMfcSaverIconPosition(i);
  123. if (IsMfcSaverIconOffscreen(i))
  124. SetupMfcSaverIcon(i);
  125. DrawMfcSaverIcon(i, pDC);
  126. }
  127. }
  128. void CMfcSaver::EraseMfcSaverIcon(int i, CDC* pDC)
  129. {
  130. CRect rcIcon = CRect(m_aIcon[i].ptP, CSize(32, 32));
  131. pDC->FillSolidRect(&rcIcon, RGB(0, 0, 0));
  132. }
  133. void CMfcSaver::DrawMfcSaverIcon(int i, CDC* pDC)
  134. {
  135. m_ilIcons.Draw(pDC, m_aIcon[i].iImage, m_aIcon[i].ptP, ILD_NORMAL);
  136. }
  137. void CMfcSaver::OnTimer(UINT nIDEvent) 
  138. {
  139. CScreenSaverWnd::OnTimer(nIDEvent);
  140. Invalidate(FALSE);
  141. }
  142. /////////////////////////////////////////////////////////////////////////////
  143. //
  144. // Compute the movement of these little square icons.
  145. // They move until they fall offscreen, then are reinitialized randomly.
  146. // If they would collide on any move, they don't move but they change
  147. // direction instead.  If they seem hopelessly stuck, they are recycled.
  148. //
  149. // With a bit more work, you could make these icons pass over each other
  150. // smoothly, or you could double-buffer them to draw with less flicker.
  151. //
  152. BOOL CMfcSaver::IsMfcSaverIconColliding(int i, CPoint ptP)
  153. {
  154. CRect rcI = CRect(ptP, CSize(32, 32));
  155. int j;
  156. for (j = 0; j < m_nIcons; j++)
  157. {
  158. if (j == i)
  159. continue;
  160. CRect rcJ = CRect(m_aIcon[j].ptP, CSize(32, 32));
  161. if (rcJ.IntersectRect(&rcJ, &rcI))
  162. return TRUE;
  163. }
  164. return FALSE;
  165. }
  166. BOOL CMfcSaver::IsMfcSaverIconOffscreen(int i)
  167. {
  168. CRect rcI = CRect(m_aIcon[i].ptP, CSize(32, 32));
  169. CRect rcC;
  170. GetClientRect(&rcC);
  171. return !rcC.IntersectRect(&rcC, &rcI);
  172. }
  173. void CMfcSaver::UpdateMfcSaverIconPosition(int i)
  174. {
  175. CPoint ptP;
  176. ptP = m_aIcon[i].ptP + m_aIcon[i].szV;
  177. if (IsMfcSaverIconColliding(i, ptP))
  178. {
  179. m_aIcon[i].nStuck++;
  180. BounceMfcSaverIcon(i);
  181. if (m_aIcon[i].nStuck > 5)
  182. SetupMfcSaverIcon(i);
  183. return;
  184. }
  185. m_aIcon[i].nStuck = 0;
  186. m_aIcon[i].ptP = ptP;
  187. }
  188. void CMfcSaver::BounceMfcSaverIcon(int i)
  189. {
  190. do
  191. {
  192. m_aIcon[i].szV.cx = (rand() % 5) - 2;
  193. m_aIcon[i].szV.cy = (rand() % 5) - 2;
  194. } while (m_aIcon[i].szV.cx == 0 && m_aIcon[i].szV.cy == 0);
  195. }
  196. void CMfcSaver::SetupMfcSaverIcon(int i)
  197. {
  198. int count = max(1, m_ilIcons.GetImageCount());
  199. int breakout = 10;
  200. do
  201. {
  202. m_aIcon[i].iImage = (rand() % count);
  203. m_aIcon[i].ptP.x =
  204. (rand() % ::GetSystemMetrics(SM_CXSCREEN));
  205. m_aIcon[i].ptP.y =
  206. (rand() % ::GetSystemMetrics(SM_CXSCREEN));
  207. BounceMfcSaverIcon(i);
  208. m_aIcon[i].nStuck = 0;
  209. } while (breakout > 0 &&
  210.          IsMfcSaverIconColliding(i, m_aIcon[i].ptP));
  211. }