mii.fMask = MIIM_FTYPE | MIIM_DATA; mii.fType |= MF_OWNERDRAW; mii.dwItemData = (DWORD)pInfo; // set user define data for draw if (mii.hSubMenu != NULL) // this is a popupmenu { COfficeMenu *pSubMenu = reinterpret_cast<COfficeMenu*>(pMenu->GetSubMenu(i)); SetMenuOwnerDraw(pSubMenu->m_hMenu); }
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1; m_menu.SetMainWnd(GetSafeHwnd());
CMenu *pMenu = GetMenu();
m_menu.FromHandle(pMenu->GetSafeHmenu());
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
} if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
} // TODO: Delete these three lines if you don't want the toolbar to
// be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar); return 0;
}在自画菜单里.头文件
#include <vector>
#include <list>
#include <algorithm>
#include <functional>using namespace std;class COfficeMenu : public CMenu
{
typedef struct menu_item_info {
HICON hIcon;
TCHAR szTitle[MAX_PATH];
UINT uStyle;
UINT uID;
bool bSperator:1;
} MENUDATAINFO, *PMENUDATAINFO, *LPMENUDATAINFO;
public:
COfficeMenu();
virtual ~COfficeMenu(); enum {DRAW_BITMAP, DRAW_GRADIENT, DRAW_OFFICE2003} m_nDrawStyle;
public:
BOOL FromHandle(HMENU);
BOOL CreateOfficeMenu(UINT uIDRes);
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItem);
void SetMainWnd(HWND hWnd) {
m_hWndMain = hWnd;
}
protected:
virtual void SetMenuOwnerDraw(HMENU hMenu);
virtual void DrawItem(LPDRAWITEMSTRUCT lpds);
void Cleanup();
protected:
vector<LPMENUDATAINFO> m_vtInfo;
HWND m_hWndMain;
};#endif // !defined(AFX_OFFICEMENU1_H__75C7C88F_63B0_4416_AE71_997ED2D3DB23__INCLUDED_)cpp文件
#include "stdafx.h"
#include "OfficeMenu.h"
#include "OfficeMenu1.h"
#include "strsafe.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////COfficeMenu::COfficeMenu()
{}COfficeMenu::~COfficeMenu()
{
Cleanup();
}
BOOL COfficeMenu::CreateOfficeMenu(UINT uIDRes)
{
CMenu::LoadMenu(uIDRes); // Change all menu to ownerdraw style
SetMenuOwnerDraw(m_hMenu); return TRUE;
}void COfficeMenu::SetMenuOwnerDraw(HMENU hMenu)
{
ASSERT(hMenu);
COfficeMenu *pMenu = reinterpret_cast<COfficeMenu*>(CMenu::FromHandle(hMenu));
pMenu->AssertValid();
INT nCount = pMenu->GetMenuItemCount();
for (int i = 0; i < nCount; ++i)
{
// Check this menu item is the popup
MENUITEMINFO mii;
memset(&mii, 0, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_SUBMENU | MIIM_STRING | MIIM_FTYPE | MIIM_ID;
VERIFY(pMenu->GetMenuItemInfo(i, &mii, TRUE));
menu_item_info *pInfo = new menu_item_info;
memset(pInfo, 0, sizeof(menu_item_info));
::GetMenuString(hMenu, i, pInfo->szTitle, MAX_PATH, MF_BYPOSITION);
pInfo->uID = pMenu->GetMenuItemID(i);
pInfo->uStyle = mii.fState;
pInfo->bSperator = pInfo->uID ? 0 : 1;
TRACE(_T("%s\n"), pInfo->szTitle);
mii.fMask = MIIM_FTYPE | MIIM_DATA;
mii.fType |= MF_OWNERDRAW;
mii.dwItemData = (DWORD)pInfo; // set user define data for draw
if (mii.hSubMenu != NULL) // this is a popupmenu
{
COfficeMenu *pSubMenu = reinterpret_cast<COfficeMenu*>(pMenu->GetSubMenu(i));
SetMenuOwnerDraw(pSubMenu->m_hMenu);
}
mii.fType |= MF_OWNERDRAW;
mii.fMask = MIIM_FTYPE | MIIM_DATA;
VERIFY(SetMenuItemInfo(hMenu, i, TRUE, &mii));
// test if set for ownerdraw ok
#ifdef _DEBUG
memset(&mii, 0, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_FTYPE | MIIM_ID;
::GetMenuItemInfo(hMenu, i, TRUE, &mii); ASSERT(mii.fType & MF_OWNERDRAW);
#endif
// add to vector container
m_vtInfo.push_back(pInfo);
} pMenu->Detach();
}
void COfficeMenu::Cleanup()
{
vector<LPMENUDATAINFO>::iterator itor = m_vtInfo.begin();
for (; itor != m_vtInfo.end(); ++itor)
{
delete *itor;
} // for m_vtInfo.clear();
}void COfficeMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItem)
{
SIZE size; // contian menuitem's width and height
size_t nLen; // text length
HDC hdc; // Main wnd dc
LRESULT lRet; LPMENUDATAINFO pInfo = (LPMENUDATAINFO)lpMeasureItem->itemData;
ASSERT(pInfo);
hdc = GetWindowDC(m_hWndMain); lRet = ::StringCchLength(pInfo->szTitle, MAX_PATH, &nLen);
if (FAILED(lRet))
{
return ;
}
::GetTextExtentPoint32(hdc, pInfo->szTitle, _tcslen(pInfo->szTitle), &size); lpMeasureItem->itemWidth = size.cx;
lpMeasureItem->itemHeight = size.cy; ReleaseDC(m_hWndMain, hdc);
}void COfficeMenu::DrawItem(LPDRAWITEMSTRUCT lpds)
{
CDC *pdc = NULL;
CRect rt = lpds->rcItem;
LPMENUDATAINFO pInfo = (LPMENUDATAINFO)lpds->itemData;
pdc = CDC::FromHandle(lpds->hDC); switch (lpds->itemAction)
{
case ODA_DRAWENTIRE:
{
CBrush brh;
brh.CreateSolidBrush(RGB(0XFF, 0, 0XFF));
pdc->DrawText(pInfo->szTitle, &rt, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
break;
default:
break;
}
}BOOL COfficeMenu::FromHandle(HMENU hMenu)
{
SetMenuOwnerDraw(hMenu);
return TRUE;
}可是没有调用MeasureItem.我已经写下了Mainframe 的OnMeasureItem里加了的