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

对话框与窗口

开发平台:

Visual C++

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