MFC渐入渐出框实现方式二

类似360消息弹出框,实现方式一见http://blog.csdn.net/segen_jaa/article/details/7848598

本文采用另外的API实现渐入渐出效果。

主要API:SetLayeredWindowAttributes。

实现功能:

采用管理器控制消息框每次只显示一个。

消息框独立显示在右下角,不随主窗口放大缩小变化。

鼠标进入消息框区域,渐入渐出效果停止。

1、消息框实现

创建对话框类CMsgTipDlg,设置对话框属性。

Tool Window:true。设置对话框为消息框,任务栏上将没有图标。

Topmost:true。设置对话框置顶。

MsgTipDlg.h。

  1. #pragma once
  2. // CMsgTipDlg dialog
  3. class CMsgTipMng;
  4. class CMsgTipDlg : public CDialog
  5. {
  6. DECLARE_DYNAMIC(CMsgTipDlg)
  7. public:
  8. CMsgTipDlg(CMsgTipMng* pTipMng, const CString& strTipInfo, CWnd* pParent = NULL);   // standard constructor
  9. virtual ~CMsgTipDlg();
  10. // Dialog Data
  11. enum { IDD = IDD_MCMSG_DLG };
  12. void ShowMsgWindow();
  13. int GetTipID() const
  14. {
  15. return m_nTipID;
  16. }
  17. protected:
  18. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  19. virtual BOOL OnInitDialog();
  20. virtual void OnCancel();
  21. virtual void PostNcDestroy();
  22. virtual BOOL PreTranslateMessage(MSG* pMsg);
  23. afx_msg void OnTimer(UINT_PTR nIDEvent);
  24. afx_msg void OnBnClickedOk();
  25. afx_msg void OnBnClickedCancel();
  26. afx_msg void OnMouseMove(UINT nFlags, CPoint point);
  27. DECLARE_MESSAGE_MAP()
  28. private:
  29. void InitDlgPosition();
  30. private:
  31. CMsgTipMng* m_pTipMng;
  32. CString m_strTipInfo;
  33. int m_nTipID;
  34. BYTE m_bAlpha;//淡入淡出透明效果
  35. };

MsgTipDlg.cpp。

  1. // MCMsgTipDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "mcmsgtip_demo.h"
  5. #include "MsgTipDlg.h"
  6. #include "MsgTipMng.h"
  7. const UINT_PTR BLAND_IN = 1;
  8. const UINT_PTR DLG_DELAY = 2;
  9. const UINT_PTR BLAND_OUT = 3;
  10. const UINT IN_ELAPSE = 50;
  11. const UINT DELAY_ELAPSE = 5000;
  12. const UINT OUT_ELAPSE = 50;
  13. //淡入淡出跨度
  14. const BYTE BLAND_SPAN = 15;
  15. //淡入淡出最小值
  16. const BYTE BLAND_MIN = 0;
  17. //淡入淡出最大值
  18. const BYTE BLAND_MAX = 255;
  19. //淡入淡出颜色值设置
  20. const COLORREF BLAND_COLOR = 0;
  21. // CMsgTipDlg dialog
  22. IMPLEMENT_DYNAMIC(CMsgTipDlg, CDialog)
  23. CMsgTipDlg::CMsgTipDlg(CMsgTipMng* pTipMng, const CString& strTipInfo, CWnd* pParent)
  24. : CDialog(CMsgTipDlg::IDD, pParent)
  25. , m_pTipMng(pTipMng)
  26. , m_strTipInfo(strTipInfo)
  27. , m_nTipID(0)
  28. , m_bAlpha(0)
  29. {
  30. static int s_nTipID = 0;
  31. ++s_nTipID;
  32. m_nTipID = s_nTipID;
  33. }
  34. CMsgTipDlg::~CMsgTipDlg()
  35. {
  36. }
  37. void CMsgTipDlg::DoDataExchange(CDataExchange* pDX)
  38. {
  39. CDialog::DoDataExchange(pDX);
  40. }
  41. BEGIN_MESSAGE_MAP(CMsgTipDlg, CDialog)
  42. ON_WM_TIMER()
  43. ON_WM_MOUSEMOVE()
  44. ON_BN_CLICKED(IDOK, &CMsgTipDlg::OnBnClickedOk)
  45. ON_BN_CLICKED(IDCANCEL, &CMsgTipDlg::OnBnClickedCancel)
  46. END_MESSAGE_MAP()
  47. // CMsgTipDlg message handlers
  48. void CMsgTipDlg::ShowMsgWindow()
  49. {
  50. HWND hActiveHwnd = ::GetActiveWindow();
  51. Create(IDD, GetDesktopWindow());
  52. ShowWindow(SW_HIDE);
  53. ShowWindow(SW_SHOWNOACTIVATE);
  54. if (hActiveHwnd != NULL)
  55. {
  56. ::SetActiveWindow(hActiveHwnd);
  57. }
  58. }
  59. BOOL CMsgTipDlg::OnInitDialog()
  60. {
  61. CDialog::OnInitDialog();
  62. // TODO:  Add extra initialization here
  63. SetDlgItemText(IDC_TIP_INFO, m_strTipInfo);
  64. InitDlgPosition();
  65. //设置窗口可淡入淡出
  66. ModifyStyleEx(NULL, WS_EX_LAYERED);
  67. //消息渐入渐出效果
  68. SetTimer(BLAND_IN, IN_ELAPSE, NULL);
  69. return TRUE;
  70. }
  71. void CMsgTipDlg::InitDlgPosition()
  72. {
  73. CRect rectInit;
  74. GetWindowRect(&rectInit);
  75. RECT rect;
  76. SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
  77. int cy = rect.bottom-rect.top;
  78. int cx = rect.right-rect.left;
  79. int nx = rect.right - rectInit.Width();
  80. int ny = cy - rectInit.Height();
  81. rectInit.MoveToXY(nx, ny);
  82. MoveWindow(rectInit);
  83. }
  84. void CMsgTipDlg::OnTimer(UINT_PTR nIDEvent)
  85. {
  86. RECT rect;
  87. SystemParametersInfo(SPI_GETWORKAREA,0,&rect,0);
  88. int cy = rect.bottom-rect.top;
  89. int cx = rect.right-rect.left;
  90. CRect rectTip;
  91. GetWindowRect(&rectTip);
  92. switch (nIDEvent)
  93. {
  94. case BLAND_IN:
  95. {
  96. if (m_bAlpha > (BLAND_MAX - BLAND_SPAN))
  97. {
  98. m_bAlpha = BLAND_MAX;
  99. }
  100. else
  101. {
  102. m_bAlpha += BLAND_SPAN;
  103. }
  104. SetLayeredWindowAttributes(BLAND_COLOR, m_bAlpha, LWA_ALPHA);
  105. if (BLAND_MAX == m_bAlpha)
  106. {
  107. KillTimer(BLAND_IN);
  108. SetTimer(DLG_DELAY, DELAY_ELAPSE, NULL);
  109. }
  110. break;
  111. }
  112. case DLG_DELAY:
  113. {
  114. KillTimer(DLG_DELAY);
  115. SetTimer(BLAND_OUT, OUT_ELAPSE, NULL);
  116. break;
  117. }
  118. case BLAND_OUT:
  119. {
  120. if (m_bAlpha < BLAND_SPAN)
  121. {
  122. m_bAlpha = BLAND_MIN;
  123. }
  124. else
  125. {
  126. m_bAlpha -= BLAND_SPAN;
  127. }
  128. SetLayeredWindowAttributes(BLAND_COLOR, m_bAlpha, LWA_ALPHA);
  129. if (BLAND_MIN == m_bAlpha)
  130. {
  131. KillTimer(BLAND_OUT);
  132. PostMessage(WM_CLOSE);
  133. }
  134. break;
  135. }
  136. }
  137. CDialog::OnTimer(nIDEvent);
  138. }
  139. void CMsgTipDlg::OnCancel()
  140. {
  141. DestroyWindow();
  142. }
  143. void CMsgTipDlg::PostNcDestroy()
  144. {
  145. CDialog::PostNcDestroy();
  146. //窗口销毁时,删除该对象
  147. m_pTipMng->RemoveTipWindow(m_nTipID);
  148. }
  149. void CMsgTipDlg::OnBnClickedOk()
  150. {
  151. OnCancel();
  152. //::MessageBox(AfxGetMainWnd()->GetSafeHwnd(), _T("提示框的反馈-是"), _T("提示"), MB_OK);
  153. }
  154. void CMsgTipDlg::OnBnClickedCancel()
  155. {
  156. OnCancel();
  157. }
  158. BOOL CMsgTipDlg::PreTranslateMessage(MSG* pMsg)
  159. {
  160. //对话框屏蔽Enter和ESC键
  161. if (WM_KEYDOWN == pMsg->message)
  162. {
  163. if (    (VK_RETURN == pMsg->wParam)
  164. || (VK_ESCAPE == pMsg->wParam))
  165. {
  166. return TRUE;
  167. }
  168. }
  169. return CDialog::PreTranslateMessage(pMsg);
  170. }
  171. void CMsgTipDlg::OnMouseMove(UINT nFlags, CPoint point)
  172. {
  173. // TODO: Add your message handler code here and/or call default
  174. CRect rect;
  175. GetClientRect(&rect);
  176. //显示对话框
  177. if (m_bAlpha < BLAND_MAX)
  178. {
  179. KillTimer(BLAND_IN);
  180. KillTimer(DLG_DELAY);
  181. KillTimer(BLAND_OUT);
  182. m_bAlpha = BLAND_MAX;
  183. SetLayeredWindowAttributes(BLAND_COLOR, m_bAlpha, LWA_ALPHA);
  184. //继续等待
  185. SetTimer(DLG_DELAY, DELAY_ELAPSE, NULL);
  186. }
  187. CDialog::OnMouseMove(nFlags, point);
  188. }

2、消息框管理器

消息框管理器功能:控制每次只弹出一个消息框。

MsgTipMng.h。

  1. /*
  2. @brief 消息提示管理器
  3. @date 2012-08-10
  4. */
  5. #pragma once
  6. #include "MsgTipDlg.h"
  7. #include <vector>
  8. #include <algorithm>
  9. using namespace std;
  10. class CMsgTipMng
  11. {
  12. public:
  13. CMsgTipMng(void);
  14. ~CMsgTipMng(void);
  15. void AddTipWindow(const CString& strTipInfo);
  16. void RemoveTipWindow(int nTipID);
  17. private:
  18. void ShowTipWindow();
  19. private:
  20. vector<CMsgTipDlg*> m_vTipVct;
  21. bool m_bInShow;//是否有消息框弹出
  22. };

MsgTipMng.cpp。

  1. #include "StdAfx.h"
  2. #include "mcmsgtip_demo.h"
  3. #include "MsgTipMng.h"
  4. class vcttip_finder
  5. {
  6. public:
  7. vcttip_finder(int nTipID)
  8. : m_nTipID(nTipID)
  9. {
  10. }
  11. bool operator()(const CMsgTipDlg* pTipDlg)
  12. {
  13. if (NULL == pTipDlg)
  14. {
  15. return false;
  16. }
  17. int nInTipID = pTipDlg->GetTipID();
  18. return (m_nTipID == nInTipID);
  19. }
  20. private:
  21. int m_nTipID;
  22. };
  23. CMsgTipMng::CMsgTipMng(void)
  24. : m_bInShow(false)
  25. {
  26. }
  27. CMsgTipMng::~CMsgTipMng(void)
  28. {
  29. }
  30. void CMsgTipMng::AddTipWindow(const CString& strTipInfo)
  31. {
  32. m_vTipVct.push_back(new CMsgTipDlg(this, strTipInfo));
  33. ShowTipWindow();
  34. }
  35. void CMsgTipMng::RemoveTipWindow(int nTipID)
  36. {
  37. vector<CMsgTipDlg*>::iterator vIter =
  38. find_if(m_vTipVct.begin(), m_vTipVct.end(), vcttip_finder(nTipID));
  39. if (vIter == m_vTipVct.end())
  40. {
  41. return;
  42. }
  43. m_vTipVct.erase(vIter);
  44. m_bInShow = false;
  45. ShowTipWindow();
  46. }
  47. void CMsgTipMng::ShowTipWindow()
  48. {
  49. if (m_vTipVct.empty())
  50. {
  51. return;
  52. }
  53. if (m_bInShow)
  54. {
  55. return;
  56. }
  57. m_bInShow = true;
  58. m_vTipVct[0]->ShowMsgWindow();
  59. }

3、消息框显示

m_pTipMng为成员变量,类型CMsgTipMng*。

显示对话框:

m_pTipMng->AddTipWindow(_T("Hello World!"));

上一篇:解决Jquery mobile点击较长文本body的时候Header和footer会渐入渐出的问题


下一篇:WinFrm访问MVC数据