📄 windowanima.cpp
字号:
whose image has not been captured before. An image of the window could be
stored as a resource within the application.
************************************************************************************/
BOOL CWindowAnima::ReplaceWindowImage(UINT nResID)
{
CBitmap bmWindow;
// load the bitmap into the object
BOOL bResult=bmWindow.LoadBitmap(nResID);
if(bResult){
BITMAP bitmapData;
// get the bitmap dimensions
bmWindow.GetBitmap(&bitmapData);
SetWindowSize(bitmapData.bmWidth, bitmapData.bmHeight);
// get rid of the old window image is one existed
if(m_pdcMemWnd!=NULL){
m_pdcMemWnd->SelectObject(m_pOldBitmapWnd);
delete m_pdcMemWnd;
}
m_pdcMemWnd=new CDC;
m_pdcMemWnd->CreateCompatibleDC(NULL);
//place the bitmap image into our memory DC for the window
m_pOldBitmapWnd=m_pdcMemWnd->SelectObject(&bmWindow);
}
return bResult;
}
/************************************************************************************
Copy the image from the CDC object pointed to by pdcMemScr into our member
DC object m_dcMemScr and update our member variables describing the screen's
size;
************************************************************************************/
BOOL CWindowAnima::InjectScreenImage(CDC *pdcMemScr)
{
CBitmap bmWindow;
CRect rectWindow;
if(m_pdcMemScr!=NULL){
m_pdcMemScr->SelectObject(m_pOldBitmapScr);
delete m_pdcMemScr;
}
m_pdcMemScr=new CDC;
CRect ClipRect;
// get the other CWindowAnima object's clipping region
pdcMemScr->GetClipBox(&ClipRect);
// set the screen dimensions to those of the other CWindowAnima object
SetScreenDimensions(ClipRect);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(m_pdcScreen,m_czScr.cx, m_czScr.cy);
// create compatible memory buffer of the screen dc
m_pdcMemScr->CreateCompatibleDC(m_pdcScreen);
// get a pointer to our original screen image
m_pOldBitmapScr=m_pdcMemScr->SelectObject(&bitmap);
// set the clipping region equal to that of the other CWindowAnima object
SetClippingRegion(ClipRect);
// capture a copy of the screen within the clipping region
return m_pdcMemScr->BitBlt(m_rectScr.left,m_rectScr.top,m_czScr.cx,
m_czScr.cy,pdcMemScr,m_rectScr.left,m_rectScr.top,SRCCOPY);
}
/************************************************************************************
Grab a copy of the window that another CWindowAnima object has gone to all the
trouble of capturing. Make sure (in debug mode) that some idiot hasn't passed
us a pointer to an CWindowAnima object that hasn't got a window image.
************************************************************************************/
BOOL CWindowAnima::CopyWindowCapture(CWindowAnima *pWA)
{
ASSERT(pWA->m_pdcMemWnd!=NULL);
return InjectWindowImage(pWA->m_pdcMemWnd, &pWA->m_rectWnd);
}
/************************************************************************************
Simply call the CWnd function ShowWindow with the SW_SHOW parameter on our
member variable m_pWnd which holds the pointer to the window we are
animating
************************************************************************************/
void CWindowAnima::ShowWindow()
{
m_pWnd->ShowWindow(SW_SHOW);
}
/************************************************************************************
Called by the constructors to initialise the member variables before any
animation can be done.
************************************************************************************/
void CWindowAnima::InitialSetup()
{
// get a dc to the entire screen
m_pdcScreen=new CClientDC(NULL);
m_pdcMemWnd=NULL;
m_pdcMemScr=NULL;
m_pWnd=NULL;
m_nFlags=0x0;
m_TaskBarClippingOn=FALSE;
m_pdcMemScr=new CDC;
//set the clipping region (initally the whole screen);
CRect rectScreen(0,0,GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN));
// set the screen dimensions
SetScreenDimensions(rectScreen);
CBitmap bitmap;
// create a bitmap whose dimensions are equal to that of the screen
bitmap.CreateCompatibleBitmap(m_pdcScreen,m_czScr.cx, m_czScr.cy);
// create compatible memory buffer of the screen dc
m_pdcMemScr->CreateCompatibleDC(m_pdcScreen);
// get a pointer to our original bitmap object
m_pOldBitmapScr=m_pdcMemScr->SelectObject(&bitmap);
}
/************************************************************************************
Sets the window to be animated and captures an image of the window. ASSERTs if
the window to be animated is invalid.
************************************************************************************/
void CWindowAnima::SetWindow(CWnd *pWnd)
{
ASSERT(pWnd!=NULL);
m_pWnd=pWnd;
CaptureWindowImage(m_pWnd);
}
/************************************************************************************
Returns a pointer to the window currently set for animation
************************************************************************************/
CWnd* CWindowAnima::GetWindow()
{
return m_pWnd;
}
/************************************************************************************
Repositions a window to the new co-ordinates specified by x and y and updates
internal variables that keep track of window position.
************************************************************************************/
void CWindowAnima::MoveWindowPosition(int x, int y)
{
m_pWnd->MoveWindow(x,y,m_czWnd.cx, m_czWnd.cy, TRUE);
m_rectWnd.OffsetRect(x-m_rectWnd.left,y-m_rectWnd.top);
}
/************************************************************************************
Sets the member flags variable with the nFlags parameter. Returns the current
state of the flags.
************************************************************************************/
UINT CWindowAnima::FlagSet(UINT nFlags)
{
m_nFlags|=nFlags;
return m_nFlags;
}
/************************************************************************************
Unsets the member flags variable with the nFlags parameter. Returns the current
state of the flags
************************************************************************************/
UINT CWindowAnima::FlagUnset(UINT nFlags)
{
m_nFlags&=~nFlags;
return m_nFlags;
}
/************************************************************************************
Returns TRUE / FALSE depending on whether a flag or set of flags is set.
************************************************************************************/
BOOL CWindowAnima::FlagIsSet(UINT nFlags)
{
return m_nFlags & nFlags;
}
/************************************************************************************
Returns one random direction from a possible number of nDirections. Currently
4 or 6. They include (left,right,up,down) when nDirections=4 and include
(vertical, horizontal) when nDirections=6.
************************************************************************************/
int CWindowAnima::GetRandomDirection(int nDirections)
{
srand((unsigned)time(NULL));
return rand()%nDirections;
}
/************************************************************************************
Creates a horizontal blinds disappearing effect on the window
************************************************************************************/
void CWindowAnima::BlindHorz(int nSegments, int nGapFactor, int nSleeptime)
{
int wx=m_rectWnd.left, wy=m_rectWnd.top;
int segWidth=m_czWnd.cy/nSegments;
int istop=m_czWnd.cy;
int stepcum=0;
int nGapWidth=nGapFactor;
PrintWindow();
for(int gap=nGapWidth;stepcum<segWidth;gap+=nGapWidth){
for(int i=0;i<=istop;i+=segWidth){
m_pdcScreen->BitBlt(wx,wy+i+stepcum, m_czWnd.cx,gap,
m_pdcMemScr, wx, wy+i+stepcum, SRCCOPY);
}
stepcum+=gap;
Sleep(nSleeptime);
}
}
/************************************************************************************
Creates a horizontal blinds appearing effect on the window
************************************************************************************/
void CWindowAnima::UnBlindHorz(int nSegments, int nGapFactor, int nSleeptime)
{
int wx=m_rectWnd.left, wy=m_rectWnd.top;
int segWidth=m_czWnd.cy/nSegments;
int istop=m_czWnd.cy;
int stepcum=0;
int nGapWidth=nGapFactor;
for(int gap=nGapWidth;stepcum<segWidth;gap+=nGapWidth){
for(int i=0;i<=istop;i+=segWidth){
m_pdcScreen->BitBlt(wx,wy+i+stepcum, m_czWnd.cx,gap,
m_pdcMemWnd, 0, i+stepcum, SRCCOPY);
}
stepcum+=gap;
Sleep(nSleeptime);
}
}
/************************************************************************************
Chooses which type of Blind effect to perform.
************************************************************************************/
void CWindowAnima::Blind(int nDirection, int nSegments, int nGapFactor, int nSleeptime)
{
// Do any pre-animation initialisations
Initialise();
switch(nDirection){
case WA_HORZ:
BlindHorz(nSegments, nGapFactor, nSleeptime);
break;
case WA_VERT:
BlindVert(nSegments, nGapFactor, nSleeptime);
break;
}
}
/************************************************************************************
Chooses which type of UnBlind effect to perform.
************************************************************************************/
void CWindowAnima::UnBlind(int nDirection, int nSegments, int nGapFactor, int nSleeptime)
{
// Do any pre-animation initialisations
Initialise();
switch(nDirection){
case WA_HORZ:
UnBlindHorz(nSegments, nGapFactor, nSleeptime);
break;
case WA_VERT:
UnBlindVert(nSegments, nGapFactor, nSleeptime);
break;
}
RestoreWindow(FALSE);
}
/************************************************************************************
Replace a window's image and size with an image contained in a CDC object.
Useful if you wanted to animate the initial appearance of a window
whose image has not been captured before. An image of the window could be
stored as a resource within the application.
************************************************************************************/
BOOL CWindowAnima::ReplaceWindowImage(CDC *pdc)
{
CRect dcRect;
// get the other pdc's clipping region and use that as the window size
// and postion
pdc->GetClipBox(&dcRect);
// call InjectWindowImage to set the new window image.
return InjectWindowImage(pdc, &dcRect);
}
/************************************************************************************
Sets the windows size by updating internal member variables relating to size
and position.
************************************************************************************/
void CWindowAnima::SetWindowSize(int nWidth, int nHeight)
{
CDC dc;
m_czWnd.cx=nWidth;
m_czWnd.cy=nHeight;
m_rectWnd.right=m_rectWnd.left+m_czWnd.cx;
m_rectWnd.bottom=m_rectWnd.top+m_czWnd.cy;
}
/************************************************************************************
Sets the clipping region rectangle for the animation and updates the
screen dimensions
************************************************************************************/
BOOL CWindowAnima::SetClippingRegion(CRect &ClipRect)
{
CRgn ClipRgn;
ClipRgn.CreateRectRgnIndirect(ClipRect);
ASSERT(m_pdcScreen!=NULL && m_pdcMemScr!=NULL);
// Possible change here is to set the clipping region only on the
// screen dc. Dunno if putting a clipping region on the memorydc
// causes a performance penalty
if(m_pdcScreen->SelectObject(&ClipRgn)!=ERROR &&
m_pdcMemScr->SelectObject(&ClipRgn)!=ERROR){
SetScreenDimensions(ClipRect);
return TRUE;
}
return FALSE;
}
/************************************************************************************
Overloaded version of SetClippingRegion() function above
************************************************************************************/
BOOL CWindowAnima::SetClippingRegion(int l, int t, int r, int b)
{
CRect ClipRect(l,t,r,b);
return SetClippingRegion(ClipRect);
}
/************************************************************************************
Returns the current Clipping Region and Working Screen Area (same thing)
************************************************************************************/
void CWindowAnima::GetClippingRegion(CRect *pEmptyRect)
{
pEmptyRect->CopyRect(&m_rectScr);
}
/************************************************************************************
Sets the dimensions of the Working Screen Area and clipping region (same thing)
************************************************************************************/
void CWindowAnima::SetScreenDimensions(CRect &ScrRect)
{
m_rectScr.CopyRect(ScrRect);
m_czScr.cx=ScrRect.Width();
m_czScr.cy=ScrRect.Height();
}
/************************************************************************************
Toggles on/off whether or not the windows taskbar will be always on top of the
animation or not.
************************************************************************************/
void CWindowAnima::ToggleTaskBarOnTop(UINT nSwitch)
{
APPBARDATA AppBarData;
AppBarData.cbSize=sizeof(AppBarData);
// get the taskbar position and dimensions
if(SHAppBarMessage(ABM_GETTASKBARPOS, &AppBarData)){
CRect rectTemp;
// Set rectNewScreen to our current Screen dimensions, then at
// worst we'll just set the clipping region to what it already is
CRect rectNewScreen(m_rectScr);
switch(nSwitch){
case WA_TASKBAR_ON:
// if part of the window is obscured by the task bar
if(rectTemp.IntersectRect(m_rectScr, &AppBarData.rc))
rectNewScreen.SubtractRect(m_rectScr, &AppBarData.rc);
break;
case WA_TASKBAR_OFF:
// find which edge the task bar is stuck to
switch(AppBarData.uEdge){
case ABE_BOTTOM:
// if the bottom of our window and the top of the taskbar
// are touching then extend the clipping region
if(AppBarData.rc.top<=m_rectScr.bottom)
rectNewS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -