You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
367 lines
8.4 KiB
C++
367 lines
8.4 KiB
C++
2 years ago
|
// XTPCommandBarAnimation.cpp : implementation file
|
||
|
//
|
||
|
// This file is a part of the XTREME COMMANDBARS MFC class library.
|
||
|
// (c)1998-2012 Codejock Software, All Rights Reserved.
|
||
|
//
|
||
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
||
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
||
|
// CONSENT OF CODEJOCK SOFTWARE.
|
||
|
//
|
||
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
||
|
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
||
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
||
|
// SINGLE COMPUTER.
|
||
|
//
|
||
|
// CONTACT INFORMATION:
|
||
|
// support@codejock.com
|
||
|
// http://www.codejock.com
|
||
|
//
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
|
||
|
#include "Common/XTPImageManager.h"
|
||
|
#include "Common/XTPDrawHelpers.h"
|
||
|
#include "Common/XTPHookManager.h"
|
||
|
#include "Common/XTPSystemHelpers.h"
|
||
|
#include "Common/XTPColorManager.h"
|
||
|
|
||
|
#include "XTPCommandBarsDefines.h"
|
||
|
#include "XTPCommandBarAnimation.h"
|
||
|
#include "XTPCommandBar.h"
|
||
|
#include "XTPPaintManager.h"
|
||
|
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#define new DEBUG_NEW
|
||
|
#undef THIS_FILE
|
||
|
static char THIS_FILE[] = __FILE__;
|
||
|
#endif
|
||
|
|
||
|
CXTPCommandBarAnimation::CAnimateInfo::CAnimateInfo()
|
||
|
{
|
||
|
hbmSrc = 0;
|
||
|
pSrcBits = 0;
|
||
|
hbmSrcBack = 0;
|
||
|
pSrcBackBits = 0;
|
||
|
SetRectEmpty(&rcPaint);
|
||
|
m_nAnimation = 0;
|
||
|
}
|
||
|
|
||
|
CXTPCommandBarAnimation::CAnimateInfo::~CAnimateInfo()
|
||
|
{
|
||
|
DeleteObject(hbmSrc);
|
||
|
DeleteObject(hbmSrcBack);
|
||
|
}
|
||
|
|
||
|
CXTPCommandBarAnimation::CXTPCommandBarAnimation(CXTPCommandBar* pCommandBar)
|
||
|
{
|
||
|
m_bInvalidate = FALSE;
|
||
|
m_pParent = pCommandBar;
|
||
|
m_nTimer = 0;
|
||
|
|
||
|
m_bAnimation = FALSE;
|
||
|
m_bDoubleBuffer = FALSE;
|
||
|
}
|
||
|
|
||
|
CXTPCommandBarAnimation::~CXTPCommandBarAnimation()
|
||
|
{
|
||
|
RemoveAnimations();
|
||
|
}
|
||
|
|
||
|
void CXTPCommandBarAnimation::RemoveAnimations()
|
||
|
{
|
||
|
for (int i = 0; i < m_arrAnimation.GetSize(); i++)
|
||
|
{
|
||
|
delete m_arrAnimation[i];
|
||
|
}
|
||
|
|
||
|
m_arrAnimation.RemoveAll();
|
||
|
|
||
|
if (m_nTimer && m_pParent->GetSafeHwnd())
|
||
|
{
|
||
|
m_pParent->KillTimer(XTP_TID_ANIMATION);
|
||
|
}
|
||
|
m_nTimer = 0;
|
||
|
}
|
||
|
|
||
|
void CXTPCommandBarAnimation::AlphaBlendU(PBYTE pDest, PBYTE pSrcBack, int cx, int cy, PBYTE pSrc, BYTE byAlpha)
|
||
|
{
|
||
|
const BYTE byDiff = (BYTE)(255 - byAlpha);
|
||
|
|
||
|
for (int i = 0; i < cx * cy * 4; i++)
|
||
|
{
|
||
|
pDest[0] = (BYTE)((pSrcBack[0] * byDiff + pSrc[0] * byAlpha) >> 8);
|
||
|
|
||
|
pDest += 1;
|
||
|
pSrcBack += 1;
|
||
|
pSrc += 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#define MAXANIMATION 6
|
||
|
|
||
|
BOOL CXTPCommandBarAnimation::IsAnimationEnabled() const
|
||
|
{
|
||
|
return m_bAnimation || m_pParent->GetPaintManager()->m_bEnableAnimation;
|
||
|
}
|
||
|
|
||
|
void CXTPCommandBarAnimation::AnimateRect(CClientDC& dc, CAnimateInfo* pai)
|
||
|
{
|
||
|
CRect rcPaint = pai->rcPaint;
|
||
|
int cx = rcPaint.Width();
|
||
|
int cy = rcPaint.Height();
|
||
|
|
||
|
CDC memDC;
|
||
|
memDC.CreateCompatibleDC(&dc);
|
||
|
|
||
|
if (pai->m_nAnimation == MAXANIMATION)
|
||
|
{
|
||
|
HBITMAP hOldBitmap = (HBITMAP)::SelectObject(memDC, m_bmpCache);
|
||
|
|
||
|
dc.BitBlt(rcPaint.left, rcPaint.top, cx, cy,
|
||
|
&memDC, rcPaint.left, rcPaint.top, SRCCOPY);
|
||
|
|
||
|
::SelectObject(memDC, hOldBitmap);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
BYTE* pDestBits = NULL;
|
||
|
HBITMAP hbmDest = CXTPImageManager::Create32BPPDIBSection(dc, cx, cy, &pDestBits);
|
||
|
|
||
|
if (hbmDest && pDestBits)
|
||
|
{
|
||
|
AlphaBlendU(pDestBits, pai->pSrcBackBits, cx, cy, pai->pSrcBits, (BYTE)(255 * pai->m_nAnimation / MAXANIMATION));
|
||
|
|
||
|
HBITMAP hOldBitmap = (HBITMAP)::SelectObject(memDC, hbmDest);
|
||
|
|
||
|
dc.BitBlt(rcPaint.left, rcPaint.top, cx, cy, &memDC, 0, 0, SRCCOPY);
|
||
|
|
||
|
::SelectObject(memDC, hOldBitmap);
|
||
|
DeleteObject(hbmDest);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pai->m_nAnimation++;
|
||
|
}
|
||
|
|
||
|
void CXTPCommandBarAnimation::OnAnimate()
|
||
|
{
|
||
|
CClientDC dc(m_pParent);
|
||
|
|
||
|
for (int i = 0; i < m_arrAnimation.GetSize(); i++)
|
||
|
{
|
||
|
CAnimateInfo* pai = m_arrAnimation[i];
|
||
|
|
||
|
for (int j = 0; j < pai->arrExclude.GetSize(); j++)
|
||
|
dc.ExcludeClipRect(&pai->arrExclude[j]);
|
||
|
|
||
|
AnimateRect(dc, pai);
|
||
|
|
||
|
dc.SelectClipRgn(NULL);
|
||
|
|
||
|
if (pai->m_nAnimation > MAXANIMATION)
|
||
|
{
|
||
|
m_arrAnimation.RemoveAt(i);
|
||
|
delete pai;
|
||
|
i--;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (m_arrAnimation.GetSize() == 0 && m_nTimer)
|
||
|
{
|
||
|
m_pParent->KillTimer(XTP_TID_ANIMATION);
|
||
|
m_nTimer = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CXTPCommandBarAnimation::RemoveIntersections(LPCRECT rcPaint, BOOL bAddExclude)
|
||
|
{
|
||
|
for (int i = 0; i < m_arrAnimation.GetSize(); i++)
|
||
|
{
|
||
|
CAnimateInfo* paiOld = m_arrAnimation[i];
|
||
|
|
||
|
CRect rcIntersect;
|
||
|
if (rcIntersect.IntersectRect(&paiOld->rcPaint, rcPaint))
|
||
|
{
|
||
|
if (rcIntersect == paiOld->rcPaint)
|
||
|
{
|
||
|
m_arrAnimation.RemoveAt(i);
|
||
|
delete paiOld;
|
||
|
i--;
|
||
|
}
|
||
|
else if (bAddExclude)
|
||
|
{
|
||
|
paiOld->arrExclude.Add((RECT&)*rcPaint);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CXTPCommandBarAnimation::AddAnimation(CClientDC& dc, CAnimateInfo* pai)
|
||
|
{
|
||
|
RemoveIntersections(&pai->rcPaint, FALSE);
|
||
|
|
||
|
m_arrAnimation.Add(pai);
|
||
|
|
||
|
if (m_nTimer == 0)
|
||
|
{
|
||
|
m_nTimer = m_pParent->SetTimer(XTP_TID_ANIMATION, 50, NULL);
|
||
|
}
|
||
|
|
||
|
AnimateRect(dc, pai);
|
||
|
}
|
||
|
|
||
|
void CXTPCommandBarAnimation::OnDestroy()
|
||
|
{
|
||
|
m_bmpCache.DeleteObject();
|
||
|
RemoveAnimations();
|
||
|
}
|
||
|
|
||
|
void CXTPCommandBarAnimation::RedrawRect(LPCRECT lpRect, BOOL bAnimate)
|
||
|
{
|
||
|
if (lpRect == NULL)
|
||
|
{
|
||
|
m_bmpCache.DeleteObject();
|
||
|
}
|
||
|
|
||
|
if (lpRect == NULL || m_bmpCache.GetSafeHandle() == 0 || !IsAnimationEnabled())
|
||
|
{
|
||
|
m_bInvalidate = TRUE;
|
||
|
m_pParent->InvalidateRect(lpRect, FALSE);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
CClientDC dc(m_pParent);
|
||
|
CXTPClientRect rc(m_pParent);
|
||
|
CRect rcPaint(lpRect);
|
||
|
|
||
|
CDC dcDraw;
|
||
|
dcDraw.CreateCompatibleDC(&dc);
|
||
|
|
||
|
CBitmap bmpDraw;
|
||
|
bmpDraw.CreateCompatibleBitmap(&dc, rc.Width(), rc.Height());
|
||
|
HBITMAP hOldBitmapDraw = (HBITMAP)::SelectObject(dcDraw, bmpDraw);
|
||
|
|
||
|
CRgn rgn;
|
||
|
rgn.CreateRectRgnIndirect(rcPaint);
|
||
|
dcDraw.SelectClipRgn(&rgn);
|
||
|
|
||
|
m_pParent->DrawCommandBar(&dcDraw, rcPaint);
|
||
|
|
||
|
dcDraw.SelectClipRgn(0);
|
||
|
|
||
|
CDC dcCache;
|
||
|
dcCache.CreateCompatibleDC(&dc);
|
||
|
HBITMAP hOldBitmapCache = (HBITMAP)::SelectObject(dcCache, m_bmpCache);
|
||
|
|
||
|
if (!bAnimate)
|
||
|
{
|
||
|
RemoveIntersections(&rcPaint, TRUE);
|
||
|
|
||
|
dcCache.BitBlt(rcPaint.left, rcPaint.top, rcPaint.Width(), rcPaint.Height(),
|
||
|
&dcDraw, rcPaint.left, rcPaint.top, SRCCOPY);
|
||
|
|
||
|
dc.BitBlt(rcPaint.left, rcPaint.top, rcPaint.Width(), rcPaint.Height(),
|
||
|
&dcDraw, rcPaint.left, rcPaint.top, SRCCOPY);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CAnimateInfo* pai = new CAnimateInfo;
|
||
|
pai->rcPaint = rcPaint;
|
||
|
pai->m_nAnimation = 1;
|
||
|
pai->hbmSrc = CXTPImageManager::Create32BPPDIBSection(dc, rcPaint.Width(), rcPaint.Height(), &pai->pSrcBits);
|
||
|
pai->hbmSrcBack = CXTPImageManager::Create32BPPDIBSection(dc, rcPaint.Width(), rcPaint.Height(), &pai->pSrcBackBits);
|
||
|
|
||
|
CDC dcSrc;
|
||
|
dcSrc.CreateCompatibleDC(&dc);
|
||
|
|
||
|
CDC dcSrcBack;
|
||
|
dcSrcBack.CreateCompatibleDC(&dc);
|
||
|
|
||
|
HBITMAP hOldBitmapSrc = (HBITMAP)::SelectObject(dcSrc, pai->hbmSrc);
|
||
|
HBITMAP hOldBitmapSrcBack = (HBITMAP)::SelectObject(dcSrcBack, pai->hbmSrcBack);
|
||
|
|
||
|
dcSrc.BitBlt(0, 0, rcPaint.Width(), rcPaint.Height(), &dcDraw, rcPaint.left, rcPaint.top, SRCCOPY);
|
||
|
|
||
|
dcSrcBack.BitBlt(0, 0, rcPaint.Width(), rcPaint.Height(), &dcCache, rcPaint.left, rcPaint.top, SRCCOPY);
|
||
|
|
||
|
dcCache.BitBlt(rcPaint.left, rcPaint.top, rcPaint.Width(), rcPaint.Height(), &dcSrc, 0, 0, SRCCOPY);
|
||
|
|
||
|
::SelectObject(dcSrcBack, hOldBitmapSrcBack);
|
||
|
::SelectObject(dcSrc, hOldBitmapSrc);
|
||
|
|
||
|
if (memcmp(pai->pSrcBits, pai->pSrcBackBits, rcPaint.Width() * rcPaint.Height() * 4) == 0)
|
||
|
{
|
||
|
delete pai;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
AddAnimation(dc, pai);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
::SelectObject(dcCache, hOldBitmapCache);
|
||
|
::SelectObject(dcDraw, hOldBitmapDraw);
|
||
|
}
|
||
|
|
||
|
void CXTPCommandBarAnimation::OnPaint(CPaintDC& paintDC)
|
||
|
{
|
||
|
CXTPClientRect rc(m_pParent);
|
||
|
CRect rcPaint(paintDC.m_ps.rcPaint);
|
||
|
|
||
|
if (m_bmpCache.GetSafeHandle())
|
||
|
{
|
||
|
BITMAP bmpInfo;
|
||
|
m_bmpCache.GetBitmap(&bmpInfo);
|
||
|
|
||
|
if (bmpInfo.bmHeight != rc.Height() || bmpInfo.bmWidth != rc.Width())
|
||
|
m_bmpCache.DeleteObject();
|
||
|
}
|
||
|
|
||
|
if (!m_bDoubleBuffer && !IsAnimationEnabled())
|
||
|
{
|
||
|
m_bmpCache.DeleteObject();
|
||
|
|
||
|
CXTPBufferDC memDC(paintDC);
|
||
|
m_pParent->DrawCommandBar(&memDC, rcPaint);
|
||
|
|
||
|
RemoveAnimations();
|
||
|
}
|
||
|
else if (m_bInvalidate || m_bmpCache.GetSafeHandle() == 0)
|
||
|
{
|
||
|
CDC memDC;
|
||
|
memDC.CreateCompatibleDC(&paintDC);
|
||
|
|
||
|
if (!m_bmpCache.GetSafeHandle())
|
||
|
{
|
||
|
m_bmpCache.CreateCompatibleBitmap(&paintDC, rc.Width(), rc.Height());
|
||
|
rcPaint = rc;
|
||
|
}
|
||
|
|
||
|
CBitmap* pOldBitmap = memDC.SelectObject(&m_bmpCache);
|
||
|
|
||
|
CRgn rgn;
|
||
|
rgn.CreateRectRgnIndirect(rcPaint);
|
||
|
memDC.SelectClipRgn(&rgn);
|
||
|
|
||
|
m_pParent->DrawCommandBar(&memDC, rcPaint);
|
||
|
|
||
|
memDC.SelectClipRgn(0);
|
||
|
|
||
|
paintDC.BitBlt(rcPaint.left, rcPaint.top, rcPaint.Width(), rcPaint.Height(),
|
||
|
&memDC, rcPaint.left, rcPaint.top, SRCCOPY);
|
||
|
|
||
|
memDC.SelectObject(pOldBitmap);
|
||
|
|
||
|
RemoveAnimations();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CXTPCompatibleDC memDC(&paintDC, &m_bmpCache);
|
||
|
paintDC.BitBlt(0, 0, rc.right, rc.bottom, &memDC, 0, 0, SRCCOPY);
|
||
|
}
|
||
|
|
||
|
m_bInvalidate = FALSE;
|
||
|
}
|