819 views
首页 > WTL > MSN 式样通知窗口的 WTL 实现

MSN 式样通知窗口的 WTL 实现

2010年4月6日



源码:

  1. // CTaskbarNotifier Header file
  2.  
  3. #pragma once
  4.  
  5. #define WM_TASKBARNOTIFIERCLICKED    WM_USER+123
  6. #define TN_TEXT_NORMAL            0x0000
  7. #define TN_TEXT_BOLD            0x0001
  8. #define TN_TEXT_ITALIC            0x0002
  9. #define TN_TEXT_UNDERLINE        0x0004
  10.  
  11.  
  12. #define IDT_HIDDEN            0
  13. #define IDT_APPEARING        1
  14. #define IDT_WAITING            2
  15. #define IDT_DISAPPEARING    3
  16.  
  17. #define TASKBAR_ON_TOP        1
  18. #define TASKBAR_ON_LEFT        2
  19. #define TASKBAR_ON_RIGHT    3
  20. #define TASKBAR_ON_BOTTOM    4
  21.  
  22.  
  23. #define DEFAULT_INCREMENT    2
  24.  
  25. // CTaskbarNotifier
  26.  
  27. template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CFrameWinTraits>
  28. class CTaskbarNotifierT 
  29.     : public CWindowImpl<T, TBase, TWinTraits >
  30.     , public CMessageFilter
  31. {
  32.     typedef CWindowImpl<T, TBase, TWinTraits> baseClass;
  33.     typedef CTaskbarNotifierT<T, TBase, TWinTraits> thisClass;
  34. public:
  35.     DECLARE_WND_CLASS(_T("CTaskbarNotifierT"))
  36.  
  37.     CTaskbarNotifierT();
  38.     virtual ~CTaskbarNotifierT();
  39.     BOOL PreTranslateMessage(MSG* pMsg);
  40.  
  41.     HWND Create(HWND pWndParent);
  42.     void Show(LPCTSTR szCaption,
  43.         DWORD dwTimeToShow=500,DWORD dwTimeToStay=3000,
  44.         DWORD dwTimeToHide=500,int nIncrement=DEFAULT_INCREMENT);
  45.     void Hide();
  46.     BOOL SetSkin(UINT nBitmapID,short red=-1,short green=-1,short blue=-1);
  47.     BOOL SetSkin(LPCTSTR szFileName,short red=-1,short green=-1,short blue=-1);
  48.     void SetTextFont(LPCTSTR szFont,int nSize,int nNormalStyle,int nSelectedStyle);
  49.     void SetTextColor(COLORREF crNormalTextColor,COLORREF crSelectedTextColor);
  50.     void SetTextRect(RECT rcText);
  51.  
  52.  
  53.     BEGIN_MSG_MAP( thisClass )
  54.         MESSAGE_HANDLER(WM_CREATE, OnCreate)
  55.         MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
  56.         MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
  57.         MESSAGE_HANDLER(WM_PAINT, OnPaint)
  58.         MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave)
  59.         MESSAGE_HANDLER(WM_MOUSEHOVER, OnMouseHover)
  60.         MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor)
  61.         MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
  62.         MESSAGE_HANDLER(WM_TIMER, OnTimer)
  63.     END_MSG_MAP()
  64.  
  65.     HWND m_pWndParent;
  66.  
  67.  
  68.     CFont m_myNormalFont;
  69.     CFont m_mySelectedFont;
  70.     COLORREF m_crNormalTextColor;
  71.     COLORREF m_crSelectedTextColor;
  72.     HCURSOR m_hCursor;
  73.  
  74.     CBitmap m_biSkinBackground;
  75.     HRGN m_hSkinRegion;
  76.     CRect m_rcText;
  77.     int m_nSkinWidth;
  78.     int m_nSkinHeight;
  79.  
  80.     CString m_strCaption;
  81.     BOOL m_bMouseIsOver;
  82.     int m_nAnimStatus;
  83.  
  84.     DWORD m_dwTimeToShow;
  85.     DWORD m_dwTimeToLive;
  86.     DWORD m_dwTimeToHide;
  87.     DWORD m_dwDelayBetweenShowEvents;
  88.     DWORD m_dwDelayBetweenHideEvents;
  89.     int m_nStartPosX;
  90.     int m_nStartPosY;
  91.     int m_nCurrentPosX;
  92.     int m_nCurrentPosY;
  93.     int m_nTaskbarPlacement;
  94.     int m_nIncrement;
  95.  
  96. protected:
  97.     BYTE * Get24BitPixels(HBITMAP pBitmap, WORD *pwWidth, WORD *pwHeight);
  98.     HRGN GenerateRegion(HBITMAP hBitmap, BYTE red, BYTE green, BYTE blue);
  99.  
  100.     POINT m_ptBase;
  101.  
  102. public:
  103.     LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  104.     LRESULT OnSetCursor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  105.     LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  106.     LRESULT OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  107.     LRESULT OnMouseHover(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  108.     LRESULT OnMouseLeave(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  109.     LRESULT OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  110.     LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  111.     LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  112. };
  113.  
  114.  
  115. template <class T, class TBase, class TWinTraits>
  116. CTaskbarNotifierT<T, TBase, TWinTraits>::CTaskbarNotifierT()
  117. {
  118.     m_strCaption=_T("");
  119.     m_pWndParent=NULL;
  120.     m_bMouseIsOver=FALSE;
  121.     m_hSkinRegion=NULL;
  122.     m_hCursor=NULL;
  123.     m_crNormalTextColor=RGB(133,146,181);
  124.     m_crSelectedTextColor=RGB(10,36,106);
  125.     m_nSkinHeight=0;
  126.     m_nSkinWidth=0;
  127.  
  128.     m_dwTimeToShow=0;
  129.     m_dwTimeToLive=0;
  130.     m_dwTimeToHide=0;
  131.     m_dwDelayBetweenShowEvents=0;
  132.     m_dwDelayBetweenHideEvents=0;
  133.     m_nStartPosX=0;
  134.     m_nStartPosY=0;
  135.     m_nCurrentPosX=0;
  136.     m_nCurrentPosY=0;
  137.     m_nIncrement=DEFAULT_INCREMENT;
  138.     m_nTaskbarPlacement=0;
  139.     m_nAnimStatus=IDT_HIDDEN;
  140.     m_rcText.SetRect(0,0,0,0);
  141. }
  142.  
  143. template <class T, class TBase, class TWinTraits>
  144. CTaskbarNotifierT<T, TBase, TWinTraits>::~CTaskbarNotifierT()
  145. {
  146. }
  147.  
  148. template <class T, class TBase, class TWinTraits>
  149. BOOL CTaskbarNotifierT<T, TBase, TWinTraits>::PreTranslateMessage(MSG* pMsg)
  150. {
  151.     return FALSE;
  152. }
  153.  
  154. template <class T, class TBase, class TWinTraits>
  155. HWND CTaskbarNotifierT<T, TBase, TWinTraits>::Create(HWND pWndParent)
  156. {
  157.     HWND bResult = NULL;
  158.     m_pWndParent=pWndParent;
  159.  
  160.     bResult = baseClass::Create(pWndParent, rcDefault, NULL, WS_POPUP);
  161.     ::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
  162.     return bResult;
  163. }
  164.  
  165. template <class T, class TBase, class TWinTraits>
  166. void CTaskbarNotifierT<T, TBase, TWinTraits>::SetTextFont(LPCTSTR szFont,int nSize,int nNormalStyle,int nSelectedStyle)
  167. {
  168.     LOGFONT lf = { 0 };
  169.     if (m_myNormalFont.m_hFont) {
  170.         m_myNormalFont.DeleteObject();
  171.     }
  172.     m_myNormalFont.CreatePointFont(nSize,szFont);
  173.     m_myNormalFont.GetLogFont(&lf);
  174.  
  175.     // We  set the Font of the unselected ITEM
  176.     if (nNormalStyle & TN_TEXT_BOLD)
  177.         lf.lfWeight = FW_BOLD;
  178.     else
  179.         lf.lfWeight = FW_NORMAL;
  180.  
  181.     if (nNormalStyle & TN_TEXT_ITALIC)
  182.         lf.lfItalic=TRUE;
  183.     else
  184.         lf.lfItalic=FALSE;
  185.  
  186.     if (nNormalStyle & TN_TEXT_UNDERLINE)
  187.         lf.lfUnderline=TRUE;
  188.     else
  189.         lf.lfUnderline=FALSE;
  190.  
  191.     m_myNormalFont.DeleteObject();
  192.     m_myNormalFont.CreateFontIndirect(&lf);
  193.  
  194.     // We set the Font of the selected ITEM
  195.     if (nSelectedStyle & TN_TEXT_BOLD)
  196.         lf.lfWeight = FW_BOLD;
  197.     else
  198.         lf.lfWeight = FW_NORMAL;
  199.  
  200.     if (nSelectedStyle & TN_TEXT_ITALIC)
  201.         lf.lfItalic=TRUE;
  202.     else
  203.         lf.lfItalic=FALSE;
  204.  
  205.     if (nSelectedStyle & TN_TEXT_UNDERLINE)
  206.         lf.lfUnderline=TRUE;
  207.     else
  208.         lf.lfUnderline=FALSE;
  209.  
  210.     if (m_mySelectedFont.m_hFont) {
  211.         m_mySelectedFont.DeleteObject();
  212.     }
  213.     m_mySelectedFont.CreateFontIndirect(&lf);
  214. }
  215.  
  216. template <class T, class TBase, class TWinTraits>
  217. void CTaskbarNotifierT<T, TBase, TWinTraits>::SetTextColor(COLORREF crNormalTextColor,COLORREF crSelectedTextColor)
  218. {
  219.     m_crNormalTextColor=crNormalTextColor;
  220.     m_crSelectedTextColor=crSelectedTextColor;
  221.     RedrawWindow();
  222. }
  223.  
  224. template <class T, class TBase, class TWinTraits>
  225. void CTaskbarNotifierT<T, TBase, TWinTraits>::SetTextRect(RECT rcText)
  226. {
  227.     m_rcText=rcText;
  228. }
  229.  
  230. template <class T, class TBase, class TWinTraits>
  231. BOOL CTaskbarNotifierT<T, TBase, TWinTraits>::SetSkin(UINT nBitmapID,short red,short green,short blue)
  232. {
  233.     BITMAP bm = { 0 };
  234.  
  235.     if (m_biSkinBackground.m_hBitmap)
  236.     {
  237.         m_biSkinBackground.DeleteObject();
  238.     }
  239.  
  240.     if (!m_biSkinBackground.LoadBitmap(nBitmapID)) {
  241.         return FALSE;
  242.     }
  243.     GetObject(m_biSkinBackground.m_hBitmap, sizeof(bm), &bm);
  244.     m_nSkinWidth=bm.bmWidth;
  245.     m_nSkinHeight=bm.bmHeight;
  246.     m_rcText.SetRect(0,0,bm.bmWidth,bm.bmHeight);
  247.  
  248.     if (red!=-1 && green!=-1 && blue!=-1)
  249.     {
  250.         // No need to delete the HRGN,  SetWindowRgn() owns it after being called
  251.         m_hSkinRegion=GenerateRegion((HBITMAP)m_biSkinBackground.m_hBitmap,
  252.             (BYTE) red,(BYTE) green,(BYTE) blue);
  253.         SetWindowRgn(m_hSkinRegion, true);
  254.     }
  255.  
  256.     return TRUE;
  257. }
  258.  
  259. template <class T, class TBase, class TWinTraits>
  260. BOOL CTaskbarNotifierT<T, TBase, TWinTraits>::SetSkin(LPCTSTR szFileName,short red,short green,short blue)
  261. {
  262.     BITMAP bm = { 0 };
  263.     HBITMAP hBmp = NULL;
  264.  
  265.     hBmp=(HBITMAP) ::LoadImage(ModuleHelper::GetResourceInstance(),
  266.         szFileName,IMAGE_BITMAP,0,0, LR_LOADFROMFILE);
  267.     if (!hBmp) {
  268.         return FALSE;
  269.     }
  270.  
  271.     m_biSkinBackground.DeleteObject();
  272.     m_biSkinBackground.Attach(hBmp);
  273.     GetObject(m_biSkinBackground.m_hBitmap, sizeof(bm), &bm);
  274.     m_nSkinWidth=bm.bmWidth;
  275.     m_nSkinHeight=bm.bmHeight;
  276.     m_rcText.SetRect(0,0,bm.bmWidth,bm.bmHeight);
  277.  
  278.     if (red!=-1 && green!=-1 && blue!=-1)
  279.     {
  280.         // No need to delete the HRGN,  SetWindowRgn() owns it after being called
  281.         m_hSkinRegion=GenerateRegion((HBITMAP)m_biSkinBackground.m_hBitmap,
  282.             (BYTE) red,(BYTE) green,(BYTE) blue);
  283.         SetWindowRgn(m_hSkinRegion, true);
  284.     }
  285.  
  286.     return TRUE;
  287. }
  288.  
  289. template <class T, class TBase, class TWinTraits>
  290. void CTaskbarNotifierT<T, TBase, TWinTraits>::Show(LPCTSTR szCaption,DWORD dwTimeToShow,
  291.                                                    DWORD dwTimeToLive,DWORD dwTimeToHide,
  292.                                                    int nIncrement)
  293. {
  294.     unsigned int nDesktopHeight;
  295.     unsigned int nDesktopWidth;
  296.     unsigned int nScreenWidth;
  297.     unsigned int nScreenHeight;
  298.     CRect rcDesktop;
  299.  
  300.     m_strCaption=szCaption;
  301.     m_dwTimeToShow=dwTimeToShow;
  302.     m_dwTimeToLive=dwTimeToLive;
  303.     m_dwTimeToHide=dwTimeToHide;
  304.  
  305.     m_nIncrement = nIncrement;
  306.  
  307.     ::SystemParametersInfo(SPI_GETWORKAREA,0,&rcDesktop,0);
  308.     nDesktopWidth=rcDesktop.right-rcDesktop.left;
  309.     nDesktopHeight=rcDesktop.bottom-rcDesktop.top;
  310.     nScreenWidth=::GetSystemMetrics(SM_CXSCREEN);
  311.     nScreenHeight=::GetSystemMetrics(SM_CYSCREEN);
  312.  
  313.     BOOL bTaskbarOnRight=nDesktopWidth<nScreenWidth && rcDesktop.left==0;
  314.     BOOL bTaskbarOnLeft=nDesktopWidth<nScreenWidth && rcDesktop.left!=0;
  315.     BOOL bTaskBarOnTop=nDesktopHeight<nScreenHeight && rcDesktop.top!=0;
  316.     // BOOL bTaskbarOnBottom=nDesktopHeight<nScreenHeight && rcDesktop.top==0;
  317.  
  318.     switch (m_nAnimStatus)
  319.     {
  320.     case IDT_HIDDEN:
  321.         if (bTaskbarOnRight)
  322.         {
  323.             m_dwDelayBetweenShowEvents=m_dwTimeToShow/(m_nSkinWidth/m_nIncrement);
  324.             m_dwDelayBetweenHideEvents=m_dwTimeToHide/(m_nSkinWidth/m_nIncrement);
  325.             m_nStartPosX=rcDesktop.right;
  326.             m_nStartPosY=rcDesktop.bottom-m_nSkinHeight;
  327.             m_nTaskbarPlacement=TASKBAR_ON_RIGHT;
  328.             m_ptBase.x = rcDesktop.right;
  329.             m_ptBase.y = nScreenHeight;
  330.         }
  331.         else if (bTaskbarOnLeft)
  332.         {
  333.             m_dwDelayBetweenShowEvents=m_dwTimeToShow/(m_nSkinWidth/m_nIncrement);
  334.             m_dwDelayBetweenHideEvents=m_dwTimeToHide/(m_nSkinWidth/m_nIncrement);
  335.             m_nStartPosX=rcDesktop.left-m_nSkinWidth;
  336.             m_nStartPosY=rcDesktop.bottom-m_nSkinHeight;
  337.             m_nTaskbarPlacement=TASKBAR_ON_LEFT;
  338.             m_ptBase.x = rcDesktop.left;
  339.             m_ptBase.y = nScreenHeight;
  340.         }
  341.         else if (bTaskBarOnTop)
  342.         {
  343.             m_dwDelayBetweenShowEvents=m_dwTimeToShow/(m_nSkinHeight/m_nIncrement);
  344.             m_dwDelayBetweenHideEvents=m_dwTimeToHide/(m_nSkinHeight/m_nIncrement);
  345.             m_nStartPosX=rcDesktop.right-m_nSkinWidth;
  346.             m_nStartPosY=rcDesktop.top-m_nSkinHeight;
  347.             m_nTaskbarPlacement=TASKBAR_ON_TOP;
  348.             m_ptBase.x = nScreenWidth;
  349.             m_ptBase.y = rcDesktop.top;
  350.         }
  351.         else //if (bTaskbarOnBottom)
  352.         {
  353.             // Taskbar is on the bottom or Invisible
  354.             m_dwDelayBetweenShowEvents=m_dwTimeToShow/(m_nSkinHeight/m_nIncrement);
  355.             m_dwDelayBetweenHideEvents=m_dwTimeToHide/(m_nSkinHeight/m_nIncrement);
  356.             m_nStartPosX=rcDesktop.right-m_nSkinWidth;
  357.             m_nStartPosY=rcDesktop.bottom;
  358.             m_nTaskbarPlacement=TASKBAR_ON_BOTTOM;
  359.             m_ptBase.x = nScreenWidth;
  360.             m_ptBase.y = rcDesktop.bottom;
  361.         }
  362.  
  363.         m_nCurrentPosX=m_nStartPosX;
  364.         m_nCurrentPosY=m_nStartPosY;
  365.  
  366.         SetWindowPos(NULL,m_nCurrentPosX,m_nCurrentPosY,0,0,
  367.             SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOACTIVATE);
  368.         ShowWindow(SW_SHOW);
  369.         SetTimer(IDT_APPEARING,m_dwDelayBetweenShowEvents);
  370.         break;
  371.  
  372.     case IDT_WAITING:
  373.         RedrawWindow();
  374.         KillTimer(IDT_WAITING);
  375.         SetTimer(IDT_WAITING,m_dwTimeToLive);
  376.         break;
  377.  
  378.     case IDT_APPEARING:
  379.         RedrawWindow();
  380.         break;
  381.  
  382.     case IDT_DISAPPEARING:
  383.         KillTimer(IDT_DISAPPEARING);
  384.         SetTimer(IDT_WAITING,m_dwTimeToLive);
  385.         if (bTaskbarOnRight) {
  386.             m_nCurrentPosX=rcDesktop.right-m_nSkinWidth;
  387.         } else if (bTaskbarOnLeft) {
  388.             m_nCurrentPosX=rcDesktop.left;
  389.         } else if (bTaskBarOnTop) {
  390.             m_nCurrentPosY=rcDesktop.top;
  391.         } else { //if (bTaskbarOnBottom)
  392.             m_nCurrentPosY=rcDesktop.bottom-m_nSkinHeight;
  393.         }
  394.  
  395.         SetWindowPos(NULL,m_nCurrentPosX,m_nCurrentPosY,m_nSkinWidth,m_nSkinHeight,
  396.             SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOACTIVATE);
  397.         RedrawWindow();
  398.         break;
  399.     }
  400. }
  401.  
  402. template <class T, class TBase, class TWinTraits>
  403. void CTaskbarNotifierT<T, TBase, TWinTraits>::Hide()
  404. {
  405.     switch (m_nAnimStatus)
  406.     {
  407.     case IDT_APPEARING:
  408.         KillTimer(IDT_APPEARING);
  409.         break;
  410.     case IDT_WAITING:
  411.         KillTimer(IDT_WAITING);
  412.         break;
  413.     case IDT_DISAPPEARING:
  414.         KillTimer(IDT_DISAPPEARING);
  415.         break;
  416.     }
  417.     MoveWindow(0,0,0,0);
  418.     ShowWindow(SW_HIDE);
  419.     m_nAnimStatus=IDT_HIDDEN;
  420. }
  421.  
  422. template <class T, class TBase, class TWinTraits>
  423. HRGN CTaskbarNotifierT<T, TBase, TWinTraits>::GenerateRegion(HBITMAP hBitmap, BYTE red, BYTE green, BYTE blue)
  424. {
  425.     WORD wBmpWidth,wBmpHeight;
  426.     HRGN hRgn, hTmpRgn;
  427.  
  428.     // 24bit pixels from the bitmap
  429.     BYTE *pPixels = Get24BitPixels(hBitmap, &wBmpWidth, &wBmpHeight);
  430.     if (!pPixels) return NULL;
  431.  
  432.     // create our working region
  433.     hRgn = CreateRectRgn(0,0,wBmpWidth,wBmpHeight);
  434.     if (!hRgn) { delete pPixels; return NULL; }
  435.  
  436.     DWORD p=0;
  437.     for (WORD y=0; y<wBmpHeight; y++)
  438.     {
  439.         for (WORD x=0; x<wBmpWidth; x++)
  440.         {
  441.             BYTE jRed   = pPixels[p+2];
  442.             BYTE jGreen = pPixels[p+1];
  443.             BYTE jBlue  = pPixels[p+0];
  444.  
  445.             if (jRed==red && jGreen==green && jBlue==blue)
  446.             {
  447.                 // remove transparent color from region
  448.                 hTmpRgn = CreateRectRgn(x,y,x+1,y+1);
  449.                 CombineRgn(hRgn, hRgn, hTmpRgn, RGN_XOR);
  450.                 DeleteObject(hTmpRgn);
  451.             }
  452.  
  453.             // next pixel
  454.             p+=3;
  455.         }
  456.     }
  457.  
  458.     // release pixels
  459.     delete pPixels;
  460.  
  461.     // return the region
  462.     return hRgn;
  463. }
  464.  
  465. template <class T, class TBase, class TWinTraits>
  466. BYTE* CTaskbarNotifierT<T, TBase, TWinTraits>::Get24BitPixels(HBITMAP pBitmap, WORD *pwWidth, WORD *pwHeight)
  467. {
  468.     BITMAP bmpBmp;
  469.     LPBITMAPINFO pbmiInfo;
  470.     BITMAPINFO bmiInfo;
  471.     WORD wBmpWidth, wBmpHeight;
  472.  
  473.     GetObject(pBitmap, sizeof(bmpBmp),&bmpBmp);
  474.     pbmiInfo   = (LPBITMAPINFO)&bmpBmp;
  475.  
  476.     wBmpWidth  = (WORD)pbmiInfo->bmiHeader.biWidth;
  477.     wBmpWidth -= (wBmpWidth%4);
  478.     wBmpHeight = (WORD)pbmiInfo->bmiHeader.biHeight;
  479.  
  480.     *pwWidth  = wBmpWidth;
  481.     *pwHeight = wBmpHeight;
  482.  
  483.     BYTE *pPixels = new BYTE[wBmpWidth*wBmpHeight*3];
  484.     if (!pPixels) return NULL;
  485.  
  486.     HDC hDC =::GetWindowDC(NULL);
  487.  
  488.     bmiInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  489.     bmiInfo.bmiHeader.biWidth = wBmpWidth;
  490.     bmiInfo.bmiHeader.biHeight = -wBmpHeight;
  491.     bmiInfo.bmiHeader.biPlanes = 1;
  492.     bmiInfo.bmiHeader.biBitCount = 24;
  493.     bmiInfo.bmiHeader.biCompression = BI_RGB;
  494.     bmiInfo.bmiHeader.biSizeImage = wBmpWidth*wBmpHeight*3;
  495.     bmiInfo.bmiHeader.biXPelsPerMeter = 0;
  496.     bmiInfo.bmiHeader.biYPelsPerMeter = 0;
  497.     bmiInfo.bmiHeader.biClrUsed = 0;
  498.     bmiInfo.bmiHeader.biClrImportant = 0;
  499.  
  500.     // get pixels from the original bitmap converted to 24bits
  501.     int iRes = GetDIBits(hDC,pBitmap,0,wBmpHeight,(LPVOID)pPixels,&bmiInfo,DIB_RGB_COLORS);
  502.  
  503.     // release the device context
  504.     ::ReleaseDC(NULL,hDC);
  505.  
  506.     // if failed, cancel the operation.
  507.     if (!iRes)
  508.     {
  509.         delete pPixels;
  510.         return NULL;
  511.     };
  512.  
  513.     // return the pixel array
  514.     return pPixels;
  515. }
  516.  
  517. template <class T, class TBase, class TWinTraits>
  518. LRESULT CTaskbarNotifierT<T, TBase, TWinTraits>::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  519. {
  520.     uMsg, wParam, lParam, bHandled;
  521.     bHandled = FALSE;
  522.     m_hCursor = ::LoadCursor(NULL, MAKEINTRESOURCE(32649));
  523.     return 0;
  524. }
  525.  
  526. template <class T, class TBase, class TWinTraits>
  527. LRESULT CTaskbarNotifierT<T, TBase, TWinTraits>::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  528. {
  529.     bHandled = FALSE;
  530.  
  531.     TRACKMOUSEEVENT t_MouseEvent = { sizeof(t_MouseEvent) };
  532.     t_MouseEvent.cbSize      = sizeof(TRACKMOUSEEVENT);
  533.     t_MouseEvent.dwFlags     = TME_LEAVE | TME_HOVER;
  534.     t_MouseEvent.hwndTrack   = m_hWnd;
  535.     t_MouseEvent.dwHoverTime = 1;
  536.  
  537.     ::_TrackMouseEvent(&t_MouseEvent);
  538.  
  539.     return 0;
  540. }
  541.  
  542. template <class T, class TBase, class TWinTraits>
  543. LRESULT CTaskbarNotifierT<T, TBase, TWinTraits>::OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  544. {
  545.     bHandled = FALSE;
  546.     ::PostMessage(m_pWndParent, WM_TASKBARNOTIFIERCLICKED, (WPARAM)m_hWnd,0);
  547.     return 0;
  548. }
  549.  
  550. template <class T, class TBase, class TWinTraits>
  551. LRESULT CTaskbarNotifierT<T, TBase, TWinTraits>::OnMouseHover(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  552. {
  553.     uMsg, wParam, lParam, bHandled;
  554.     if (m_bMouseIsOver==FALSE)
  555.     {
  556.         m_bMouseIsOver=TRUE;
  557.         RedrawWindow();
  558.     }
  559.     return 0;
  560. }
  561.  
  562. template <class T, class TBase, class TWinTraits>
  563. LRESULT CTaskbarNotifierT<T, TBase, TWinTraits>::OnMouseLeave(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  564. {
  565.     uMsg, wParam, lParam, bHandled;
  566.     if (m_bMouseIsOver==TRUE)
  567.     {
  568.         m_bMouseIsOver=FALSE;
  569.         RedrawWindow();
  570.     }
  571.     return 0;
  572. }
  573.  
  574. template <class T, class TBase, class TWinTraits>
  575. LRESULT CTaskbarNotifierT<T, TBase, TWinTraits>::OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  576. {
  577.     uMsg, wParam, lParam, bHandled;
  578.     CDCHandle pDC((HDC)wParam);
  579.     CDC memDC;
  580.     CBitmapHandle pOldBitmap;
  581.     BITMAP bm;
  582.  
  583.     memDC.CreateCompatibleDC(pDC);
  584.     GetObject(m_biSkinBackground.m_hBitmap, sizeof(bm), &bm);
  585.     pOldBitmap=memDC.SelectBitmap(m_biSkinBackground);
  586.  
  587.     pDC.BitBlt(0,0,bm.bmWidth,bm.bmHeight,memDC,0,0,SRCCOPY);
  588.     memDC.SelectBitmap(pOldBitmap);
  589.  
  590.     return TRUE;
  591. }
  592.  
  593. template <class T, class TBase, class TWinTraits>
  594. LRESULT CTaskbarNotifierT<T, TBase, TWinTraits>::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  595. {
  596.     uMsg, wParam, lParam, bHandled;
  597.     CPaintDC dc(*this);
  598.     CRect rcClient;
  599.     CFontHandle pOldFont;
  600.     TCHAR *szBuffer;
  601.  
  602.     if (m_bMouseIsOver)
  603.     {
  604.         dc.SetTextColor(m_crSelectedTextColor);
  605.         pOldFont=dc.SelectFont(m_mySelectedFont);
  606.     }
  607.     else
  608.     {
  609.         dc.SetTextColor(m_crNormalTextColor);
  610.         pOldFont=dc.SelectFont(m_myNormalFont);
  611.     }
  612.  
  613.     szBuffer=new TCHAR[m_strCaption.GetLength()+10];
  614.     lstrcpy(szBuffer, (LPCTSTR)m_strCaption);
  615.  
  616.     dc.SetBkMode(TRANSPARENT);
  617.     rcClient.DeflateRect(10,20,10,20);
  618.     dc.DrawText(szBuffer,-1,m_rcText,DT_CENTER | DT_VCENTER | DT_WORDBREAK | DT_END_ELLIPSIS);
  619.  
  620.     delete[] szBuffer;
  621.     dc.SelectFont(pOldFont);
  622.     return 0;
  623. }
  624.  
  625. template <class T, class TBase, class TWinTraits>
  626. LRESULT CTaskbarNotifierT<T, TBase, TWinTraits>::OnSetCursor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  627. {
  628.     uMsg, wParam, lParam, bHandled;
  629.     if (LOWORD(lParam) == HTCLIENT)
  630.     {
  631.         ::SetCursor(m_hCursor);
  632.         return TRUE;
  633.     }
  634.     bHandled = FALSE;
  635.     return 0;
  636. }
  637.  
  638. template <class T, class TBase, class TWinTraits>
  639. LRESULT CTaskbarNotifierT<T, TBase, TWinTraits>::OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  640. {
  641.     uMsg, wParam, lParam, bHandled;
  642.     bHandled = FALSE;
  643.     int nDeltaX=m_nSkinWidth, nDeltaY=m_nSkinHeight;
  644.     UINT nIDEvent = (UINT) wParam;
  645.     switch (nIDEvent)
  646.     {
  647.     case IDT_APPEARING:
  648.         m_nAnimStatus=IDT_APPEARING;
  649.         switch(m_nTaskbarPlacement)
  650.         {
  651.         case TASKBAR_ON_BOTTOM:
  652.             if (m_nCurrentPosY>(m_nStartPosY-m_nSkinHeight)) {
  653.                 m_nCurrentPosY -= m_nIncrement;
  654.                 nDeltaX = m_nSkinWidth;
  655.                 nDeltaY = m_ptBase.y - m_nCurrentPosY;
  656.             } else {
  657.                 KillTimer(IDT_APPEARING);
  658.                 SetTimer(IDT_WAITING,m_dwTimeToLive);
  659.                 m_nAnimStatus=IDT_WAITING;
  660.             }
  661.             break;
  662.         case TASKBAR_ON_TOP:
  663.             if ((m_nCurrentPosY-m_nStartPosY)<m_nSkinHeight) {
  664.                 m_nCurrentPosY += m_nIncrement;
  665.                 nDeltaX = m_nSkinWidth;
  666.                 nDeltaY = m_nCurrentPosY - m_ptBase.y;
  667.             } else {
  668.                 KillTimer(IDT_APPEARING);
  669.                 SetTimer(IDT_WAITING,m_dwTimeToLive);
  670.                 m_nAnimStatus=IDT_WAITING;
  671.             }
  672.             break;
  673.         case TASKBAR_ON_LEFT:
  674.             if ((m_nCurrentPosX-m_nStartPosX)<m_nSkinWidth) {
  675.                 m_nCurrentPosX += m_nIncrement;
  676.                 nDeltaX = m_nCurrentPosX - m_ptBase.x;
  677.                 nDeltaY = m_nSkinHeight;
  678.             } else {
  679.                 KillTimer(IDT_APPEARING);
  680.                 SetTimer(IDT_WAITING,m_dwTimeToLive);
  681.                 m_nAnimStatus=IDT_WAITING;
  682.             }
  683.             break;
  684.         case TASKBAR_ON_RIGHT:
  685.             if (m_nCurrentPosX>(m_nStartPosX-m_nSkinWidth)) {
  686.                 m_nCurrentPosX -= m_nIncrement;
  687.                 nDeltaX = m_ptBase.x - m_nCurrentPosX;
  688.                 nDeltaY = m_nSkinHeight;
  689.             } else {
  690.                 KillTimer(IDT_APPEARING);
  691.                 SetTimer(IDT_WAITING,m_dwTimeToLive);
  692.                 m_nAnimStatus=IDT_WAITING;
  693.             }
  694.             break;
  695.         }
  696.         SetWindowPos(NULL,m_nCurrentPosX,m_nCurrentPosY,nDeltaX,nDeltaY,
  697.             SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOACTIVATE);
  698.         break;
  699.  
  700.     case IDT_WAITING:
  701.         KillTimer(IDT_WAITING);
  702.         SetTimer(IDT_DISAPPEARING,m_dwDelayBetweenHideEvents);
  703.         break;
  704.  
  705.     case IDT_DISAPPEARING:
  706.         m_nAnimStatus=IDT_DISAPPEARING;
  707.         switch(m_nTaskbarPlacement)
  708.         {
  709.         case TASKBAR_ON_BOTTOM:
  710.             if (m_nCurrentPosY<m_nStartPosY) {
  711.                 m_nCurrentPosY += m_nIncrement;
  712.                 nDeltaX = m_nSkinWidth;
  713.                 nDeltaY = m_ptBase.y - m_nCurrentPosY;
  714.             } else {
  715.                 KillTimer(IDT_DISAPPEARING);
  716.                 Hide();
  717.             }
  718.             break;
  719.         case TASKBAR_ON_TOP:
  720.             if (m_nCurrentPosY>m_nStartPosY) {
  721.                 m_nCurrentPosY -= m_nIncrement;
  722.                 nDeltaX = m_nSkinWidth;
  723.                 nDeltaY = m_nCurrentPosY - m_ptBase.y;
  724.             } else {
  725.                 KillTimer(IDT_DISAPPEARING);
  726.                 Hide();
  727.             }
  728.             break;
  729.         case TASKBAR_ON_LEFT:
  730.             if (m_nCurrentPosX>m_nStartPosX) {
  731.                 m_nCurrentPosX -= m_nIncrement;
  732.                 nDeltaX = m_nCurrentPosX - m_ptBase.x;
  733.                 nDeltaY = m_nSkinHeight;
  734.             } else {
  735.                 KillTimer(IDT_DISAPPEARING);
  736.                 Hide();
  737.             }
  738.             break;
  739.         case TASKBAR_ON_RIGHT:
  740.             if (m_nCurrentPosX<m_nStartPosX) {
  741.                 m_nCurrentPosX += m_nIncrement;
  742.                 nDeltaX = m_ptBase.x - m_nCurrentPosX;
  743.                 nDeltaY = m_nSkinHeight;
  744.             } else {
  745.                 KillTimer(IDT_DISAPPEARING);
  746.                 Hide();
  747.             }
  748.             break;
  749.         }
  750.         SetWindowPos(NULL,m_nCurrentPosX,m_nCurrentPosY,nDeltaX,nDeltaY,
  751.             SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOACTIVATE);
  752.         break;
  753.     }
  754.  
  755.     return 0;
  756. }
  757.  
  758.  
  759. class CTaskbarNotifier : public CTaskbarNotifierT<CTaskbarNotifier>
  760. {
  761. public:
  762.     DECLARE_WND_CLASS(_T("CTaskbarNotifier"))
  763. };

demo

WTL , , , ,

  1. 目前还没有任何评论.
  1. 目前还没有任何 trackbacks 和 pingbacks.