/*----------------------------------------------------------------------------*/
/* CFaderWnd implementation */
/*----------------------------------------------------------------------------*/
//
// File: FaderWnd.cpp
// Author: Phil J. Pearson
// Created: 20 June 2000 14:26
// Last Mod: 23 June 2000 19:06
//
/*----------------------------------------------------------------------------
/*
/* Copyright (C) 2000 by Real World Software
/* All Rights Reserved.
/*
/*----------------------------------------------------------------------------*/
///////////////////////////////////////////////////////////////////////////////
//
// An MFC class to fade out any window, requiring only one extra line of
// code, typically:
// new CFaderWnd(this);
//
// It uses the UpdateLayeredWindow function, not available on Win9x or NT.
// It uses GetProcAddress instead of implicitly linking to the function so
// that code using this class will load and run on any Win32 platform. If
// the necessary function is not available then the fade will simply not
// happen.
// It works by making an exact copy of the source window and fading the copy
// so it is usual to hide or destroy the source window immediately after
// creating an instance of this class. For example,
// new CFaderWnd(this);
// ShowWindow(SW_HIDE);
// or
// new CFaderWnd(this);
// DestroyWindow();
// or
// new CFaderWnd(this);
// EndDialog(nResult);
// Note that it's essential to construct the CFaderWnd FIRST.
//
// CFaderWnd must ALWAYS be contructed on the heap (with new CFaderWnd...).
// It is NEVER necessary to call the destructor (delete ...) since CFaderWnd
// takes care of deleting itself (tidies up and closes the door behind itself).
//
///////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "FaderWnd.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// how much we decrease the alpha each time
#define ALPHA_STEP 5
/////////////////////////////////////////////////////////////////////////////
// CFaderWnd
CFaderWnd::CFaderWnd(CWnd *pWndToFade, UINT nFadeTime /*= 2000*/, BYTE byAlpha /*= 255*/)
: m_pWndToFade(pWndToFade)
{
ASSERT(pWndToFade);
ASSERT_VALID(pWndToFade);
// Try to get the address of the UpdateLayeredWindow function. It may not be available.
HMODULE hUser32 = GetModuleHandle(_T("USER32.DLL"));
m_pUpdateLayeredWindow = (lpfnUpdateLayeredWindow)GetProcAddress(hUser32, "UpdateLayeredWindow");
// If OS doesn't provide the function we can't fade, just commit suicide.
if (NULL == m_pUpdateLayeredWindow)
delete this;
else
{
CRect rc;
CPoint ptSrc(0, 0);
SIZE size;
// Get the window rect of the source window.
m_pWndToFade->GetWindowRect(rc);
// Make a new window to match.
// WS_EX_LAYERED is necessary for UpdateLayeredWindow to be enabled.
// WS_EX_TRANSPARENT allows mouse clicks through to the window "underneath",
// (it's nothing to do with optical transparency).
CreateEx(WS_EX_LAYERED|WS_EX_TRANSPARENT|WS_EX_TOPMOST|WS_EX_TOOLWINDOW,
"STATIC", "", WS_POPUP|WS_VISIBLE, rc, AfxGetMainWnd(), 0);
// UpdateLayeredWindow needs the size and origin of the source window.
size.cx = rc.Width();
size.cy = rc.Height();
ptSrc = rc.TopLeft();
// Set up the BLENDFUNCTION struct used by UpdateLayeredWindow
m_Blend.BlendOp = AC_SRC_OVER; // the only BlendOp defined in Windows 2000
m_Blend.BlendFlags = 0; // nothing else is special ...
m_Blend.AlphaFormat = 0; // ...
m_Blend.SourceConstantAlpha = byAlpha; // the initial alpha value
// Display the new static window with the exact content and position of the source window.
// When we return the caller can hide or destroy the source window and nothing will
// appear to change. Subsequently (in OnTimer) we will reduce the alpha value to fade away
// this copy window.
m_pUpdateLayeredWindow(GetSafeHwnd(), NULL, NULL, &size, ::GetDC(m_pWndToFade->GetSafeHwnd()),
&ptSrc, 0, &m_Blend, ULW_ALPHA);
// Calculate the timer interval required to complete the fade in the specified time.
UINT nElapse = nFadeTime / (byAlpha / ALPHA_STEP);
SetTimer(1, nElapse, NULL);
}
}
CFaderWnd::~CFaderWnd()
{
}
BEGIN_MESSAGE_MAP(CFaderWnd, CWnd)
//{{AFX_MSG_MAP(CFaderWnd)
ON_WM_TIMER()
ON_WM_SETFOCUS()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFaderWnd message handlers
void CFaderWnd::OnTimer(UINT nIDEvent)
{
if (m_Blend.SourceConstantAlpha >= ALPHA_STEP)
{
// Reduce the alpha value (towards transparency) and update the window.
m_Blend.SourceConstantAlpha -= ALPHA_STEP;
m_pUpdateLayeredWindow(GetSafeHwnd(), NULL, NULL, NULL, NULL, NULL, NULL, &m_Blend, ULW_ALPHA);
}
else
{
// Reached minimum alpha. Kill the timer and destroy our window.
// PostNcDestroy will delete this CFaderWnd instance.
KillTimer(nIDEvent);
DestroyWindow();
}
}
void CFaderWnd::OnSetFocus(CWnd* pOldWnd)
{
// When we get the input focus pass it back to the previous holder, if any.
if (pOldWnd)
pOldWnd->SetFocus();
}
本文地址:http://com.8s8s.com/it/it25006.htm