重载DrawItem后,我试过直接return,但是还可以看见Menu的边框显示出来,只是一半的边框,看似阴影。
这个阴影我可以自己控制吗?需要重载什么函数?

解决方案 »

  1.   

    // SSMenu.h: interface for the SSMenu class.
    //
    //////////////////////////////////////////////////////////////////////#if !defined(AFX_SSMENU_H__A0F77499_BF1A_4977_B740_14240B7717D3__INCLUDED_)
    #define AFX_SSMENU_H__A0F77499_BF1A_4977_B740_14240B7717D3__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000#include <vector>
    #include "XPCDC.h"
    #include "XPImage.h"
    using namespace Xproer::Drawing;
    using namespace std;namespace Sesame
    {
    namespace UI
    {
    namespace Controls
    {
    /*
    时间:2009-6-27
    作者:ToTo
    说明:菜单
    */
    class CMenuItemInfo
    {
    public:
    CMenuItemInfo()
    {
    m_hIcon = NULL;
    }
    ~CMenuItemInfo()
    {
    DestroyIcon(m_hIcon);
    }
    public:
    CString m_strText;
    int m_nItemID;
    HICON m_hIcon;
    };

    class SSMenu :
    public CMenu
    {
    public:
    SSMenu(void);
    ~SSMenu(void);
    virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
    virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
    private:
    int m_nItemWidth; //菜单项宽度
    int m_nItemHeight; //菜单项高度
    int m_nLeftWidth; //左边宽度(即图标宽度)
    COLORREF m_clrNormalText;//正常状态文字颜色
    COLORREF m_clrSelectText;//选择状态文字颜色
    COLORREF m_clrDisabledText;//关闭状态文字颜色
    COLORREF m_clrSelectFrame; //被选择时菜单项的背景色
    COLORREF m_clrBK; //背景色
    COLORREF m_clrLeft; //左边的颜色
    CBitmap* m_pSeparatorImage; //分隔符
    vector<CMenuItemInfo*> m_vAllMenuItem; //保存所有菜单项
    CSize m_iconSize;
    private:
    void OwnerDraw(CMenu* pMenu, bool bTop); //将菜单设成自绘
    void DrawNormalItem(CDC* pDC, const CRect& itemRect, const CMenuItemInfo* pMenuItemInfo);//绘制正常状态的菜单项
    void DrawSelectItem(CDC* pDC, const CRect& itemRect, const CMenuItemInfo* pMenuItemInfo);//绘制选择状态的菜单项
    void DrawDisabledItem(CDC* pDC, const CRect& itemRect, const CMenuItemInfo* pMenuItemInfo);//绘制关闭状态的菜单项
    void DrawSeparator(CDC* pDC, const CRect& itemRect);//绘制分隔条
    void DrawIcon(CDC* pDC, const CRect& itemRect, const CMenuItemInfo* pMenuItemInfo);//绘制图标
    public:
    void Init(const CString& strBmpSeparator = "", COLORREF clrNormalText = 0,
    COLORREF clrSelectText = 16777215,COLORREF clrDisabledText = 7171437, COLORREF clrSelectFrame = 14789120,
    COLORREF clrBK = 16642787, COLORREF clrLeft = 16574407);//初始化
    void SetItemWH(int nItemWidth = 120, int nItemHeight = 20); //设置菜单项的宽高
    void SetLeftWidth(int nLeftWidth); //设置左边的宽度
    void AddIconToItem(int nIndexItem, const CString& strIcon);
    };
    }
    }
    }#endif // !defined(AFX_SSMENU_H__A0F77499_BF1A_4977_B740_14240B7717D3__INCLUDED_)
    // SSMenu.cpp: implementation of the SSMenu class.
    //
    //////////////////////////////////////////////////////////////////////#include "stdafx.h"
    #include "XproeIm.h"
    #include "SSMenu.h"#ifdef _DEBUG
    #undef THIS_FILE
    static char THIS_FILE[]=__FILE__;
    #define new DEBUG_NEW
    #endif//////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////
    using namespace Sesame::UI::Controls;
    SSMenu::SSMenu(void)
    {
    m_nItemWidth = 150;
    m_nItemHeight = 20;
    m_nLeftWidth = 25;
    m_iconSize.cx = 16;
    m_iconSize.cy = 16;
    }
    SSMenu::~SSMenu(void)
    {
    for (int nIndex = 0; nIndex < m_vAllMenuItem.size(); ++nIndex)
    {
    delete m_vAllMenuItem[nIndex];
    }
    m_vAllMenuItem.clear();
    m_pSeparatorImage->DeleteObject();
    }
    void SSMenu::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
    {
    CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
    pDC->SetBkMode(TRANSPARENT);
    CMenuItemInfo* pMenuItemInfo = (CMenuItemInfo*)lpDrawItemStruct->itemData; //左边背景色
    pDC->FillSolidRect(CRect(lpDrawItemStruct->rcItem.left, lpDrawItemStruct->rcItem.top,
    lpDrawItemStruct->rcItem.left + m_nLeftWidth, lpDrawItemStruct->rcItem.bottom), m_clrLeft);
    //右边背景色
    pDC->FillSolidRect(CRect(lpDrawItemStruct->rcItem.left + m_nLeftWidth, lpDrawItemStruct->rcItem.top,
    lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom), m_clrBK); if (0 != pMenuItemInfo->m_nItemID)
    {//画选项
    if ((lpDrawItemStruct->itemState & ODS_SELECTED))
    {
    DrawSelectItem(pDC, lpDrawItemStruct->rcItem, pMenuItemInfo);
    }
    else if ((lpDrawItemStruct->itemState & ODS_DISABLED))
    {
    DrawDisabledItem(pDC, lpDrawItemStruct->rcItem, pMenuItemInfo);
    }
    else
    {
    DrawNormalItem(pDC, lpDrawItemStruct->rcItem, pMenuItemInfo);
    } if (lpDrawItemStruct->itemState & ODS_CHECKED)
    {
    pDC->TextOut(lpDrawItemStruct->rcItem.left + 7, lpDrawItemStruct->rcItem.top + 2,
    "√");
    }
    else
    {
    DrawIcon(pDC, lpDrawItemStruct->rcItem, pMenuItemInfo);
    }
    }
    else
    {//画分隔条
    DrawSeparator(pDC, lpDrawItemStruct->rcItem);
    }}
    void SSMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
    {
    lpMeasureItemStruct->itemWidth = m_nItemWidth;
    lpMeasureItemStruct->itemHeight = m_nItemHeight;

    if (0 == lpMeasureItemStruct->itemID)//分隔符
    {
    lpMeasureItemStruct->itemHeight = 5;
    }
    }void SSMenu::DrawIcon(CDC* pDC, const CRect& itemRect, const CMenuItemInfo* pMenuItemInfo)
    {
    //pDC->DrawIcon(itemRect.left, itemRect.top, pMenuItemInfo->m_hIcon);这种方法绘出来的图标大小偏大
    int nXLeft = itemRect.left + (m_nLeftWidth - m_iconSize.cx) / 2;
    int nYTop = itemRect.top + (m_nItemHeight - m_iconSize.cy) / 2;
    ::DrawIconEx(pDC->m_hDC, nXLeft, nYTop, pMenuItemInfo->m_hIcon,
    m_iconSize.cx, m_iconSize.cy, 0, NULL, DI_NORMAL);
    }void SSMenu::DrawSeparator(CDC* pDC, const CRect& itemRect)
    {
      XPCDC::DrawBitmap(m_pSeparatorImage, pDC, itemRect.left + m_nLeftWidth, itemRect.top,
      93, 4);
    }void SSMenu::OwnerDraw(CMenu* pMenu, bool bTop)
    {
    int nItemCount = pMenu->GetMenuItemCount();//决定弹出菜单或顶层菜单的项数。
    for (int nIndex = 0; nIndex < nItemCount; ++nIndex)
    {
    CMenuItemInfo* pMenuItemInfo = new CMenuItemInfo();
    pMenu->GetMenuString(nIndex, pMenuItemInfo->m_strText, MF_BYPOSITION);
    pMenuItemInfo->m_nItemID = pMenu->GetMenuItemID(nIndex);
    pMenu->ModifyMenu(nIndex, MF_OWNERDRAW | MF_BYPOSITION | MF_STRING, pMenuItemInfo->m_nItemID,
    (LPSTR)pMenuItemInfo);

    if (!bTop)
    {
    //不存放最顶层的子菜单项
    m_vAllMenuItem.push_back(pMenuItemInfo);
    }
    ////////////////////////////////////////////////////
    else//gxy修改
    {
    delete pMenuItemInfo;
    pMenuItemInfo = NULL;
    }
    ///////////////////////////////////////////////////
    CMenu* pSubMenu = pMenu->GetSubMenu(nIndex);
    if (pSubMenu)
    {
    OwnerDraw(pSubMenu, false);
    }
    }
    }void SSMenu::SetItemWH(int nItemWidth, int nItemHeight)
    {
    m_nItemWidth = nItemWidth;
    m_nItemHeight = nItemHeight;
    }void SSMenu::Init(const CString& strBmpSeparator, COLORREF clrNormalText,
       COLORREF clrSelectText,COLORREF clrDisabledText, COLORREF clrSelectFrame,
       COLORREF clrBK, COLORREF clrLeft)
    {
    m_clrNormalText = clrNormalText;//正常状态文字颜色
    m_clrSelectText = clrSelectText;//选择状态文字颜色
    m_clrDisabledText = clrDisabledText;//关闭状态文字颜色
    m_clrSelectFrame = clrSelectFrame; //被选择时菜单项的背景色
    m_clrBK = clrBK; //背景色
    m_clrLeft = clrLeft; //左边的颜色
    m_pSeparatorImage = XPImage::FromFile(strBmpSeparator);//分隔符
    OwnerDraw(this, true);
    }void SSMenu::SetLeftWidth(int nLeftWidth)
    {
    m_nLeftWidth = nLeftWidth;
    }void SSMenu::DrawNormalItem(CDC* pDC, const CRect& itemRect, const CMenuItemInfo* pMenuItemInfo)
    {
    //1.绘文字
    CRect textRect = itemRect;
    textRect.left += m_nLeftWidth + 2;
    pDC->SetTextColor(m_clrNormalText);
    pDC->DrawText(pMenuItemInfo->m_strText, textRect, DT_SINGLELINE|DT_VCENTER);
    }void SSMenu::DrawSelectItem(CDC* pDC, const CRect& itemRect, const CMenuItemInfo* pMenuItemInfo)
    {
    //1.绘边框
    pDC->FillSolidRect(itemRect, m_clrSelectFrame);
    //2.绘文字
    CRect textRect = itemRect;
    textRect.left += m_nLeftWidth + 10;
    pDC->SetTextColor(m_clrSelectText);
    pDC->DrawText(pMenuItemInfo->m_strText, textRect, DT_SINGLELINE|DT_VCENTER);
    }void SSMenu::DrawDisabledItem(CDC* pDC, const CRect& itemRect, const CMenuItemInfo* pMenuItemInfo)
    {
    //1.绘文字
    CRect textRect = itemRect;
    textRect.left += m_nLeftWidth + 2;
    pDC->SetTextColor(m_clrDisabledText);
    pDC->DrawText(pMenuItemInfo->m_strText, textRect, DT_SINGLELINE|DT_VCENTER);
    }void SSMenu::AddIconToItem(int nIndexItem, const CString& strIcon)
    {
    if (nIndexItem >=0 && nIndexItem < m_vAllMenuItem.size())
    {
    m_vAllMenuItem[nIndexItem]->m_hIcon = (HICON)::LoadImage(NULL, strIcon, IMAGE_ICON,
    m_iconSize.cx, m_iconSize.cy, LR_LOADFROMFILE);
    }
    }
      

  2.   

    这个是XperoeIm里面的自绘菜单函数,楼主可以试试这个。