// MsgWnd.cpp #include "stdafx.h" #include "MsgWnd.h" #include "HandCursor.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[]=__FILE__; #endif #define IDT_WINDOW_TIMER_1 100 #define IDT_WINDOW_TIMER_2 101 #define IDT_WINDOW_TIMER_3 102 IMPLEMENT_DYNAMIC(CMsgWnd, CWnd) BEGIN_MESSAGE_MAP(CMsgWnd, CWnd) //{{AFX_MSG_MAP(CMsgWnd) ON_WM_PAINT() ON_WM_TIMER() ON_WM_MOUSEMOVE() ON_WM_ERASEBKGND() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() //}}AFX_MSG_MAP END_MESSAGE_MAP() CMsgWnd::CMsgWnd() : LButtonDown(false), MouseOver(false), ShowTime(4000), Size(148,120) { NONCLIENTMETRICS ncm; ncm.cbSize=sizeof(NONCLIENTMETRICS); SystemParametersInfo(SPI_GETNONCLIENTMETRICS,0,&ncm,0); Font.CreateFontIndirect(&ncm.lfStatusFont); ncm.lfStatusFont.lfUnderline=TRUE; UFont.CreateFontIndirect(&ncm.lfStatusFont); Create(CPoint(0,0), NULL, 0); Cursor=HandCursor; } BOOL CMsgWnd::PreCreateWindow(CREATESTRUCT& cs) { static CString sClassName(AfxRegisterWndClass(0)); cs.lpszClass=sClassName; cs.style=WS_POPUP|WS_BORDER; cs.dwExStyle|=WS_EX_TOOLWINDOW; return CWnd::PreCreateWindow(cs); } BOOL CMsgWnd::Create(CPoint pt, CWnd* pParentWnd, UINT nID) { BOOL Return=CreateEx(0, NULL, NULL, WS_POPUP|WS_VISIBLE, CRect(pt,CSize(0,0)), pParentWnd, nID); CRect Rect(0,0,53,51); AC.Create(WS_CHILD|WS_VISIBLE|ACS_CENTER|ACS_AUTOPLAY, Rect, this, 0); return Return; } // Show window with delay. No delay means show now. void CMsgWnd::ShowDelayed(UINT msec) { Cancel(); CRect DesktopRect; ::SystemParametersInfo(SPI_GETWORKAREA, 0, &DesktopRect, 0); if(DesktopRect.Height()!=::GetSystemMetrics(SM_CYSCREEN)) { //Taskbar is horizontal Rect.right=DesktopRect.right-10; Rect.left=Rect.right-Size.cx; if(DesktopRect.top) { //Taskbar is at Top UDLR='D'; Rect.top=Rect.bottom=DesktopRect.top; }else{ //Taskbar is at Bottom UDLR='U'; Rect.top=Rect.bottom=DesktopRect.bottom; } }else{ //Taskbar is vertical Rect.bottom=DesktopRect.bottom-10; Rect.top=Rect.bottom-Size.cy; if(DesktopRect.left) { //Taskbar is on the Left UDLR='R'; Rect.left=Rect.right=DesktopRect.left; }else{ //Taskbar is on the Right UDLR='L'; Rect.left=Rect.right=DesktopRect.right; } } if(msec) SetTimer(IDT_WINDOW_TIMER_1, msec, NULL); // delay: set time else OnTimer(IDT_WINDOW_TIMER_1); // no delay: show it now } void CMsgWnd::OnTimer(UINT nIDEvent) { switch(nIDEvent) { case IDT_WINDOW_TIMER_1: { // When the window comes up switch(UDLR) { case 'U': --Rect.top ; break; case 'D': ++Rect.bottom; break; case 'L': --Rect.left ; break; case 'R': ++Rect.right ; break; } if(Rect.Width()==1 || Rect.Height()==1) { KillTimer(IDT_WINDOW_TIMER_1); SetTimer(IDT_WINDOW_TIMER_1, 10, NULL); SetWindowPos(&wndTopMost, Rect.left, Rect.top, Rect.Width(), Rect.Height(), SWP_SHOWWINDOW|SWP_NOACTIVATE); }else if(Rect.Width()==Size.cx && Rect.Height()==Size.cy) { KillTimer(IDT_WINDOW_TIMER_1); SetTimer(IDT_WINDOW_TIMER_2, ShowTime, NULL); }else SetWindowPos(0, Rect.left, Rect.top, Rect.Width(), Rect.Height(), SWP_NOZORDER|SWP_NOACTIVATE); return; } case IDT_WINDOW_TIMER_2: { KillTimer(IDT_WINDOW_TIMER_2); SetTimer(IDT_WINDOW_TIMER_3, 10, NULL); return; } case IDT_WINDOW_TIMER_3: { switch(UDLR) { case 'U': ++Rect.top ; break; case 'D': --Rect.bottom; break; case 'L': ++Rect.left ; break; case 'R': --Rect.right ; break; } if(!Rect.Width() || !Rect.Height()) Cancel(); else SetWindowPos(0, Rect.left, Rect.top, Rect.Width(), Rect.Height(), SWP_NOZORDER|SWP_NOACTIVATE); return; } } } BOOL CMsgWnd::OnEraseBkgnd(CDC* pDC) {return true;}//CWnd::OnEraseBkgnd(pDC); void CMsgWnd::OnPaint() { CPaintDC dc(this); CFont* OldFont=dc.SelectObject(MouseOver ? &UFont : &Font); dc.FillSolidRect(&dc.m_ps.rcPaint, GetSysColor(COLOR_INFOBK)); dc.SetBkMode(TRANSPARENT); dc.SetTextColor(MouseOver ? GetSysColor(COLOR_INFOTEXT)^0xFF0000 : GetSysColor(COLOR_INFOTEXT)); CString S; GetWindowText(S); dc.DrawText(S, &CRect(8, 70, 140, 100), DT_WORDBREAK|DT_CENTER); dc.SelectObject(OldFont); } void CMsgWnd::Cancel() { KillTimer(IDT_WINDOW_TIMER_1); KillTimer(IDT_WINDOW_TIMER_2); KillTimer(IDT_WINDOW_TIMER_3); ShowWindow(SW_HIDE); } void CMsgWnd::OnLButtonDown(UINT nFlags, CPoint point) { if(MouseOver) LButtonDown=true; else CWnd::OnLButtonDown(nFlags, point); } void CMsgWnd::OnMouseMove(UINT nFlags, CPoint point) { if(!MouseOver) { MouseOver=true; SetCapture(); }else{ CPoint Point(point); ClientToScreen(&Point); if(!Rect.PtInRect(Point)) { MouseOver=false; ReleaseCapture(); }else{ CWnd::OnMouseMove(nFlags, point); return; } } Cursor=::SetCursor(Cursor); RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); CWnd::OnMouseMove(nFlags, point); } void CMsgWnd::OnLButtonUp(UINT nFlags, CPoint point) { if(MouseOver && LButtonDown) { NMHDR nm; nm.code =NM_CLICK; nm.idFrom =GetDlgCtrlID(); nm.hwndFrom =m_hWnd; CWnd* pOwner=GetOwner(); Cancel(); if(pOwner && IsWindow(pOwner->m_hWnd)) pOwner->SendMessage(WM_NOTIFY, nm.idFrom, (LPARAM)&nm); }else CWnd::OnLButtonUp(nFlags, point); LButtonDown=false; }