类似360消息弹出框,实现方式一见http://blog.csdn.net/segen_jaa/article/details/7848598。
本文采用另外的API实现渐入渐出效果。
主要API:SetLayeredWindowAttributes。
实现功能:
采用管理器控制消息框每次只显示一个。
消息框独立显示在右下角,不随主窗口放大缩小变化。
鼠标进入消息框区域,渐入渐出效果停止。
1、消息框实现
创建对话框类CMsgTipDlg,设置对话框属性。
Tool Window:true。设置对话框为消息框,任务栏上将没有图标。
Topmost:true。设置对话框置顶。
MsgTipDlg.h。
[cpp] view plaincopy
- #pragma once
- // CMsgTipDlg dialog
- class CMsgTipMng;
- class CMsgTipDlg : public CDialog
- {
- DECLARE_DYNAMIC(CMsgTipDlg)
- public:
- CMsgTipDlg(CMsgTipMng* pTipMng, const CString& strTipInfo, CWnd* pParent = NULL); // standard constructor
- virtual ~CMsgTipDlg();
- // Dialog Data
- enum { IDD = IDD_MCMSG_DLG };
- void ShowMsgWindow();
- int GetTipID() const
- {
- return m_nTipID;
- }
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- virtual BOOL OnInitDialog();
- virtual void OnCancel();
- virtual void PostNcDestroy();
- virtual BOOL PreTranslateMessage(MSG* pMsg);
- afx_msg void OnTimer(UINT_PTR nIDEvent);
- afx_msg void OnBnClickedOk();
- afx_msg void OnBnClickedCancel();
- afx_msg void OnMouseMove(UINT nFlags, CPoint point);
- DECLARE_MESSAGE_MAP()
- private:
- void InitDlgPosition();
- private:
- CMsgTipMng* m_pTipMng;
- CString m_strTipInfo;
- int m_nTipID;
- BYTE m_bAlpha;//淡入淡出透明效果
- };
MsgTipDlg.cpp。
[cpp] view plaincopy
- // MCMsgTipDlg.cpp : implementation file
- //
- #include "stdafx.h"
- #include "mcmsgtip_demo.h"
- #include "MsgTipDlg.h"
- #include "MsgTipMng.h"
- const UINT_PTR BLAND_IN = 1;
- const UINT_PTR DLG_DELAY = 2;
- const UINT_PTR BLAND_OUT = 3;
- const UINT IN_ELAPSE = 50;
- const UINT DELAY_ELAPSE = 5000;
- const UINT OUT_ELAPSE = 50;
- //淡入淡出跨度
- const BYTE BLAND_SPAN = 15;
- //淡入淡出最小值
- const BYTE BLAND_MIN = 0;
- //淡入淡出最大值
- const BYTE BLAND_MAX = 255;
- //淡入淡出颜色值设置
- const COLORREF BLAND_COLOR = 0;
- // CMsgTipDlg dialog
- IMPLEMENT_DYNAMIC(CMsgTipDlg, CDialog)
- CMsgTipDlg::CMsgTipDlg(CMsgTipMng* pTipMng, const CString& strTipInfo, CWnd* pParent)
- : CDialog(CMsgTipDlg::IDD, pParent)
- , m_pTipMng(pTipMng)
- , m_strTipInfo(strTipInfo)
- , m_nTipID(0)
- , m_bAlpha(0)
- {
- static int s_nTipID = 0;
- ++s_nTipID;
- m_nTipID = s_nTipID;
- }
- CMsgTipDlg::~CMsgTipDlg()
- {
- }
- void CMsgTipDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- }
- BEGIN_MESSAGE_MAP(CMsgTipDlg, CDialog)
- ON_WM_TIMER()
- ON_WM_MOUSEMOVE()
- ON_BN_CLICKED(IDOK, &CMsgTipDlg::OnBnClickedOk)
- ON_BN_CLICKED(IDCANCEL, &CMsgTipDlg::OnBnClickedCancel)
- END_MESSAGE_MAP()
- // CMsgTipDlg message handlers
- void CMsgTipDlg::ShowMsgWindow()
- {
- HWND hActiveHwnd = ::GetActiveWindow();
- Create(IDD, GetDesktopWindow());
- ShowWindow(SW_HIDE);
- ShowWindow(SW_SHOWNOACTIVATE);
- if (hActiveHwnd != NULL)
- {
- ::SetActiveWindow(hActiveHwnd);
- }
- }
- BOOL CMsgTipDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- // TODO: Add extra initialization here
- SetDlgItemText(IDC_TIP_INFO, m_strTipInfo);
- InitDlgPosition();
- //设置窗口可淡入淡出
- ModifyStyleEx(NULL, WS_EX_LAYERED);
- //消息渐入渐出效果
- SetTimer(BLAND_IN, IN_ELAPSE, NULL);
- return TRUE;
- }
- void CMsgTipDlg::InitDlgPosition()
- {
- CRect rectInit;
- GetWindowRect(&rectInit);
- RECT rect;
- SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
- int cy = rect.bottom-rect.top;
- int cx = rect.right-rect.left;
- int nx = rect.right - rectInit.Width();
- int ny = cy - rectInit.Height();
- rectInit.MoveToXY(nx, ny);
- MoveWindow(rectInit);
- }
- void CMsgTipDlg::OnTimer(UINT_PTR nIDEvent)
- {
- RECT rect;
- SystemParametersInfo(SPI_GETWORKAREA,0,&rect,0);
- int cy = rect.bottom-rect.top;
- int cx = rect.right-rect.left;
- CRect rectTip;
- GetWindowRect(&rectTip);
- switch (nIDEvent)
- {
- case BLAND_IN:
- {
- if (m_bAlpha > (BLAND_MAX - BLAND_SPAN))
- {
- m_bAlpha = BLAND_MAX;
- }
- else
- {
- m_bAlpha += BLAND_SPAN;
- }
- SetLayeredWindowAttributes(BLAND_COLOR, m_bAlpha, LWA_ALPHA);
- if (BLAND_MAX == m_bAlpha)
- {
- KillTimer(BLAND_IN);
- SetTimer(DLG_DELAY, DELAY_ELAPSE, NULL);
- }
- break;
- }
- case DLG_DELAY:
- {
- KillTimer(DLG_DELAY);
- SetTimer(BLAND_OUT, OUT_ELAPSE, NULL);
- break;
- }
- case BLAND_OUT:
- {
- if (m_bAlpha < BLAND_SPAN)
- {
- m_bAlpha = BLAND_MIN;
- }
- else
- {
- m_bAlpha -= BLAND_SPAN;
- }
- SetLayeredWindowAttributes(BLAND_COLOR, m_bAlpha, LWA_ALPHA);
- if (BLAND_MIN == m_bAlpha)
- {
- KillTimer(BLAND_OUT);
- PostMessage(WM_CLOSE);
- }
- break;
- }
- }
- CDialog::OnTimer(nIDEvent);
- }
- void CMsgTipDlg::OnCancel()
- {
- DestroyWindow();
- }
- void CMsgTipDlg::PostNcDestroy()
- {
- CDialog::PostNcDestroy();
- //窗口销毁时,删除该对象
- m_pTipMng->RemoveTipWindow(m_nTipID);
- }
- void CMsgTipDlg::OnBnClickedOk()
- {
- OnCancel();
- //::MessageBox(AfxGetMainWnd()->GetSafeHwnd(), _T("提示框的反馈-是"), _T("提示"), MB_OK);
- }
- void CMsgTipDlg::OnBnClickedCancel()
- {
- OnCancel();
- }
- BOOL CMsgTipDlg::PreTranslateMessage(MSG* pMsg)
- {
- //对话框屏蔽Enter和ESC键
- if (WM_KEYDOWN == pMsg->message)
- {
- if ( (VK_RETURN == pMsg->wParam)
- || (VK_ESCAPE == pMsg->wParam))
- {
- return TRUE;
- }
- }
- return CDialog::PreTranslateMessage(pMsg);
- }
- void CMsgTipDlg::OnMouseMove(UINT nFlags, CPoint point)
- {
- // TODO: Add your message handler code here and/or call default
- CRect rect;
- GetClientRect(&rect);
- //显示对话框
- if (m_bAlpha < BLAND_MAX)
- {
- KillTimer(BLAND_IN);
- KillTimer(DLG_DELAY);
- KillTimer(BLAND_OUT);
- m_bAlpha = BLAND_MAX;
- SetLayeredWindowAttributes(BLAND_COLOR, m_bAlpha, LWA_ALPHA);
- //继续等待
- SetTimer(DLG_DELAY, DELAY_ELAPSE, NULL);
- }
- CDialog::OnMouseMove(nFlags, point);
- }
2、消息框管理器
消息框管理器功能:控制每次只弹出一个消息框。
MsgTipMng.h。
[cpp] view plaincopy
- /*
- @brief 消息提示管理器
- @date 2012-08-10
- */
- #pragma once
- #include "MsgTipDlg.h"
- #include <vector>
- #include <algorithm>
- using namespace std;
- class CMsgTipMng
- {
- public:
- CMsgTipMng(void);
- ~CMsgTipMng(void);
- void AddTipWindow(const CString& strTipInfo);
- void RemoveTipWindow(int nTipID);
- private:
- void ShowTipWindow();
- private:
- vector<CMsgTipDlg*> m_vTipVct;
- bool m_bInShow;//是否有消息框弹出
- };
MsgTipMng.cpp。
[cpp] view plaincopy
- #include "StdAfx.h"
- #include "mcmsgtip_demo.h"
- #include "MsgTipMng.h"
- class vcttip_finder
- {
- public:
- vcttip_finder(int nTipID)
- : m_nTipID(nTipID)
- {
- }
- bool operator()(const CMsgTipDlg* pTipDlg)
- {
- if (NULL == pTipDlg)
- {
- return false;
- }
- int nInTipID = pTipDlg->GetTipID();
- return (m_nTipID == nInTipID);
- }
- private:
- int m_nTipID;
- };
- CMsgTipMng::CMsgTipMng(void)
- : m_bInShow(false)
- {
- }
- CMsgTipMng::~CMsgTipMng(void)
- {
- }
- void CMsgTipMng::AddTipWindow(const CString& strTipInfo)
- {
- m_vTipVct.push_back(new CMsgTipDlg(this, strTipInfo));
- ShowTipWindow();
- }
- void CMsgTipMng::RemoveTipWindow(int nTipID)
- {
- vector<CMsgTipDlg*>::iterator vIter =
- find_if(m_vTipVct.begin(), m_vTipVct.end(), vcttip_finder(nTipID));
- if (vIter == m_vTipVct.end())
- {
- return;
- }
- m_vTipVct.erase(vIter);
- m_bInShow = false;
- ShowTipWindow();
- }
- void CMsgTipMng::ShowTipWindow()
- {
- if (m_vTipVct.empty())
- {
- return;
- }
- if (m_bInShow)
- {
- return;
- }
- m_bInShow = true;
- m_vTipVct[0]->ShowMsgWindow();
- }
3、消息框显示
m_pTipMng为成员变量,类型CMsgTipMng*。
显示对话框:
m_pTipMng->AddTipWindow(_T("Hello World!"));