XTPTaskPanelAnimation.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:8k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPTaskPanelAnimation.cpp : implementation file
  2. //
  3. // This file is a part of the XTREME TASKPANEL MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "Common/XTPImageManager.h"
  22. #include "Common/XTPDrawHelpers.h"
  23. #include "XTPTaskPanelAnimation.h"
  24. #include "XTPTaskPanel.h"
  25. #ifdef _DEBUG
  26. #define new DEBUG_NEW
  27. #undef THIS_FILE
  28. static char THIS_FILE[] = __FILE__;
  29. #endif
  30. CXTPTaskPanelAnimation::CAnimateInfo::CAnimateInfo()
  31. {
  32. hbmSrc = 0;
  33. pSrcBits = 0;
  34. hbmSrcBack = 0;
  35. pSrcBackBits = 0;
  36. SetRectEmpty(&rcPaint);
  37. m_nAnimation = 0;
  38. }
  39. CXTPTaskPanelAnimation::CAnimateInfo::~CAnimateInfo()
  40. {
  41. DeleteObject(hbmSrc);
  42. DeleteObject(hbmSrcBack);
  43. }
  44. CXTPTaskPanelAnimation::CXTPTaskPanelAnimation(CXTPTaskPanel* pTaskPanel)
  45. {
  46. m_bInvalidate = FALSE;
  47. m_pParent = pTaskPanel;
  48. m_nTimer = 0;
  49. m_bAnimation = FALSE;
  50. m_bDoubleBuffer = FALSE;
  51. }
  52. CXTPTaskPanelAnimation::~CXTPTaskPanelAnimation()
  53. {
  54. RemoveAnimations();
  55. }
  56. void CXTPTaskPanelAnimation::RemoveAnimations()
  57. {
  58. for (int i = 0; i < m_arrAnimation.GetSize(); i++)
  59. {
  60. delete m_arrAnimation[i];
  61. }
  62. m_arrAnimation.RemoveAll();
  63. if (m_nTimer && m_pParent->GetSafeHwnd())
  64. {
  65. m_pParent->KillTimer(XTP_TID_ANIMATION);
  66. }
  67. m_nTimer = 0;
  68. }
  69. void CXTPTaskPanelAnimation::AlphaBlendU(PBYTE pDest, PBYTE pSrcBack, int cx, int cy, PBYTE pSrc, BYTE byAlpha)
  70. {
  71. const BYTE byDiff = (BYTE)(255 - byAlpha);
  72. for (int i = 0; i < cx * cy * 4; i++)
  73. {
  74. pDest[0] = (BYTE)((pSrcBack[0] * byDiff + pSrc[0] * byAlpha) >> 8);
  75. pDest += 1;
  76. pSrcBack += 1;
  77. pSrc += 1;
  78. }
  79. }
  80. #define MAXANIMATION 6
  81. BOOL CXTPTaskPanelAnimation::IsAnimationEnabled() const
  82. {
  83. return m_bAnimation;
  84. }
  85. void CXTPTaskPanelAnimation::AnimateRect(CClientDC& dc, CAnimateInfo* pai)
  86. {
  87. CRect rcPaint = pai->rcPaint;
  88. int cx = rcPaint.Width();
  89. int cy = rcPaint.Height();
  90. CDC memDC;
  91. memDC.CreateCompatibleDC(&dc);
  92. if (pai->m_nAnimation == MAXANIMATION)
  93. {
  94. HBITMAP hOldBitmap = (HBITMAP)::SelectObject(memDC, m_bmpCache);
  95. dc.BitBlt(rcPaint.left, rcPaint.top, cx, cy,
  96. &memDC, rcPaint.left, rcPaint.top, SRCCOPY);
  97. ::SelectObject(memDC, hOldBitmap);
  98. }
  99. else
  100. {
  101. BYTE* pDestBits = NULL;
  102. HBITMAP hbmDest = CXTPImageManager::Create32BPPDIBSection(dc, cx, cy, &pDestBits);
  103. AlphaBlendU(pDestBits, pai->pSrcBackBits, cx, cy, pai->pSrcBits, (BYTE)(255 * pai->m_nAnimation / MAXANIMATION));
  104. HBITMAP hOldBitmap = (HBITMAP)::SelectObject(memDC, hbmDest);
  105. dc.BitBlt(rcPaint.left, rcPaint.top, cx, cy, &memDC, 0, 0, SRCCOPY);
  106. ::SelectObject(memDC, hOldBitmap);
  107. DeleteObject(hbmDest);
  108. }
  109. pai->m_nAnimation++;
  110. }
  111. void CXTPTaskPanelAnimation::OnAnimate()
  112. {
  113. CClientDC dc(m_pParent);
  114. for (int i = 0; i < m_arrAnimation.GetSize(); i++)
  115. {
  116. CAnimateInfo* pai = m_arrAnimation[i];
  117. for (int j = 0; j < pai->arrExclude.GetSize(); j++)
  118. dc.ExcludeClipRect(&pai->arrExclude[j]);
  119. AnimateRect(dc, pai);
  120. dc.SelectClipRgn(NULL);
  121. if (pai->m_nAnimation > MAXANIMATION)
  122. {
  123. m_arrAnimation.RemoveAt(i);
  124. delete pai;
  125. i--;
  126. }
  127. }
  128. if (m_arrAnimation.GetSize() == 0 && m_nTimer)
  129. {
  130. m_pParent->KillTimer(XTP_TID_ANIMATION);
  131. m_nTimer = 0;
  132. }
  133. }
  134. void CXTPTaskPanelAnimation::RemoveIntersections(LPCRECT rcPaint, BOOL bAddExclude)
  135. {
  136. for (int i = 0; i < m_arrAnimation.GetSize(); i++)
  137. {
  138. CAnimateInfo* paiOld = m_arrAnimation[i];
  139. CRect rcIntersect;
  140. if (rcIntersect.IntersectRect(&paiOld->rcPaint, rcPaint))
  141. {
  142. if (rcIntersect == paiOld->rcPaint)
  143. {
  144. m_arrAnimation.RemoveAt(i);
  145. delete paiOld;
  146. i--;
  147. }
  148. else if (bAddExclude)
  149. {
  150. paiOld->arrExclude.Add((RECT&)*rcPaint);
  151. }
  152. }
  153. }
  154. }
  155. void CXTPTaskPanelAnimation::AddAnimation(CClientDC& dc, CAnimateInfo* pai)
  156. {
  157. RemoveIntersections(&pai->rcPaint, FALSE);
  158. m_arrAnimation.Add(pai);
  159. if (m_nTimer == 0)
  160. {
  161. m_nTimer = m_pParent->SetTimer(XTP_TID_ANIMATION, 50, NULL);
  162. }
  163. AnimateRect(dc, pai);
  164. }
  165. void CXTPTaskPanelAnimation::OnDestroy()
  166. {
  167. m_bmpCache.DeleteObject();
  168. RemoveAnimations();
  169. }
  170. void CXTPTaskPanelAnimation::RedrawRect(LPCRECT lpRect, BOOL bAnimate)
  171. {
  172. if (lpRect == NULL)
  173. {
  174. m_bmpCache.DeleteObject();
  175. }
  176. if (lpRect == NULL || m_bmpCache.GetSafeHandle() == 0 || !IsAnimationEnabled())
  177. {
  178. m_bInvalidate = TRUE;
  179. m_pParent->InvalidateRect(lpRect, FALSE);
  180. return;
  181. }
  182. CClientDC dc(m_pParent);
  183. CXTPClientRect rc(m_pParent);
  184. CRect rcPaint(lpRect);
  185. CDC dcDraw;
  186. dcDraw.CreateCompatibleDC(&dc);
  187. CBitmap bmpDraw;
  188. bmpDraw.CreateCompatibleBitmap(&dc, rc.Width(), rc.Height());
  189. HBITMAP hOldBitmapDraw = (HBITMAP)::SelectObject(dcDraw, bmpDraw);
  190. CRgn rgn;
  191. rgn.CreateRectRgnIndirect(rcPaint);
  192. dcDraw.SelectClipRgn(&rgn);
  193. m_pParent->OnDraw(&dcDraw, rcPaint);
  194. dcDraw.SelectClipRgn(0);
  195. CDC dcCache;
  196. dcCache.CreateCompatibleDC(&dc);
  197. HBITMAP hOldBitmapCache = (HBITMAP)::SelectObject(dcCache, m_bmpCache);
  198. if (!bAnimate)
  199. {
  200. RemoveIntersections(&rcPaint, TRUE);
  201. dcCache.BitBlt(rcPaint.left, rcPaint.top, rcPaint.Width(), rcPaint.Height(),
  202. &dcDraw, rcPaint.left, rcPaint.top, SRCCOPY);
  203. dc.BitBlt(rcPaint.left, rcPaint.top, rcPaint.Width(), rcPaint.Height(),
  204. &dcDraw, rcPaint.left, rcPaint.top, SRCCOPY);
  205. }
  206. else
  207. {
  208. CAnimateInfo* pai = new CAnimateInfo;
  209. pai->rcPaint = rcPaint;
  210. pai->m_nAnimation = 1;
  211. pai->hbmSrc = CXTPImageManager::Create32BPPDIBSection(dc, rcPaint.Width(), rcPaint.Height(), &pai->pSrcBits);
  212. pai->hbmSrcBack = CXTPImageManager::Create32BPPDIBSection(dc, rcPaint.Width(), rcPaint.Height(), &pai->pSrcBackBits);
  213. CDC dcSrc;
  214. dcSrc.CreateCompatibleDC(&dc);
  215. CDC dcSrcBack;
  216. dcSrcBack.CreateCompatibleDC(&dc);
  217. HBITMAP hOldBitmapSrc = (HBITMAP)::SelectObject(dcSrc, pai->hbmSrc);
  218. HBITMAP hOldBitmapSrcBack = (HBITMAP)::SelectObject(dcSrcBack,  pai->hbmSrcBack);
  219. dcSrc.BitBlt(0, 0, rcPaint.Width(), rcPaint.Height(), &dcDraw, rcPaint.left, rcPaint.top, SRCCOPY);
  220. dcSrcBack.BitBlt(0, 0, rcPaint.Width(), rcPaint.Height(), &dcCache, rcPaint.left, rcPaint.top, SRCCOPY);
  221. dcCache.BitBlt(rcPaint.left, rcPaint.top, rcPaint.Width(), rcPaint.Height(), &dcSrc, 0, 0, SRCCOPY);
  222. ::SelectObject(dcSrcBack, hOldBitmapSrcBack);
  223. ::SelectObject(dcSrc, hOldBitmapSrc);
  224. if (memcmp(pai->pSrcBits, pai->pSrcBackBits, rcPaint.Width() * rcPaint.Height() * 4) == 0)
  225. {
  226. delete pai;
  227. }
  228. else
  229. {
  230. AddAnimation(dc, pai);
  231. }
  232. }
  233. ::SelectObject(dcCache, hOldBitmapCache);
  234. ::SelectObject(dcDraw, hOldBitmapDraw);
  235. }
  236. void CXTPTaskPanelAnimation::OnPaint(CPaintDC& paintDC)
  237. {
  238. CXTPClientRect rc(m_pParent);
  239. CRect rcPaint(paintDC.m_ps.rcPaint);
  240. if (m_bmpCache.GetSafeHandle())
  241. {
  242. BITMAP bmpInfo;
  243. m_bmpCache.GetBitmap(&bmpInfo);
  244. if (bmpInfo.bmHeight != rc.Height() || bmpInfo.bmWidth != rc.Width())
  245. m_bmpCache.DeleteObject();
  246. }
  247. if (!m_bDoubleBuffer && !IsAnimationEnabled())
  248. {
  249. m_bmpCache.DeleteObject();
  250. CXTPBufferDC memDC(paintDC);
  251. m_pParent->OnDraw(&memDC, rcPaint);
  252. RemoveAnimations();
  253. }
  254. else if (m_bInvalidate || m_bmpCache.GetSafeHandle() == 0)
  255. {
  256. CDC memDC;
  257. memDC.CreateCompatibleDC(&paintDC);
  258. if (!m_bmpCache.GetSafeHandle())
  259. {
  260. m_bmpCache.CreateCompatibleBitmap(&paintDC, rc.Width(), rc.Height());
  261. rcPaint = rc;
  262. }
  263. CBitmap* pOldBitmap = memDC.SelectObject(&m_bmpCache);
  264. CRgn rgn;
  265. rgn.CreateRectRgnIndirect(rcPaint);
  266. memDC.SelectClipRgn(&rgn);
  267. m_pParent->OnDraw(&memDC, rcPaint);
  268. memDC.SelectClipRgn(0);
  269. paintDC.BitBlt(rcPaint.left, rcPaint.top, rcPaint.Width(), rcPaint.Height(),
  270. &memDC, rcPaint.left, rcPaint.top, SRCCOPY);
  271. memDC.SelectObject(pOldBitmap);
  272. RemoveAnimations();
  273. }
  274. else
  275. {
  276. CXTPCompatibleDC memDC(&paintDC, &m_bmpCache);
  277. paintDC.BitBlt(0, 0, rc.right, rc.bottom, &memDC, 0, 0, SRCCOPY);
  278. }
  279. m_bInvalidate = FALSE;
  280. }