FaderWnd.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. //Download by http://www.NewXing.com
  2. /*----------------------------------------------------------------------------*/
  3. /* CFaderWnd implementation */
  4. /*----------------------------------------------------------------------------*/
  5. //
  6. // File: FaderWnd.cpp
  7. // Author: Phil J. Pearson
  8. // Created: 20 June 2000 14:26
  9. // Last Mod: 23 June 2000 19:06
  10. //
  11. /*----------------------------------------------------------------------------
  12. /*
  13. /* Copyright (C) 2000 by Real World Software
  14. /* All Rights Reserved.
  15. /*
  16. /*----------------------------------------------------------------------------*/
  17. ///////////////////////////////////////使用说明 ////////////////////////////////////////
  18. //
  19. // An MFC class to fade out any window, requiring only one extra line of
  20. // code, typically:
  21. // new CFaderWnd(this);
  22. //
  23. // It uses the UpdateLayeredWindow function, not available on Win9x or NT.
  24. // It uses GetProcAddress instead of implicitly linking to the function so
  25. // that code using this class will load and run on any Win32 platform. If
  26. // the necessary function is not available then the fade will simply not
  27. // happen.
  28. // It works by making an exact copy of the source window and fading the copy
  29. // so it is usual to hide or destroy the source window immediately after
  30. // creating an instance of this class. For example,
  31. // new CFaderWnd(this);
  32. // ShowWindow(SW_HIDE);
  33. // or
  34. // new CFaderWnd(this);
  35. // DestroyWindow();
  36. // or
  37. // new CFaderWnd(this);
  38. // EndDialog(nResult);
  39. // Note that it's essential to construct the CFaderWnd FIRST.
  40. //
  41. // CFaderWnd must ALWAYS be contructed on the heap (with new CFaderWnd...).
  42. // It is NEVER necessary to call the destructor (delete ...) since CFaderWnd
  43. // takes care of deleting itself (tidies up and closes the door behind itself).
  44. //
  45. ///////////////////////////////////////////////////////////////////////////////
  46. #include "stdafx.h"
  47. #include "FaderWnd.h"
  48. #ifdef _DEBUG
  49. #define new DEBUG_NEW
  50. #undef THIS_FILE
  51. static char THIS_FILE[] = __FILE__;
  52. #endif
  53. #define ALPHA_STEP 5 //每次减少的透明度数
  54. /////////////////////////////////////////////////////////////////////////////
  55. CFaderWnd::CFaderWnd(CWnd *pWndToFade, UINT nFadeTime /*= 1000*/, BYTE byAlpha /*= 255*/)
  56. : m_pWndToFade(pWndToFade)
  57. {
  58. ASSERT(pWndToFade);
  59. ASSERT_VALID(pWndToFade);
  60. HMODULE hUser32 = GetModuleHandle(_T("USER32.DLL"));
  61. m_pUpdateLayeredWindow = (lpfnUpdateLayeredWindow)GetProcAddress(hUser32, "UpdateLayeredWindow");
  62. // If OS doesn't provide the function we can't fade, just commit suicide.
  63. if (NULL == m_pUpdateLayeredWindow)
  64. delete this;
  65. else
  66. {
  67. CRect rc;
  68. CPoint ptSrc(0, 0);
  69. SIZE size;
  70. m_pWndToFade->GetWindowRect(rc);
  71. // Make a new window to match.
  72. // WS_EX_LAYERED is necessary for UpdateLayeredWindow to be enabled.
  73. // WS_EX_TRANSPARENT allows mouse clicks through to the window "underneath",
  74. // (it's nothing to do with optical transparency).
  75. CreateEx(WS_EX_LAYERED|WS_EX_TRANSPARENT|WS_EX_TOPMOST|WS_EX_TOOLWINDOW,
  76. "STATIC", "", WS_POPUP|WS_VISIBLE, rc, AfxGetMainWnd(), 0);
  77. // UpdateLayeredWindow needs the size and origin of the source window.
  78. size.cx = rc.Width();
  79. size.cy = rc.Height();
  80. ptSrc = rc.TopLeft();
  81. // Set up the BLENDFUNCTION struct used by UpdateLayeredWindow
  82. m_Blend.BlendOp = AC_SRC_OVER; // the only BlendOp defined in Windows 2000
  83. m_Blend.BlendFlags = 0; // nothing else is special ...
  84. m_Blend.AlphaFormat = 0; // ...
  85. m_Blend.SourceConstantAlpha = byAlpha; // the initial alpha value
  86. // Display the new static window with the exact content and position of the source window.
  87. // When we return the caller can hide or destroy the source window and nothing will
  88. // appear to change. Subsequently (in OnTimer) we will reduce the alpha value to fade away
  89. // this copy window.
  90. m_pUpdateLayeredWindow(GetSafeHwnd(),
  91. NULL,
  92. NULL,
  93. &size,
  94. ::GetDC(m_pWndToFade->GetSafeHwnd()),
  95. &ptSrc,
  96. 0,
  97. &m_Blend,
  98. ULW_ALPHA
  99. ); //调用动态连接库中的函数
  100. // Calculate the timer interval required to complete the fade in the specified time.
  101. UINT nElapse = nFadeTime / (byAlpha / ALPHA_STEP);
  102. SetTimer(1, nElapse, NULL);
  103. }
  104. }
  105. CFaderWnd::~CFaderWnd()
  106. {
  107. }
  108. BEGIN_MESSAGE_MAP(CFaderWnd, CWnd)
  109. //{{AFX_MSG_MAP(CFaderWnd)
  110. ON_WM_TIMER()
  111. ON_WM_SETFOCUS()
  112. //}}AFX_MSG_MAP
  113. END_MESSAGE_MAP()
  114. /////////////////////////////////////////////////////////////////////////////
  115. // CFaderWnd message handlers
  116. void CFaderWnd::OnTimer(UINT nIDEvent)
  117. {
  118. if (m_Blend.SourceConstantAlpha >= ALPHA_STEP)
  119. {
  120. m_Blend.SourceConstantAlpha -= ALPHA_STEP; //减少透明度
  121. m_pUpdateLayeredWindow(GetSafeHwnd(),
  122. NULL,
  123. NULL,
  124. NULL,
  125. NULL,
  126. NULL,
  127. NULL,
  128. &m_Blend,
  129. ULW_ALPHA);
  130. }
  131. else
  132. {
  133. KillTimer(nIDEvent);
  134. DestroyWindow();
  135. }
  136. }
  137. void CFaderWnd::OnSetFocus(CWnd* pOldWnd)
  138. {
  139. if (pOldWnd)
  140. pOldWnd->SetFocus();// When we get the input focus pass it back to the previous holder, if any.
  141. }