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

MsgTipDlg.cpp。

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

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.   
  11. class CMsgTipMng  
  12. {  
  13. public:  
  14.     CMsgTipMng(void);  
  15.     ~CMsgTipMng(void);  
  16.   
  17.     void AddTipWindow(const CString& strTipInfo);  
  18.     void RemoveTipWindow(int nTipID);  
  19.   
  20. private:  
  21.     void ShowTipWindow();  
  22.   
  23. private:  
  24.     vector<CMsgTipDlg*> m_vTipVct;  
  25.   
  26.     bool m_bInShow;//是否有消息框弹出  
  27. };  

MsgTipMng.cpp。

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

3、消息框显示

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

显示对话框:

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

上一篇:C语言-一维指针定义与使用


下一篇:Linux下基于TCP协议的群聊系统设计(多线程+select)