1,141 views
首页 > WTL > 实现一个 WTL 带菜单的按钮 CMenuButton

实现一个 WTL 带菜单的按钮 CMenuButton

2010年1月8日

今天将 codeproject 上的一个 MFC 实现的菜单按钮移植到 WTL 下. 测试后发现工作很好.
现在将其用法简述如下.

  1. 用 VC 的 WTL wizard 创建一个对话框程序, 然后将头文件 atlmenubtn.h 包含到 stdafx.h 文件内.
  2. 在主界面的对话框资源内添加一个按钮,
  3. 在 CMainDlg 类是消息循环添加 REFLECT_NOTIFICATIONS() 宏, 这个相当重要, 不然按钮将不会被显示出来.
  4. 在 CMainDlg 类添加 CMenuButton m_btn; 成员变量, 然后就可以用 m_btn 变量子类化刚才添加的按钮, 使用 SubclassWindow 函数; 或者创建一个, 使用 Create 函数.
  5. 然后就可以添加菜单项了, 响应菜单命令的消息. 等等等等. 具体细节请看代码.

源代码下载链接

最后的运行效果如下:

头文件 “atlmenubtn.h” 的源码如下, 全文张贴:

下载: atlmenubtn.h
  1. //
  2. // based on the class CCoolBtn
  3. // http://www.codeproject.com/KB/buttons/pushmenubutton.aspx
  4. //
  5.  
  6. #if !defined(AFX_MENUBTN_H__3A90681F_CE5F_11D3_808C_005004D6CF93__INCLUDED_)
  7. #define AFX_MENUBTN_H__3A90681F_CE5F_11D3_808C_005004D6CF93__INCLUDED_
  8.  
  9. #if _MSC_VER > 1000
  10. #pragma once
  11. #endif // _MSC_VER > 1000
  12.  
  13. #ifndef __cplusplus
  14. #error ATL requires C++ compilation (use a .cpp suffix)
  15. #endif
  16.  
  17. #ifndef __ATLCTRLS_H__
  18. #error atlmenubtn.h requires atlctrls.h to be included first
  19. #endif
  20.  
  21. #ifndef __ATLMISC_H__
  22. #error atlmenubtn.h requires atlmisc.h to be included first
  23. #endif
  24.  
  25. #ifndef __ATLFRAME_H__
  26. #error atlmenubtn.h requires atlframe.h to be included first
  27. #endif
  28.  
  29. #define  nDropBtnWidth 16
  30.  
  31. /////////////////////////////////////////////////////////////////////////////
  32. // CMenuButtonT window
  33.  
  34.  
  35. template <class T, class TBase = CButton, class TWinTraits = CControlWinTraits>
  36. class CMenuButtonT 
  37.     : public CWindowImpl<T, TBase, TWinTraits>
  38.     , public COwnerDraw<T>
  39. {
  40. public:
  41.     typedef CMenuButtonT<T, TBase, TWinTraits> thisClass;
  42.     typedef CWindowImpl<T, TBase, TWinTraits> baseClass;
  43.     typedef COwnerDraw<T> ownerDrawClass;
  44.  
  45.     DECLARE_WND_SUPERCLASS(_T("CMenuButtonT"), TBase::GetWndClassName());
  46.  
  47.     BEGIN_MSG_MAP(thisClass)
  48.         CHAIN_MSG_MAP_ALT(ownerDrawClass, 1)
  49.         MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
  50.         MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
  51.         MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
  52.         MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
  53.         MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus)
  54.         MESSAGE_HANDLER(WM_SYSCOLORCHANGE, OnSysColorChange)
  55.         DEFAULT_REFLECTION_HANDLER()
  56.     END_MSG_MAP()
  57.  
  58.  
  59.     CMenuButtonT()
  60.     {
  61.         m_bPushed        = FALSE;
  62.         m_bLoaded        = FALSE;
  63.         m_bMenuPushed    = FALSE;
  64.         m_bMenuLoaded    = FALSE;
  65.         m_bDefaultBtn    = FALSE;
  66.  
  67.         ZeroMemory(&m_bm, sizeof(m_bm));
  68.         m_menu.CreatePopupMenu();
  69.     }
  70.  
  71.     virtual ~CMenuButtonT()
  72.     {
  73.     }
  74.  
  75.     BOOL SubclassWindow(HWND hWnd)
  76.     {
  77.         BOOL bResult = baseClass::SubclassWindow(hWnd);
  78.         m_pParentWnd = GetParent();
  79.         // Force BS_OWNERDRAW during subclassing
  80.         ModifyStyle(0, BS_OWNERDRAW); // Enforce
  81.         return bResult;
  82.     }
  83.  
  84.  
  85.     // Create the button
  86.     HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL,
  87.         DWORD dwStyle = 0, DWORD dwExStyle = 0,
  88.         UINT nID = 0, LPVOID lpCreateParam = NULL)
  89.     {
  90.         dwStyle |= BS_OWNERDRAW; // Enforce
  91.         m_pParentWnd = hWndParent;
  92.         return baseClass::Create(hWndParent, rcPos, szWindowName, dwStyle, dwExStyle, nID, lpCreateParam);
  93.     }
  94.  
  95.     // Sets the button image, COLORREF crMask specifics the transparency
  96.     BOOL SetButtonImage(HINSTANCE hInstance, UINT nResourceId, COLORREF crMask)
  97.     {
  98.         // The ID must exist also as a bitmap resource!!!
  99.         {
  100.             ATLASSERT(m_btnImage.m_hBitmap == NULL);
  101.             m_btnImage.m_hBitmap = ::LoadBitmap(hInstance, MAKEINTRESOURCE(nResourceId));
  102.             ATLASSERT(m_btnImage.m_hBitmap);
  103.         }
  104.         m_btnImage.GetBitmap(m_bm);
  105.         m_IL.Create( nResourceId, m_bm.bmWidth, 1, crMask );
  106.         m_bLoaded = TRUE;
  107.         m_crMask = crMask;
  108.  
  109.         HBITMAP bmTemp = NULL;
  110.         COLORMAP mapColor = { 0 };
  111.         mapColor.from = crMask;
  112.         mapColor.to  = RGB(255,255,255);
  113.  
  114.         bmTemp = (HBITMAP)::CreateMappedBitmap(hInstance, nResourceId, IMAGE_BITMAP, &mapColor, 1);
  115.         m_hbmpDisabled = (HBITMAP)::CopyImage(bmTemp, IMAGE_BITMAP, m_bm.bmWidth, m_bm.bmHeight, LR_COPYDELETEORG);
  116.  
  117.         return m_bLoaded;
  118.     }
  119.  
  120.     // Adds a menu item and id to our menu.
  121.     BOOL AddMenuItem(UINT nMenuId, const CString strMenu, UINT nMenuFlags)
  122.     {
  123.         BOOL bRet = m_menu.AppendMenu(nMenuFlags | MF_STRING, nMenuId, (LPCTSTR)strMenu);
  124.  
  125.         m_bMenuLoaded |= bRet;
  126.  
  127.         return bRet;
  128.     }
  129.  
  130.     // Enable/Disable a menu item
  131.     BOOL EnableMenuItem(UINT nMenuId,const CString strMenu, BOOL nEnable)
  132.     {
  133.         BOOL bRet = m_menu.EnableMenuItem(nMenuId , nEnable);
  134.         m_bMenuLoaded |= bRet;
  135.         return bRet;
  136.     }
  137.  
  138.     BOOL RemoveMenuItem(UINT nMenuId,const CString strMenu, UINT nMenuFlags)
  139.     {
  140.         BOOL bRet = m_menu.RemoveMenu( nMenuId,nMenuFlags | MF_STRING);
  141.         m_bMenuLoaded |= bRet;
  142.  
  143.         return bRet;
  144.     }
  145.  
  146.     // Adds Image to menu
  147.     void AddImage( int nIndex, CBitmap& bmpEnabled, CBitmap& bmpDisabled )
  148.     {
  149.         m_menu.SetMenuItemBitmaps( nIndex, MF_BYPOSITION, &bmpEnabled, &bmpDisabled );
  150.     }
  151.  
  152.     // Allow menu flags to be changed dynamically
  153.     void ChangeMenuFlags(UINT nMenuId, UINT nMenuFlags)
  154.     { 
  155.         m_menu.CheckMenuItem(nMenuId, nMenuFlags | MF_BYCOMMAND);
  156.     }
  157.  
  158.     // Call this to allow the button to a act as a default button
  159.     void SetDefaultButton(BOOL bDefault)
  160.     {
  161.         m_bDefaultBtn = bDefault;
  162.     }
  163.  
  164.     // Attributes
  165. protected:
  166.     CMenu        m_menu;
  167.     CBitmap      m_btnImage;
  168.     CImageList   m_IL;
  169.     BOOL         m_bPushed;
  170.     BOOL         m_bMenuPushed;
  171.     BOOL         m_bMenuLoaded;
  172.     BOOL         m_bDefaultBtn;
  173.     BOOL         m_bLoaded;
  174.     BITMAP       m_bm;
  175.     CWindow      m_pParentWnd;
  176.     COLORREF     m_crMask;
  177.     CBitmap      m_hbmpDisabled;
  178.  
  179. protected:
  180.     // Draws drop down arrow, we could use DrawFrameControl - a bit too messy
  181.     void DrawArrow(HDC hDC, CPoint ArrowTip)
  182.     {
  183.         CDCHandle pDC(hDC);
  184.         CPoint ptDest;
  185.  
  186.         CPenHandle pPen = pDC.GetCurrentPen();
  187.         LOGPEN logPen = { 0 };
  188.         pPen.GetLogPen(logPen);
  189.         pDC.SetPixel(ArrowTip, logPen.lopnColor);
  190.  
  191.         ArrowTip -= CPoint(1,1);
  192.         pDC.MoveTo(ArrowTip);
  193.  
  194.         ptDest = ArrowTip;
  195.         ptDest += CPoint(3,0);
  196.         pDC.LineTo(ptDest);
  197.  
  198.         ArrowTip -= CPoint(1,1);
  199.         pDC.MoveTo(ArrowTip);
  200.  
  201.         ptDest = ArrowTip;
  202.         ptDest += CPoint(5,0);
  203.         pDC.LineTo(ptDest);
  204.  
  205.         ArrowTip -= CPoint(1,1);
  206.         pDC.MoveTo(ArrowTip);
  207.  
  208.         ptDest = ArrowTip;
  209.         ptDest += CPoint(7,0);
  210.         pDC.LineTo(ptDest);
  211.     }
  212.  
  213.     // Helper function to test for menu button hit ...
  214.     BOOL HitMenuBtn(CPoint point)
  215.     {
  216.         if (!m_bMenuLoaded)
  217.         {
  218.             // Don't allow menu button drop down if no menu items are loaded
  219.             return FALSE;
  220.         }
  221.  
  222.         ClientToScreen(&point);
  223.  
  224.         CRect rect;
  225.         GetWindowRect(rect);
  226.         rect.left = rect.right - nDropBtnWidth;
  227.  
  228.         return rect.PtInRect(point);   
  229.     }
  230.  
  231.  
  232. public:
  233.     // Called in response to draw the button
  234.     void DrawItem(LPDRAWITEMSTRUCT lpDIS)
  235.     {
  236.         if (lpDIS->CtlType != ODT_BUTTON)
  237.             return;
  238.  
  239.         CFontHandle pFont = AtlGetStockFont(DEFAULT_GUI_FONT);
  240.  
  241.         CDC dcMem;
  242.         CBitmap bmp;
  243.  
  244.         CRect btnRect(lpDIS->rcItem);
  245.         CRect trueRect(btnRect);
  246.  
  247.         CDCHandle pDC(lpDIS->hDC);
  248.  
  249.         ////////////////////////////////////////
  250.         // Button Background                  //
  251.         ////////////////////////////////////////
  252.         CBrush brsh;
  253.         brsh.CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
  254.         pDC.FillRect(trueRect, brsh);
  255.  
  256.         BOOL bDisabled = ODS_DISABLED & lpDIS->itemState;
  257.  
  258.         if (m_bDefaultBtn)
  259.             btnRect.DeflateRect(1,1);
  260.  
  261.         CRect rectFocus(btnRect);
  262.  
  263.         rectFocus.DeflateRect(4,4);
  264.  
  265.         if (!m_bMenuPushed)
  266.             rectFocus.OffsetRect(m_bPushed,m_bPushed);
  267.  
  268.         rectFocus.right -= nDropBtnWidth;
  269.  
  270.  
  271.         ////////////////////////////////////////
  272.         // Button in a normal state           //
  273.         ////////////////////////////////////////
  274.         if (!m_bPushed || m_bMenuPushed)
  275.             pDC.DrawFrameControl(&btnRect,DFC_BUTTON,DFCS_BUTTONPUSH);
  276.  
  277.  
  278.         ////////////////////////////////////////
  279.         // Default Button State               //
  280.         ////////////////////////////////////////
  281.         if ((m_bDefaultBtn || m_bPushed) && !bDisabled)
  282.         {
  283.             pDC.FrameRect(&lpDIS->rcItem, AtlGetStockBrush(BLACK_BRUSH) );
  284.  
  285.             if (m_bPushed && !m_bMenuPushed)
  286.                 pDC.FrameRect(&btnRect, AtlGetStockBrush(BLACK_BRUSH) );
  287.         }
  288.  
  289.         ////////////////////////////////////////
  290.         // State Focus                        //
  291.         ////////////////////////////////////////
  292.         if (lpDIS->itemState & ODS_FOCUS || m_bPushed)
  293.             if (!m_bMenuPushed)
  294.                 pDC.DrawFocusRect(&rectFocus);
  295.  
  296.  
  297.         ////////////////////////////////////////
  298.         // Action Focus                       //
  299.         ////////////////////////////////////////
  300.         if ((lpDIS->itemAction & ODA_FOCUS))
  301.             if (!m_bMenuPushed)
  302.                 pDC.DrawFocusRect(&rectFocus);
  303.  
  304.  
  305.         ////////////////////////////////////////
  306.         // Draw out bitmap                    //
  307.         ////////////////////////////////////////
  308.  
  309.         // Draw out bitmap
  310.         if (m_bLoaded)
  311.         {
  312.             if (!bDisabled)
  313.             {
  314.                 ATLASSERT(pDC.m_hDC != NULL);
  315.                 CPoint pt(6+m_bPushed, 6+m_bPushed);
  316.                 CSize sz(m_bm.bmWidth, m_bm.bmHeight);
  317.                 CPoint ptOrigin(0,0);
  318.                 UINT fStyle = ILD_NORMAL;
  319.                 DWORD dwRop = SRCCOPY;
  320.                 COLORREF rgbBack = CLR_DEFAULT;
  321.                 COLORREF rgbFore = CLR_DEFAULT;
  322.                 DWORD fState = ILS_NORMAL;
  323.                 DWORD Frame = ILS_NORMAL; // ILS_PULSE;
  324.                 COLORREF crEffect = CLR_DEFAULT;
  325.  
  326.                 IMAGELISTDRAWPARAMS drawing = { 0 };
  327.  
  328.                 drawing.i = 0;
  329.                 drawing.hdcDst = pDC.m_hDC;
  330.                 drawing.x = pt.x;
  331.                 drawing.y = pt.y;
  332.                 drawing.cx = sz.cx;
  333.                 drawing.cy = sz.cy;
  334.                 drawing.xBitmap = ptOrigin.x;
  335.                 drawing.yBitmap = ptOrigin.y;
  336.                 drawing.rgbBk = rgbBack;
  337.                 drawing.rgbFg = rgbFore;
  338.                 drawing.fStyle = fStyle;
  339.                 drawing.dwRop = dwRop;
  340. #if (_WIN32_IE >= 0x501)
  341.                 drawing.fState = fState;
  342.                 drawing.Frame = Frame;
  343.                 drawing.crEffect = crEffect;
  344. #endif
  345.                 // ATLASSERT(m_IL.m_hImageList != NULL);
  346.                 drawing.cbSize = sizeof(IMAGELISTDRAWPARAMS);
  347.                 drawing.himl = m_IL.m_hImageList;
  348.  
  349.                 // m_IL.DrawIndirect(pDC,0,CPoint(6+m_bPushed,6+m_bPushed),
  350.                 //    CSize(m_bm.bmWidth, m_bm.bmHeight), CPoint(0,0),ILD_NORMAL);
  351.                 m_IL.DrawIndirect(&drawing);
  352.             }
  353.             else
  354.             {
  355.                 pDC.DrawState(CPoint(6+m_bPushed,6+m_bPushed),
  356.                     CSize(m_bm.bmWidth, m_bm.bmHeight),
  357.                     m_hbmpDisabled, DST_BITMAP | DSS_DISABLED);
  358.             }
  359.         }
  360.  
  361.  
  362.         ////////////////////////////////////////
  363.         // Draw out text                      //
  364.         ////////////////////////////////////////
  365.         CFontHandle fontOld = pDC.SelectFont(pFont);
  366.         CRect rectText(rectFocus);
  367.         rectFocus.left += m_bm.bmWidth + 2;
  368.  
  369.         CString strCaption;
  370.         GetWindowText(strCaption.GetBuffer(MAX_PATH), MAX_PATH);
  371.         strCaption.ReleaseBuffer();
  372.  
  373.         pDC.SetBkMode(TRANSPARENT);
  374.         pDC.SetBkColor(GetSysColor(COLOR_BTNFACE));
  375.  
  376.         if (ODS_DISABLED & lpDIS->itemState)
  377.         {
  378.             rectFocus.OffsetRect(1,1);
  379.             pDC.SetTextColor(GetSysColor(COLOR_WINDOW));
  380.             pDC.DrawText((LPCTSTR)strCaption, strCaption.GetLength(), rectFocus, DT_SINGLELINE|DT_CENTER|DT_VCENTER);
  381.  
  382.             rectFocus.OffsetRect(-1,-1);
  383.             pDC.SetTextColor(GetSysColor(COLOR_GRAYTEXT));
  384.             pDC.DrawText((LPCTSTR)strCaption, strCaption.GetLength(), rectFocus,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
  385.         }
  386.         else
  387.         {
  388.             pDC.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
  389.             pDC.DrawText((LPCTSTR)strCaption, strCaption.GetLength(), rectFocus, DT_SINGLELINE|DT_CENTER|DT_VCENTER);
  390.         }
  391.  
  392.         CRect rectSplit(btnRect);
  393.         rectSplit.DeflateRect(2,2);
  394.         rectSplit.right -= nDropBtnWidth;
  395.  
  396.  
  397.         ////////////////////////////////////////
  398.         // Drop down split                    //
  399.         ////////////////////////////////////////
  400.         CPen brFace;
  401.         brFace.CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW));
  402.         CPenHandle penOld = pDC.SelectPen(brFace);
  403.         pDC.MoveTo(rectSplit.right, rectSplit.top);
  404.         pDC.LineTo(rectSplit.right, rectSplit.bottom);
  405.  
  406.  
  407.         CPen brLite;
  408.         brLite.CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DHILIGHT));
  409.         pDC.SelectPen(brLite);
  410.         pDC.MoveTo(rectSplit.right+1 , rectSplit.top);
  411.         pDC.LineTo(rectSplit.right+1, rectSplit.bottom);
  412.  
  413.  
  414.         rectSplit.left = rectSplit.right;
  415.         rectSplit.right += nDropBtnWidth;
  416.  
  417.         CPoint pt(rectSplit.CenterPoint());
  418.         pt += CPoint(m_bPushed,m_bPushed);
  419.  
  420.         CPen penBlack;
  421.         penBlack.CreatePen(PS_SOLID, 1, bDisabled ? GetSysColor(COLOR_GRAYTEXT) : GetSysColor(COLOR_WINDOWTEXT));
  422.         pDC.SelectPen(penBlack);
  423.         DrawArrow(pDC,pt);
  424.  
  425.         ////////////////////////////////////////
  426.         // Drop down state                    //
  427.         ////////////////////////////////////////
  428.         if (m_bMenuPushed && !bDisabled)
  429.         {
  430.             rectSplit.InflateRect(1,1);
  431.             pDC.DrawEdge(rectSplit,BDR_SUNKENOUTER, BF_RECT);
  432.         }
  433.         pDC.SelectPen(penOld);
  434.         pDC.SelectFont(fontOld);
  435.     }
  436.  
  437.  
  438.     // Implementation
  439. public:
  440.  
  441.     // Generated message map functions
  442. public:
  443.     LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  444.     {
  445.         uMsg, wParam, lParam, bHandled;
  446.         LRESULT lResult = 0;
  447.  
  448.         UINT nFlags = (UINT) wParam;
  449.         CPoint point(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
  450.         if (m_bMenuPushed)
  451.         {
  452.             m_bMenuPushed = FALSE;
  453.             Invalidate();
  454.             return lResult;
  455.         }
  456.  
  457.         if (HitMenuBtn(point))
  458.         {
  459.             m_bMenuPushed = TRUE;
  460.             SetFocus();
  461.             Invalidate();
  462.  
  463.             CRect rc;
  464.             GetWindowRect(rc);
  465.  
  466.             int x = rc.left;
  467.             int y = rc.bottom;
  468.  
  469.             m_menu.TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON, x,y, m_pParentWnd);
  470.  
  471.             m_bMenuPushed = FALSE;
  472.         }
  473.         else
  474.         {
  475.             m_bPushed = TRUE;
  476.         }
  477.  
  478.         Invalidate();
  479.  
  480.         if (m_bPushed) {
  481.             lResult = DefWindowProc(uMsg, wParam, lParam);
  482.         }
  483.         return lResult;
  484.     }
  485.  
  486.     LRESULT OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  487.     {
  488.         uMsg, wParam, lParam, bHandled;
  489.         LRESULT lResult = 0;
  490.  
  491.         UINT nFlags = (UINT) wParam;
  492.         CPoint point(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
  493.  
  494.         if (m_bPushed)
  495.         {
  496.             m_bPushed = FALSE;
  497.             ReleaseCapture();
  498.             Invalidate();
  499.             m_pParentWnd.PostMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM) m_hWnd);
  500.         }
  501.         lResult = DefWindowProc(uMsg, wParam, lParam);
  502.         return lResult;
  503.     }
  504.  
  505.     LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  506.     {
  507.         uMsg, wParam, lParam, bHandled;
  508.         LRESULT lResult = 0;
  509.  
  510.         UINT nFlags = (UINT) wParam;
  511.         CPoint point(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
  512.  
  513.         if (m_bPushed)
  514.         {
  515.             ClientToScreen(&point);
  516.  
  517.             if (WindowFromPoint(point) != *this)
  518.             {
  519.                 m_bPushed = FALSE;
  520.                 ReleaseCapture();
  521.                 Invalidate();
  522.             }
  523.         }
  524.  
  525.         lResult = DefWindowProc(uMsg, wParam, lParam);
  526.         return lResult;
  527.     }
  528.  
  529.     LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  530.     {
  531.         LRESULT lResult = 0;
  532.         lResult = DefWindowProc(uMsg, wParam, lParam);
  533.         Invalidate();
  534.         return lResult;
  535.     }
  536.  
  537.     LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  538.     {
  539.         LRESULT lResult = 0;
  540.         lResult = DefWindowProc(uMsg, wParam, lParam);
  541.         return lResult;
  542.     }
  543.  
  544.     // Called when system colors change, force a button redraw
  545.     LRESULT OnSysColorChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  546.     {
  547.         LRESULT lResult = 0;
  548.         lResult = DefWindowProc(uMsg, wParam, lParam);
  549.         Invalidate();
  550.         return lResult;
  551.     }   
  552. };
  553.  
  554. class CMenuButton : public CMenuButtonT<CMenuButton>
  555. {
  556. public:
  557.     DECLARE_WND_SUPERCLASS(_T("CMenuButton"), GetWndClassName());
  558.  
  559. protected:
  560. private:
  561. };
  562.  
  563.  
  564. /////////////////////////////////////////////////////////////////////////////
  565. // CMenuButton
  566. // ========
  567. //
  568. // To Use:
  569. // 1. Create a Bitmap resource 16x15 Pixels normal default size for a toolbar
  570. //    bitmap.
  571. //
  572. // 2. Call CMenuButton on Create function.
  573. //
  574. // 3. add REFLECT_NOTIFICATIONS() macro to the BEGIN_MSG_MAP(CMainDlg) message handler list
  575. //
  576. // 4. Call SetButtonImage specificing the Transparency color reference.
  577. //    (Usally RGB(255, 0, 255) magenta)
  578. //
  579. // 5. Add menu items with AddMenuItem using nMenuFlags to add disabled and
  580. ///   seperator menu items
  581. //
  582. // 6. Add the appropiate ON_COMMAND handlers in the parent windows message map
  583. //
  584. // 7. Enjoy...
  585. //
  586.  
  587. #endif // !defined(AFX_MENUBTN_H__3A90681F_CE5F_11D3_808C_005004D6CF93__INCLUDED_)

一个古老的带位图的菜单 源码

WTL ,

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