程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> MFC漸入漸出框實現方式

MFC漸入漸出框實現方式

編輯:C++入門知識

本文采用另外的API實現漸入漸出效果。

主要API:SetLayeredWindowAttributes。


實現功能:

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

消息框獨立顯示在右下角,不隨主窗口放大縮小變化。

鼠標進入消息框區域,漸入漸出效果停止。


1、消息框實現

創建對話框類CMsgTipDlg,設置對話框屬性。

Tool Window:true。設置對話框為消息框,任務欄上將沒有圖標。

Topmost:true。設置對話框置頂。


MsgTipDlg.h。

[cpp]
#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] 
// 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]
/*
@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]
#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!"));

 作者:segen_jaa

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved