// WindowAnima.cpp: implementation of the CWindowAnima class.
//
//////////////////////////////////////////////////////////////////////
/*
*
*
* Copyright (c) 2002 DigitalConvict <ax@digitalconvict.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
* Contact info:
* Site: http://www.digitalconvict.com
* Email: ax@digitalconvict.com
*/
#include "stdafx.h"
#include "WindowAnima.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
/************************************************************************************
Default Constructor
************************************************************************************/
CWindowAnima::CWindowAnima()
{
InitialSetup();
}
/************************************************************************************
Overloaded constructor, takes CWnd* and captures an image of the winddow. The
window pointed to by pWnd mUST be visible unless the WA_WND_SKIPCAPTURE flag is
also included in the nFlags parameter.
************************************************************************************/
CWindowAnima::CWindowAnima(CWnd *pWnd, UINT nFlags)
{
InitialSetup();
FlagSet(nFlags);
SetWindow(pWnd);
}
/************************************************************************************
Deletes any of the dynamically created CDC pointers
************************************************************************************/
CWindowAnima::~CWindowAnima()
{
// select out bitmap we've been using replace with original
m_pdcMemScr->SelectObject(m_pOldBitmapScr);
m_pdcMemWnd->SelectObject(m_pOldBitmapWnd);
// delete all DC's held in memory
delete m_pdcScreen;
delete m_pdcMemWnd;
delete m_pdcMemScr;
}
/************************************************************************************
Two partitions slide horizontally away from eachother underneath the window.
The window then disappears into the black void, Finally the partitions close
back together leaving the screen intact minus the window
************************************************************************************/
void CWindowAnima::SlideVanish(int nSlideFactor, int nScaleFactor,
int nSlideDelay, int nVanishDelay)
{
// make sure we can stretch blit on this device
if(!(m_pdcScreen->GetDeviceCaps(RASTERCAPS) & RC_STRETCHBLT))
return;
// Do any pre-animation initialisations
Initialise();
int wx=m_rectWnd.left, wy=m_rectWnd.top;
CPoint cptWindowCenter=m_rectWnd.CenterPoint();
CSize czDiv(m_czWnd.cx/2, m_czWnd.cy/2);
int nHeight=m_rectWnd.Height(), nWidth=m_rectWnd.Width(),nLeftx, nRightx;
int nOpen=0;
// print an image of the original window to the screen
PrintWindow();
// slide partitions apart
while(nOpen<=czDiv.cx){
nLeftx=wx-nOpen;
nRightx=m_rectWnd.right-nOpen;
//move left partition
m_pdcScreen->BitBlt(nLeftx,wy,nOpen,nHeight,m_pdcMemScr,
wx,wy,SRCCOPY);
//move right partition
m_pdcScreen->BitBlt(m_rectWnd.right,wy,nOpen,nHeight,m_pdcMemScr,
nRightx,wy,SRCCOPY);
nOpen+=nSlideFactor;
Sleep(nSlideDelay);
}
int nScale=0;
int x=wx,y=wy,w=nWidth,h=nHeight;
// scale down the window so it disappears into a black background
while(w>0 && h>0){
// scale window
m_pdcScreen->StretchBlt(x,y,w,h,m_pdcMemWnd,0,0,nWidth,nHeight,SRCCOPY);
// fill in solid black rectangles over only the areas that show
// part of the last scale operation. This is better than just drawing
// one solid rectangle over the whole area where we're manipulating
// because we'll avoid flicker.
m_pdcScreen->FillSolidRect(x,y,w,nScaleFactor,0x00000000);
m_pdcScreen->FillSolidRect(x,y+h-nScaleFactor,w,nScaleFactor,0x00000000);
m_pdcScreen->FillSolidRect(x,y,nScaleFactor,h,0x00000000);
m_pdcScreen->FillSolidRect(x+w,y,nScaleFactor,h,0x00000000);
x=m_rectWnd.left+nScale/2;
y=m_rectWnd.top+nScale/2;
w=nWidth-nScale;
h=nHeight-nScale;
nScale+=nScaleFactor;
Sleep(nVanishDelay);
}
// slide partitions together again
nOpen=0;
while(nOpen<=czDiv.cx){
//move left partition
m_pdcScreen->BitBlt(m_rectWnd.left-czDiv.cx+nOpen,wy,czDiv.cx,nHeight,m_pdcMemScr,
wx,wy,SRCCOPY);
//move right partition
m_pdcScreen->BitBlt(m_rectWnd.right-nOpen,wy,czDiv.cx,nHeight,m_pdcMemScr,
wx+czDiv.cx,wy,SRCCOPY);
//cover site of last left partition
m_pdcScreen->BitBlt(nLeftx,wy,nOpen,nHeight,m_pdcMemScr,
nLeftx,wy,SRCCOPY);
//cover site of last right partition
m_pdcScreen->BitBlt(m_rectWnd.right+czDiv.cx-nOpen,wy,nOpen,nHeight,m_pdcMemScr,
m_rectWnd.right+czDiv.cx-nOpen,wy,SRCCOPY);
Sleep(nSlideDelay);
nOpen+=nSlideFactor;
}
// execute loop code one more time if window size is odd
if(m_rectWnd.Width()%2==1){
m_pdcScreen->BitBlt(m_rectWnd.left-czDiv.cx+nOpen,wy,czDiv.cx,nHeight,m_pdcMemScr,
wx,wy,SRCCOPY);
m_pdcScreen->BitBlt(m_rectWnd.right-nOpen,wy,czDiv.cx,nHeight,m_pdcMemScr,
wx+czDiv.cx,wy,SRCCOPY);
// repaint original screen to avoid animation trail
m_pdcScreen->BitBlt(nLeftx,wy,nOpen,nHeight,m_pdcMemScr,
nLeftx,wy,SRCCOPY);
m_pdcScreen->BitBlt(m_rectWnd.right+czDiv.cx-nOpen,wy,nOpen,nHeight,m_pdcMemScr,
nRightx-nOpen,wy,SRCCOPY);
}
}
/************************************************************************************
Two partitions slide horizontally away from eachother opening into a black void.
Zoooming out of the woid the window appears. The partitions then close slide
back together again behind the now fully visible window.
************************************************************************************/
void CWindowAnima::SlideAppear(int nSlideFactor, int nScaleFactor,
int nSlideDelay, int nAppearDelay)
{
// make sure we can stretch blit on this device
if(!(m_pdcScreen->GetDeviceCaps(RASTERCAPS) & RC_STRETCHBLT))
return;
// Do any pre-animation initialisations
Initialise();
int wx=m_rectWnd.left, wy=m_rectWnd.top;
CPoint cptWindowCenter=m_rectWnd.CenterPoint();
CSize czDiv(m_czWnd.cx/2, m_czWnd.cy/2);
int nHeight=m_rectWnd.Height(), nWidth=m_rectWnd.Width(),nLeftx, nRightx;
int nOpen=0;
// slide out two parts of the screen to make way for the window
while(nOpen<=czDiv.cx){
nLeftx=wx-nOpen;
nRightx=cptWindowCenter.x+nOpen;
m_pdcScreen->BitBlt(nLeftx,wy,czDiv.cx,nHeight,m_pdcMemScr,
wx,wy,SRCCOPY);
m_pdcScreen->BitBlt(nRightx,wy,czDiv.cx,nHeight,m_pdcMemScr,
cptWindowCenter.x,wy,SRCCOPY);
m_pdcScreen->FillSolidRect(wx+czDiv.cx-nOpen,wy,nOpen*2,nHeight,0x00000000);
nOpen+=nSl