www.pudn.com > tabandSplitter.rar > StatusBarMsgWnd.cpp


/******************************************************************************* 
File:        StatusBarMsgWnd.cpp 
********************************************************************************/ 
 
#include "stdafx.h" 
 
#include "StatusBarMsgWnd.h" 
#include  
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
/*---------------------------------------------------------------------------- 
 Message map 
----------------------------------------------------------------------------*/ 
 
BEGIN_MESSAGE_MAP(CStatusBarMsgWnd, CFrameWnd) 
    ON_WM_SIZE() 
    ON_WM_CREATE() 
    ON_WM_MOUSEMOVE() 
    ON_WM_TIMER() 
    ON_WM_SETCURSOR() 
    ON_WM_DESTROY() 
    ON_WM_PAINT() 
    ON_WM_LBUTTONDOWN() 
    ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave) 
    ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover) 
END_MESSAGE_MAP() 
 
 
 
/*----------------------------------------------------------------------------- 
 Function : CStatusBarMsgWnd::CStatusBarMsgWnd() 
 
 Parameters :  
    1. strMsg     -> Message to be shown in the window 
    2. nWndWidth  -> Width of the message window 
    3. nWndHeight -> Height if the message window 
    4. nMsgTimeOut -> Seconds the window remains stationary 
    5. nMsgWndCreationDelay -> Seconds in which the window gets shown 
    4. pParent    -> Pointer to the parent window 
    5  rectMsgRect -> Rectangle in the window where the message will be 
 
 Return Value : none 
 
 Exceptions : none 
 
 Revisions : none 
----------------------------------------------------------------------------*/ 
 
CStatusBarMsgWnd::CStatusBarMsgWnd( 
                      CString strMsg,  
                      unsigned int nWndWidth, 
                      unsigned int nWndHeight, 
                      unsigned int nMsgTimeOut,          
                      unsigned int nMsgWndCreationDelay,  
                      CRect rectMsgRect, 
                      CWnd* pWndParent) : m_strMsg(strMsg), m_rectMsgRect(rectMsgRect) 
{ 
    m_nWndWidth  = nWndWidth; 
    m_nWndHeight = nWndHeight; 
 
    m_pWndParent = pWndParent; 
 
    m_nMsgTimeOut          = nMsgTimeOut; 
    m_nMsgWndCreationDelay = nMsgWndCreationDelay; 
 
    m_bMouseOverWnd = FALSE; 
 
    m_hCursor = NULL; 
} 
 
CStatusBarMsgWnd::~CStatusBarMsgWnd() 
{ 
} 
 
void CStatusBarMsgWnd::PopWndForLeftStatusBar() 
{ 
    CRect t_rect(0, 0, 0, 0); 
    Create(NULL, NULL, WS_VISIBLE | WS_OVERLAPPEDWINDOW, t_rect, m_pWndParent); 
     
    CRect rectDesktopWithoutTaskbar;   // The desktop area  
 
    // Get the desktop area 
    ::SystemParametersInfo(SPI_GETWORKAREA, 0, &rectDesktopWithoutTaskbar, 0); 
     
    // Calculate the actual width of the Window and its position 
    m_nWndLeft   = rectDesktopWithoutTaskbar.left; 
    m_nWndTop    = rectDesktopWithoutTaskbar.bottom - m_nWndHeight; 
    m_nWndRight  = m_nWndLeft + m_nWndWidth; 
    m_nWndBottom = m_nWndTop + m_nWndHeight; 
     
    m_nWndSize = 0; // The height of window is zero before showing 
 
    SetTimer(IDT_POP_WINDOW_TIMER, m_nMsgWndCreationDelay, NULL); 
 
} 
 
 
void CStatusBarMsgWnd::PopWndForRightStatusBar() 
{ 
    PopWndForBottomStatusBar(); 
} 
 
void CStatusBarMsgWnd::PopWndForTopStatusBar() 
{ 
    CRect t_rect(0, 0, 0, 0); 
    Create(NULL, NULL, WS_VISIBLE | WS_OVERLAPPEDWINDOW, t_rect, m_pWndParent); 
     
    CRect rectDesktopWithoutTaskbar;   // The desktop area  
 
    // Get the desktop area 
    ::SystemParametersInfo(SPI_GETWORKAREA, 0, &rectDesktopWithoutTaskbar, 0); 
     
    // Calculate the actual width of the Window and its position in screen co-ordinates 
    m_nWndLeft   = rectDesktopWithoutTaskbar.right - m_nWndWidth; 
    m_nWndTop    = rectDesktopWithoutTaskbar.top; 
    m_nWndRight  = m_nWndLeft + m_nWndWidth; 
    m_nWndBottom = m_nWndTop + m_nWndHeight; 
 
    m_nWndSize = 0; // The height of window is zero before showing 
 
    SetTimer(IDT_POP_WINDOW_TIMER, m_nMsgWndCreationDelay, NULL); 
} 
 
void CStatusBarMsgWnd::PopWndForBottomStatusBar() 
{ 
    CRect t_rect(0, 0, 0, 0); 
     
    Create(NULL, NULL, WS_VISIBLE | WS_OVERLAPPEDWINDOW, t_rect, m_pWndParent);  
     
    CRect rectDesktopWithoutTaskbar;   // The desktop area  
 
    // Get the desktop area 
    ::SystemParametersInfo(SPI_GETWORKAREA, 0, &rectDesktopWithoutTaskbar, 0); 
     
    // Calculate the actual width of the Window and its position in screen co-ordinates 
    m_nWndLeft   = rectDesktopWithoutTaskbar.right - m_nWndWidth; 
    m_nWndTop    = rectDesktopWithoutTaskbar.bottom - m_nWndHeight; 
    m_nWndRight  = m_nWndLeft + m_nWndWidth; 
    m_nWndBottom = m_nWndTop + m_nWndHeight; 
     
    m_nWndSize = 0; // The height of window is zero before showing 
 
    SetTimer(IDT_POP_WINDOW_TIMER, m_nMsgWndCreationDelay, NULL); 
} 
 
 
void CStatusBarMsgWnd::PopMsg() 
{ 
	PlaySound("alarm.wav",NULL,SND_FILENAME); 
    if (CheckIfStatusBarBottom())  // Most frequent case is status bar at bottom 
    { 
        PopWndForBottomStatusBar(); 
    } 
    else 
    { 
        if (CheckIfStatusBarTop()) 
        { 
            PopWndForTopStatusBar(); 
        } 
        else 
        { 
            if (CheckIfStatusBarLeft()) 
            { 
                PopWndForLeftStatusBar(); 
            } 
            else 
            { 
                m_nStatusBarPos = STP_RIGHT; // Force it, as no need for calling "CheckIfStatusBarRight() 
                PopWndForRightStatusBar(); 
            } 
        } 
    } 
} 
 
 
BOOL CStatusBarMsgWnd::CheckIfStatusBarLeft() 
{ 
    unsigned int nAvailableScreenTop; 
    unsigned int nAvailableScreenLeft; 
     
    CRect rectDesktopWithoutTaskbar;   // The desktop area without status bar 
     
    // Get the desktop area minus the status 
    ::SystemParametersInfo(SPI_GETWORKAREA, 0, &rectDesktopWithoutTaskbar, 0); 
    nAvailableScreenLeft  = rectDesktopWithoutTaskbar.left; 
    nAvailableScreenTop = rectDesktopWithoutTaskbar.top; 
 
    if ((nAvailableScreenLeft > 0) && (nAvailableScreenTop == 0)) 
    { 
        m_nStatusBarPos = STP_LEFT; 
        return TRUE; 
    } 
    else 
    { 
        return FALSE; 
    } 
} 
 
 
BOOL CStatusBarMsgWnd::CheckIfStatusBarRight() 
{ 
    unsigned int nAvailableScreenWidth; 
    unsigned int nAvailableScreenHeight; 
    unsigned int nActualScreenWidth; 
    unsigned int nActualScreenHeight; 
 
    // Calculate the actual screen height and width 
    nActualScreenWidth  = ::GetSystemMetrics(SM_CXFULLSCREEN); 
    nActualScreenHeight = ::GetSystemMetrics(SM_CYFULLSCREEN); 
 
   
    CRect rectDesktopWithoutTaskbar;   // The desktop area without status bar 
     
    // Get the desktop area minus the status 
    ::SystemParametersInfo(SPI_GETWORKAREA, 0, &rectDesktopWithoutTaskbar, 0); 
    nAvailableScreenWidth  = rectDesktopWithoutTaskbar.Width(); 
    nAvailableScreenHeight = rectDesktopWithoutTaskbar.Height(); 
 
    if ((nAvailableScreenWidth != nActualScreenWidth) && 
        (nAvailableScreenHeight == nActualScreenHeight)) 
    { 
        m_nStatusBarPos = STP_RIGHT; 
        return TRUE; 
    } 
    else 
    { 
        return FALSE; 
    } 
} 
 
BOOL CStatusBarMsgWnd::CheckIfStatusBarTop() 
{ 
    unsigned int nAvailableScreenTop; 
    unsigned int nAvailableScreenLeft; 
     
    CRect rectDesktopWithoutTaskbar;   // The desktop area without status bar 
     
    // Get the desktop area minus the status 
    ::SystemParametersInfo(SPI_GETWORKAREA, 0, &rectDesktopWithoutTaskbar, 0); 
    nAvailableScreenLeft  = rectDesktopWithoutTaskbar.left; 
    nAvailableScreenTop = rectDesktopWithoutTaskbar.top; 
 
    if ((nAvailableScreenLeft == 0) && (nAvailableScreenTop > 0)) 
    { 
        m_nStatusBarPos = STP_TOP; 
        return TRUE; 
    } 
    else 
    { 
        return FALSE; 
    } 
} 
BOOL CStatusBarMsgWnd::CheckIfStatusBarBottom() 
{ 
    unsigned int nAvailableScreenWidth; 
    unsigned int nAvailableScreenBottom; 
    unsigned int nActualScreenWidth; 
    unsigned int nActualScreenBottom; 
 
    // Calculate the actual screen height and width 
    nActualScreenWidth  = ::GetSystemMetrics(SM_CXSCREEN); 
    nActualScreenBottom = ::GetSystemMetrics(SM_CYSCREEN); 
 
   
    CRect rectDesktopWithoutTaskbar;   // The desktop area without status bar 
     
    // Get the desktop area minus the status 
    ::SystemParametersInfo(SPI_GETWORKAREA, 0, &rectDesktopWithoutTaskbar, 0); 
    nAvailableScreenWidth  = rectDesktopWithoutTaskbar.Width(); 
    nAvailableScreenBottom = rectDesktopWithoutTaskbar.bottom; 
 
    if ((nAvailableScreenWidth == nActualScreenWidth) && 
        (nAvailableScreenBottom < nActualScreenBottom)) 
    { 
        m_nStatusBarPos = STP_BOTTOM; 
        return TRUE; 
    } 
    else 
    { 
        return FALSE; 
    } 
} 
 
 
void CStatusBarMsgWnd::OnSize(unsigned int nType, int cx, int cy) 
{ 
    CFrameWnd::OnSize(nType, cx, cy); 
 
    //SendMessage(WM_MOUSEMOVE, 0); 
    CFont* pFont = NULL; 
    CClientDC dc(this); 
 
    if (m_bMouseOverWnd) 
    { 
        pFont = dc.SelectObject(&m_fontMessageUnderline); 
    } 
    else 
    { 
        pFont = dc.SelectObject(&m_fontMessageNoUnderline); 
    } 
 
    // Show with the message with the new font 
    dc.DrawText(m_strMsg, &m_rectMsgRect, DT_WORDBREAK | DT_CENTER); 
    dc.SelectObject(pFont); 
 
    //dc.DrawText(m_strMsg, &m_rectMsgRect, DT_WORDBREAK | DT_CENTER); 
} 
 
 
int CStatusBarMsgWnd::OnCreate( LPCREATESTRUCT lpCreateStruct ) 
{ 
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1) 
		return -1; 
 
	ModifyStyle(WS_CAPTION, 0, SWP_FRAMECHANGED); // removes title bar 
     
    // Start creating two fonts, one underlined , other non underlined 
    // 
    // LOGFONT structure for font properties 
    LOGFONT lf; 
    ::ZeroMemory (&lf, sizeof (lf)); 
    lf.lfHeight = 100; 
    lf.lfWeight = FW_BOLD; 
    lf.lfUnderline = TRUE; 
 
    ::strcpy (lf.lfFaceName, _T("Arial")); 
 
    // Prepare for an underlined font 
    m_fontMessageUnderline.CreatePointFontIndirect(&lf); 
 
    // Prepare  an non undelined font 
    lf.lfUnderline = FALSE; 
    m_fontMessageNoUnderline.CreatePointFontIndirect(&lf); 
 
    // Initialize the cursor. 
    m_hCursor = ::LoadCursor(NULL, IDC_ARROW); // Use IDC_HAND if it compiles 
    	 
    return 0; 
} 
 
void CStatusBarMsgWnd::OnMouseMove(UINT nFlags, CPoint point) 
{ 
    // Register the tracking of Mouse entering and leaveing the window 
    // for WM_MOUSEHOVER and WM_MOUSELEAVE 
    TRACKMOUSEEVENT t_MouseEvent; 
    t_MouseEvent.cbSize      = sizeof(TRACKMOUSEEVENT); 
    t_MouseEvent.dwFlags     = TME_LEAVE | TME_HOVER; 
    t_MouseEvent.hwndTrack   = m_hWnd; 
    t_MouseEvent.dwHoverTime = 1; 
 
    ::_TrackMouseEvent(&t_MouseEvent); 
} 
 
 
void CStatusBarMsgWnd::OnTimer(UINT nIDEvent) 
{ 
    switch (nIDEvent) 
    { 
        case IDT_POP_WINDOW_TIMER:    // When the window comes up 
        { 
            switch (m_nStatusBarPos) 
            { 
                case STP_BOTTOM: 
                case STP_RIGHT: 
                { 
                    ++m_nWndSize; 
                    if (m_nWndSize > m_nWndHeight) 
                    { 
                        KillTimer(IDT_POP_WINDOW_TIMER); 
                        SetTimer(IDT_SHOW_WINDOW_TIMER, m_nMsgTimeOut, NULL); 
                    } 
                    else 
                    { 
                        // Keep sizing the window, show it 
                        SetWindowPos( 
                            &wndTopMost, 
                            m_nWndLeft, 
                            m_nWndBottom - m_nWndSize -5,  
                            m_nWndWidth - 10, 
                            m_nWndSize, 
                            SWP_SHOWWINDOW 
                        ); 
                    } 
                } 
                break; 
 
                case STP_TOP: 
                { 
                    ++m_nWndSize; 
                    if (m_nWndSize > m_nWndHeight) 
                    { 
                        KillTimer(IDT_POP_WINDOW_TIMER); 
                        SetTimer(IDT_SHOW_WINDOW_TIMER, m_nMsgTimeOut, NULL); 
                    } 
                    else 
                    { 
                        // Keep sizing the window, collapse it 
                        SetWindowPos( 
                            &wndTopMost, 
                            m_nWndLeft, 
                            m_nWndTop,  
                            m_nWndWidth - 10, 
                            m_nWndSize, 
                            SWP_SHOWWINDOW 
                        ); 
                    } 
                } 
                break; 
 
                case STP_LEFT: 
                { 
                    ++m_nWndSize; 
                    if (m_nWndSize > m_nWndHeight) 
                    { 
                        KillTimer(IDT_POP_WINDOW_TIMER); 
                        SetTimer(IDT_SHOW_WINDOW_TIMER, m_nMsgTimeOut, NULL); 
                    } 
                    else 
                    { 
                        // Keep sizing the window, collpase it 
                        SetWindowPos( 
                            &wndTopMost, 
                            m_nWndLeft + 10, 
                            m_nWndBottom - m_nWndSize - 5,  
                            m_nWndWidth, 
                            m_nWndSize, 
                            SWP_SHOWWINDOW 
                        ); 
                    } 
                } 
                break; 
            } 
        } 
        break; 
 
        case IDT_SHOW_WINDOW_TIMER: 
        { 
            KillTimer(IDT_SHOW_WINDOW_TIMER); 
            SetTimer(IDT_COLLAPSE_WINDOW_TIMER, m_nMsgWndCreationDelay, NULL); 
        } 
        break; 
 
        case IDT_COLLAPSE_WINDOW_TIMER: 
        { 
            switch (m_nStatusBarPos) 
            { 
                case STP_BOTTOM: 
                case STP_RIGHT: 
                { 
                    --m_nWndSize; 
                    if (m_nWndSize <= 0)  
                    { 
                        KillTimer(IDT_COLLAPSE_WINDOW_TIMER); 
                        m_nWndSize = 0; 
 
                        delete this; 
                    } 
                    else 
                    { 
                        // Keep showing the window, collapse it 
                        SetWindowPos( 
                            &wndTopMost, 
                            m_nWndLeft, 
                            m_nWndBottom - m_nWndSize - 5,  
                            m_nWndWidth - 10, 
                            m_nWndSize, 
                            SWP_SHOWWINDOW 
                        );       
                    } 
                } 
                break; 
 
                case STP_TOP: 
                { 
                    --m_nWndSize; 
                    if (m_nWndSize <= 0) 
                    { 
                        KillTimer(IDT_COLLAPSE_WINDOW_TIMER); 
                        m_nWndSize = 0; 
 
                        delete this; 
                    } 
                    else 
                    { 
                        SetWindowPos( 
                            &wndTopMost, 
                            m_nWndLeft, 
                            m_nWndTop,  
                            m_nWndWidth - 10, 
                            m_nWndSize, 
                            SWP_SHOWWINDOW 
                        ); 
                    } 
                } 
                break; 
 
                case STP_LEFT: 
                { 
                    --m_nWndSize; 
                    if (m_nWndSize <= 0) 
                    { 
                        KillTimer(IDT_COLLAPSE_WINDOW_TIMER); 
                        m_nWndSize = 0; 
 
                        delete this; 
                    } 
                    else 
                    { 
                        SetWindowPos( 
                            &wndTopMost, 
                            m_nWndLeft + 10, 
                            m_nWndBottom - m_nWndSize - 5,  
                            m_nWndWidth, 
                            m_nWndSize, 
                            SWP_SHOWWINDOW 
                        ); 
                    } 
                } 
                break; 
            } 
        } 
        break; 
    } 
 
} 
 
 
 
LRESULT CStatusBarMsgWnd::OnMouseHover(WPARAM w, LPARAM l) 
{ 
    if (m_bMouseOverWnd == FALSE) // Mouse was not on window 
    { 
        CClientDC dc(this); 
        CFont* pFont = dc.SelectObject(&m_fontMessageUnderline); 
 
        // Show with the message with the new font 
        dc.DrawText(m_strMsg, &m_rectMsgRect, DT_WORDBREAK | DT_CENTER); 
         
        dc.SelectObject(pFont); // restore the DC to its original state 
 
        m_bMouseOverWnd = TRUE; // Mouse is now over window 
    } 
    return 0; 
} 
 
 
 
LRESULT CStatusBarMsgWnd::OnMouseLeave(WPARAM w, LPARAM l) 
{ 
    if (m_bMouseOverWnd) // Mouse was over window, now it is leaving 
    { 
        CClientDC dc(this); 
        CFont* pFont = dc.SelectObject(&m_fontMessageNoUnderline); 
 
        // Show with the message with the new font 
        dc.DrawText(m_strMsg, &m_rectMsgRect, DT_WORDBREAK | DT_CENTER); 
 
        dc.SelectObject(pFont); // Restore DC back to its original state 
 
        m_bMouseOverWnd = FALSE; // Mouse is not over window 
    } 
    return 0; 
} 
 
 
BOOL CStatusBarMsgWnd::OnSetCursor(CWnd* pWnd , UINT nHitTest , UINT message) 
{ 
    if (nHitTest == HTCLIENT) 
    { 
        ::SetCursor(m_hCursor);  // Set cursor to HAND type when mouse is over window 
 
        return TRUE; 
    } 
     
    return CFrameWnd::OnSetCursor (pWnd, nHitTest, message); 
} 
 
 
void CStatusBarMsgWnd::OnDestroy(void) 
{ 
    ::CloseHandle(m_hCursor); // Free the cursor as it is a shared resource.. 
 
    CFrameWnd::OnDestroy(); 
} 
 
void CStatusBarMsgWnd::OnPaint() 
{ 
    CFont* pFont = NULL; 
    CPaintDC dc(this); 
	COLORREF clrOld = dc.GetTextColor(); 
 
    if (m_bMouseOverWnd) 
    { 
        pFont = dc.SelectObject(&m_fontMessageUnderline); 
		dc.SetTextColor(RGB(255,0,0)); 
    } 
    else 
    { 
        pFont = dc.SelectObject(&m_fontMessageNoUnderline); 
    } 
 
    // Show with the message with the new font 
    dc.DrawText(m_strMsg, &m_rectMsgRect, DT_WORDBREAK | DT_CENTER); 
    dc.SelectObject(pFont); // restore the DC to its original state 
	dc.SetTextColor(clrOld); 
} 
 
 
void CStatusBarMsgWnd::OnLButtonDown(UINT nFlags, CPoint point) 
{ 
    ::AfxMessageBox(_T("您已接受消息了!")); 
} 
 
 
 
 
/*----------------------------------------------------------------------------- 
 Function : CStatusBarMsgWnd::CreateObject() 
 
 Abstract : Creates an CStatusBarMsgWnd, constructor is not public because we 
            want to force heap creation for better response for the 
            parent window. So we use SetTimer in PopWnd() and return.  
            So no blocking with Sleep() API. 
 
 Parameters :  
    1. strMsg     -> Message to be shown in the window 
    2. nWndWidth  -> Width of the message window 
    3. nWndHeight -> Height if the message window 
    4. nMsgTimeOut -> Seconds the window remains stationary 
    5. nMsgWndCreationDelay -> Seconds in which the window gets shown 
    4. pParent    -> Pointer to the parent window 
    5  rectMsgRect -> Rectangle in the window where the message will be 
 
 Return Value : none 
 
 Exceptions : none 
 
 Revisions : none 
----------------------------------------------------------------------------*/ 
 
CStatusBarMsgWnd* CStatusBarMsgWnd::CreateObject(CString strMsg, 
                                       unsigned int nWndWidth, 
                                       unsigned int nWndHeight,  
                                       unsigned int nMsgTimeOut,          
                                       unsigned int nMsgWndCreationDelay,  
                                       CRect rectMsgRect, 
                                       CWnd* pWndParent) 
{ 
    CStatusBarMsgWnd* t_StatusBarMsgWnd = new CStatusBarMsgWnd( 
                                                  strMsg, 
                                                  nWndWidth, 
                                                  nWndHeight,  
                                                  nMsgTimeOut,          
                                                  nMsgWndCreationDelay,  
                                                  rectMsgRect, 
                                                  pWndParent 
                                              ); 
 
    return (t_StatusBarMsgWnd); 
}