Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

315 lines
10 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1998, 1999, 2000
  4. *
  5. * TITLE: IMAGESCR.CPP
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 1/13/1999
  12. *
  13. * DESCRIPTION: My Pictures Slideshow screen saver class
  14. *
  15. *******************************************************************************/
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. #include "imagescr.h"
  19. #include "isdbg.h"
  20. #include "simreg.h"
  21. #include "waitcurs.h"
  22. #include "ssutil.h"
  23. #include "findthrd.h"
  24. #include "ssmprsrc.h"
  25. #include <shlobj.h>
  26. CImageScreenSaver::CImageScreenSaver( HINSTANCE hInstance, const CSimpleString &strRegistryKey )
  27. : m_pPainter(NULL),
  28. m_hInstance(hInstance),
  29. m_MyDocsScreenSaverData( HKEY_CURRENT_USER, strRegistryKey )
  30. {
  31. EnumDisplayMonitors( NULL, NULL, MonitorEnumProc, reinterpret_cast<LPARAM>(this) );
  32. }
  33. CImageScreenSaver::~CImageScreenSaver(void)
  34. {
  35. if (m_pPainter)
  36. delete m_pPainter;
  37. m_pPainter = NULL;
  38. }
  39. BOOL CALLBACK CImageScreenSaver::MonitorEnumProc( HMONITOR hMonitor, HDC hdcMonitor, LPRECT prcMonitor, LPARAM lParam )
  40. {
  41. CImageScreenSaver *pThis = reinterpret_cast<CImageScreenSaver*>(lParam);
  42. if (pThis)
  43. {
  44. if (hMonitor)
  45. {
  46. MONITORINFOEX MonitorInfoEx;
  47. ZeroMemory( &MonitorInfoEx, sizeof(MonitorInfoEx) );
  48. MonitorInfoEx.cbSize = sizeof(MonitorInfoEx);
  49. if (GetMonitorInfo( hMonitor, reinterpret_cast<MONITORINFO*>(&MonitorInfoEx)))
  50. {
  51. pThis->m_ScreenList.Append( MonitorInfoEx.rcMonitor );
  52. WIA_TRACE((TEXT("Monitor = [%s], rcMonitor = (%d,%d,%d,%d), rcWork = (%d,%d,%d,%d), dwFlags = %08X\n"),
  53. MonitorInfoEx.szDevice,
  54. MonitorInfoEx.rcMonitor.left, MonitorInfoEx.rcMonitor.top, MonitorInfoEx.rcMonitor.right, MonitorInfoEx.rcMonitor.bottom,
  55. MonitorInfoEx.rcWork.left, MonitorInfoEx.rcWork.top, MonitorInfoEx.rcWork.right, MonitorInfoEx.rcWork.bottom,
  56. MonitorInfoEx.dwFlags ));
  57. }
  58. else
  59. {
  60. WIA_TRACE((TEXT("MonitorEnumProc, GetMonitorInfo failed (%d)\n"), GetLastError()));
  61. }
  62. }
  63. else
  64. {
  65. WIA_TRACE((TEXT("MonitorEnumProc, hMonitor == NULL\n")));
  66. }
  67. }
  68. else
  69. {
  70. WIA_TRACE((TEXT("MonitorEnumProc, pThis == NULL\n")));
  71. }
  72. return TRUE;
  73. }
  74. bool CImageScreenSaver::IsValid(void) const
  75. {
  76. return(true);
  77. }
  78. HANDLE CImageScreenSaver::Initialize( HWND hwndNotify, UINT nNotifyMessage, HANDLE hEventCancel )
  79. {
  80. HANDLE hResult = NULL;
  81. //
  82. // Get the file extensions for the file types we are able to deal with
  83. //
  84. CSimpleString strExtensions;
  85. m_GdiPlusHelper.ConstructDecoderExtensionSearchStrings(strExtensions);
  86. WIA_TRACE((TEXT("strExtensions = %s"), strExtensions.String()));
  87. //
  88. // Start the image finding thread
  89. //
  90. hResult = CFindFilesThread::Find(
  91. m_MyDocsScreenSaverData.ImageDirectory(),
  92. strExtensions,
  93. hwndNotify,
  94. nNotifyMessage,
  95. hEventCancel,
  96. m_MyDocsScreenSaverData.MaxFailedFiles(),
  97. m_MyDocsScreenSaverData.MaxSuccessfulFiles(),
  98. m_MyDocsScreenSaverData.MaxDirectories()
  99. );
  100. //
  101. // Return the thread handle
  102. //
  103. return hResult;
  104. }
  105. bool CImageScreenSaver::TimerTick( CSimpleDC &ClientDC )
  106. {
  107. if (m_pPainter && ClientDC.IsValid())
  108. {
  109. return m_pPainter->TimerTick( ClientDC );
  110. }
  111. return false;
  112. }
  113. void CImageScreenSaver::Paint( CSimpleDC &PaintDC )
  114. {
  115. if (m_pPainter && PaintDC.IsValid())
  116. {
  117. m_pPainter->Paint( PaintDC );
  118. }
  119. }
  120. int CImageScreenSaver::ChangeTimerInterval(void) const
  121. {
  122. return(m_MyDocsScreenSaverData.ChangeInterval());
  123. }
  124. int CImageScreenSaver::PaintTimerInterval(void) const
  125. {
  126. return(m_MyDocsScreenSaverData.PaintInterval());
  127. }
  128. bool CImageScreenSaver::AllowKeyboardControl(void)
  129. {
  130. return(m_MyDocsScreenSaverData.AllowKeyboardControl());
  131. }
  132. bool CImageScreenSaver::ReplaceImage( bool bForward, bool bNoTransition )
  133. {
  134. CSimpleString strCurrentFile;
  135. if (m_pPainter)
  136. {
  137. delete m_pPainter;
  138. m_pPainter = NULL;
  139. }
  140. if (!m_VisibleAreaList.Size())
  141. {
  142. return false;
  143. }
  144. if (m_FindImageFiles.Count())
  145. {
  146. //
  147. // exit the loop when we get a valid image or we've exhausted the list
  148. //
  149. int nNumTries = 0;
  150. while (!m_pPainter && nNumTries < m_FindImageFiles.Count())
  151. {
  152. CSimpleString strNextFile;
  153. bool bNextFile = bForward ? m_FindImageFiles.NextFile(strNextFile) : m_FindImageFiles.PreviousFile(strNextFile);
  154. if (bNextFile)
  155. {
  156. CSimpleDC ClientDC;
  157. if (ClientDC.GetDC(NULL))
  158. {
  159. CBitmapImage *pBitmapImage = new CBitmapImage;
  160. if (pBitmapImage)
  161. {
  162. int nAreaToUse = CRandomNumberGen().Generate(0,m_VisibleAreaList.Size());
  163. RECT rcAreaToUse = m_VisibleAreaList[nAreaToUse];
  164. WIA_TRACE((TEXT("Chosen Image Area [%d] = (%d,%d), (%d,%d)"), nAreaToUse, rcAreaToUse.left, rcAreaToUse.top, rcAreaToUse.right, rcAreaToUse.bottom ));
  165. if (pBitmapImage->Load( ClientDC, strNextFile, rcAreaToUse, m_MyDocsScreenSaverData.MaxScreenPercent(), m_MyDocsScreenSaverData.AllowStretching(), m_MyDocsScreenSaverData.DisplayFilename() ))
  166. {
  167. if (m_MyDocsScreenSaverData.DisableTransitions() || bNoTransition)
  168. {
  169. m_pPainter = new CSimpleTransitionPainter( pBitmapImage, ClientDC, rcAreaToUse, m_rcClient );
  170. }
  171. else
  172. {
  173. m_pPainter = GetRandomImagePainter( pBitmapImage, ClientDC, rcAreaToUse, m_rcClient );
  174. }
  175. //
  176. // If we couldn't create a painter, delete the bitmap
  177. //
  178. if (!m_pPainter)
  179. {
  180. WIA_TRACE((TEXT("%hs (%d): Unable to create a painter\n"), __FILE__, __LINE__ ));
  181. delete pBitmapImage;
  182. }
  183. }
  184. else
  185. {
  186. WIA_TRACE((TEXT("%hs (%d): pBitmapImage->Load() failed\n"), __FILE__, __LINE__ ));
  187. delete pBitmapImage;
  188. }
  189. }
  190. else
  191. {
  192. WIA_TRACE((TEXT("%hs (%d): CImageScreenSaver::CreateImage() failed\n"), __FILE__, __LINE__ ));
  193. }
  194. }
  195. else
  196. {
  197. WIA_TRACE((TEXT("%hs (%d): ClientDC.GetDC() failed\n"), __FILE__, __LINE__ ));
  198. }
  199. }
  200. else
  201. {
  202. WIA_TRACE((TEXT("%hs (%d): m_FindImageFiles.NextFile() failed\n"), __FILE__, __LINE__ ));
  203. }
  204. nNumTries++;
  205. }
  206. }
  207. else
  208. {
  209. //
  210. // Create a new image
  211. //
  212. CBitmapImage *pBitmapImage = new CBitmapImage;
  213. if (pBitmapImage)
  214. {
  215. //
  216. // Get a desktop DC
  217. //
  218. CSimpleDC ClientDC;
  219. if (ClientDC.GetDC(NULL))
  220. {
  221. //
  222. // Figure out which screen to display the message on
  223. //
  224. RECT rcAreaToUse = m_VisibleAreaList[CRandomNumberGen().Generate(0,m_VisibleAreaList.Size())];
  225. //
  226. // Create the bitmap with an appropriate message
  227. //
  228. if (pBitmapImage->CreateFromText( CSimpleString().Format( IDS_NO_FILES_FOUND, g_hInstance, m_MyDocsScreenSaverData.ImageDirectory().String() ), rcAreaToUse, m_MyDocsScreenSaverData.MaxScreenPercent() ))
  229. {
  230. //
  231. // Create a simple painter to display it
  232. //
  233. m_pPainter = new CSimpleTransitionPainter( pBitmapImage, ClientDC, rcAreaToUse, m_rcClient );
  234. if (!m_pPainter)
  235. {
  236. //
  237. // If we couldn't get a painter, destroy the bitmap
  238. //
  239. delete pBitmapImage;
  240. }
  241. }
  242. else
  243. {
  244. //
  245. // If we couldn't create a bitmap, destroy it
  246. //
  247. delete pBitmapImage;
  248. }
  249. }
  250. }
  251. }
  252. return(m_pPainter != NULL);
  253. }
  254. CImagePainter *CImageScreenSaver::GetRandomImagePainter( CBitmapImage *pBitmapImage, CSimpleDC &dc, const RECT &rcAreaToUse, const RECT &rcClient )
  255. {
  256. CImagePainter *pPainter = NULL;
  257. int nPainter = CRandomNumberGen().Generate(0,5);
  258. if (!pPainter)
  259. {
  260. switch (nPainter)
  261. {
  262. case 0:
  263. pPainter = new CSimpleTransitionPainter( pBitmapImage, dc, rcAreaToUse, rcClient );
  264. break;
  265. case 1:
  266. pPainter = new CSlidingTransitionPainter( pBitmapImage, dc, rcAreaToUse, rcClient );
  267. break;
  268. case 2:
  269. pPainter = new CRandomBlockPainter( pBitmapImage, dc, rcAreaToUse, rcClient );
  270. break;
  271. case 3:
  272. pPainter = new CAlphaFadePainter( pBitmapImage, dc, rcAreaToUse, rcClient );
  273. break;
  274. case 4:
  275. pPainter = new COpenCurtainPainter( pBitmapImage, dc, rcAreaToUse, rcClient );
  276. break;
  277. }
  278. }
  279. if (!pPainter)
  280. {
  281. WIA_TRACE((TEXT("%hs (%d): pPainter is NULL\n"), __FILE__, __LINE__ ));
  282. return(NULL);
  283. }
  284. if (!pPainter->IsValid())
  285. {
  286. WIA_TRACE((TEXT("%hs (%d): pPainter->IsValid() == FALSE\n"), __FILE__, __LINE__ ));
  287. delete pPainter;
  288. return(NULL);
  289. }
  290. return(pPainter);
  291. }