Click here to Skip to main content
15,895,084 members
Articles / Desktop Programming / MFC

Owner Drawn Menu with Icons, Titles and Shading

Rate me:
Please Sign up or sign in to vote.
4.95/5 (205 votes)
5 Dec 2003CPOL12 min read 2.8M   35K   522  
An easy use of owner drawn menu with variable styles like new Office products with titles, shading and icons.
// PopupTestView.cpp : implementation of the CPopupTestView class
//

#include "stdafx.h"
#include "PopupTest.h"

#include "PopupTestDoc.h"
#include "PopupTestView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CPopupTestView

IMPLEMENT_DYNCREATE(CPopupTestView, CView)

BEGIN_MESSAGE_MAP(CPopupTestView, CView)
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
ON_WM_CONTEXTMENU()

ON_WM_MEASUREITEM()
ON_WM_MENUCHAR()
ON_WM_INITMENUPOPUP()
END_MESSAGE_MAP()

// CPopupTestView construction/destruction

CPopupTestView::CPopupTestView()
{
  // TODO: add construction code here
  
}

CPopupTestView::~CPopupTestView()
{
}

BOOL CPopupTestView::PreCreateWindow(CREATESTRUCT& cs)
{
  // TODO: Modify the Window class or styles here by modifying
  //  the CREATESTRUCT cs
  
  return CView::PreCreateWindow(cs);
}

// CPopupTestView drawing

void CPopupTestView::OnDraw(CDC* /*pDC*/)
{
  CPopupTestDoc* pDoc = GetDocument();
  ASSERT_VALID(pDoc);
  
  // TODO: add draw code for native data here
}


// CPopupTestView printing

BOOL CPopupTestView::OnPreparePrinting(CPrintInfo* pInfo)
{
  // default preparation
  return DoPreparePrinting(pInfo);
}

void CPopupTestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
  // TODO: add extra initialization before printing
}

void CPopupTestView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
  // TODO: add cleanup after printing
}


// CPopupTestView diagnostics

#ifdef _DEBUG
void CPopupTestView::AssertValid() const
{
  CView::AssertValid();
}

void CPopupTestView::Dump(CDumpContext& dc) const
{
  CView::Dump(dc);
}

CPopupTestDoc* CPopupTestView::GetDocument() const // non-debug version is inline
{
  ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPopupTestDoc)));
  return (CPopupTestDoc*)m_pDocument;
}
#endif //_DEBUG


// CPopupTestView message handlers
static CString GetShort(UINT id)
{
  CString str;
  str.LoadString(id);
  int nIndex = str.ReverseFind(_T('\n'));
  if(nIndex!=-1)
  {
    str=str.Mid(nIndex+1);
  }
  return str;
}

void CPopupTestView::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) 
{
  CView::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);

  // Do this call at the end. After you have changed your menu items.
  CNewMenu::OnInitMenuPopup(m_hWnd,pPopupMenu, nIndex, bSysMenu);
}

void CPopupTestView::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMIS) 
{
  if(!CNewMenu::OnMeasureItem(GetCurrentMessage()))
  {
    CView::OnMeasureItem(nIDCtl, lpMIS);
  }
} 

LRESULT CPopupTestView::OnMenuChar(UINT nChar, UINT nFlags, CMenu* pMenu) 
{
  LRESULT lresult;
  if( DYNAMIC_DOWNCAST(CNewMenu,pMenu) )
    lresult=CNewMenu::FindKeyboardShortcut(nChar, nFlags, pMenu);
  else
    lresult=CView::OnMenuChar(nChar, nFlags, pMenu);
  
  return lresult;
}

void CPopupTestView::OnContextMenu(CWnd* pWnd, CPoint point)
{
  UNREFERENCED_PARAMETER(pWnd);

  if(point.x==-1 && point.y==-1)
  {
    CRect rect;
    GetWindowRect(rect);
    
    point = rect.TopLeft()+CPoint(10,10);
  }
  SetFocus();
  
  // Change the menu-style. After showing the popup the old style will be resored
  CNewMenuHelper doSetMenuStyle(CNewMenu::STYLE_XP);
  // Keep in mind you must have set a previous menustyle.
  // Default style is STYLE_XP, but I have changed it in BOOL CPopupTestApp::InitInstance()

  CNewMenu menu;
  menu.CreatePopupMenu();
  menu.InsertMenu(0, MF_BYPOSITION , ID_EDIT_UNDO, GetShort(ID_EDIT_UNDO));
  menu.InsertMenu(1, MF_BYPOSITION|MF_SEPARATOR);
  menu.InsertMenu(2, MF_BYPOSITION , ID_EDIT_COPY, GetShort(ID_EDIT_COPY));
  menu.InsertMenu(2, MF_BYPOSITION , ID_EDIT_CUT, GetShort(ID_EDIT_CUT));
  menu.InsertMenu(4, MF_BYPOSITION , ID_EDIT_CLEAR, GetShort(ID_EDIT_CLEAR));
  menu.InsertMenu(5, MF_BYPOSITION , ID_EDIT_PASTE, GetShort(ID_EDIT_PASTE));
  menu.InsertMenu(6, MF_BYPOSITION|MF_SEPARATOR);
  
  menu.InsertMenu(7, MF_BYPOSITION , ID_EDIT_SELECT_ALL,GetShort(ID_EDIT_SELECT_ALL));
  menu.InsertMenu(8, MF_BYPOSITION|MF_SEPARATOR);
  menu.InsertMenu(9, MF_BYPOSITION , ID_FILE_NEW,_T("Test file new"));
  
  menu.SetMenuTitle(_T("Edit commands"),MFT_GRADIENT|MFT_SIDE_TITLE|MFT_LINE);
  
  CNewMenu* pSubMenu = menu.AppendODPopupMenu(_T("NewMenu"));
  pSubMenu->SetBitmapBackground(RGB(192,192,192));
  UINT nIDs[] = {IDB_FILE_A,IDB_FILE_B,IDB_FOLDER_A,IDB_FOLDER_B};
  for(int n=0;n<80;n++)
  {
    CString str;
    str.Format(_T("File %2ld"),1+n);
    pSubMenu->InsertODMenu(n, str,MF_BYPOSITION , n+10000, nIDs[n&3]);
    // Enabling and disabling items
    pSubMenu->EnableMenuItem(n, MF_BYPOSITION | ((n&4) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
  }
  
  pSubMenu = menu.AppendODPopupMenu(_T("NewMenu Sub"));
  pSubMenu->InsertMenu(0, MF_BYPOSITION , ID_EDIT_UNDO, GetShort(ID_EDIT_UNDO));;
  pSubMenu->InsertMenu(1, MF_BYPOSITION | MF_SEPARATOR);
  pSubMenu->InsertMenu(2, MF_BYPOSITION , ID_EDIT_COPY, GetShort(ID_EDIT_COPY));
  
  pSubMenu = pSubMenu->AppendODPopupMenu(_T("NewMenu Sub 3"));
  pSubMenu->InsertMenu(0, MF_BYPOSITION , ID_EDIT_UNDO, GetShort(ID_EDIT_UNDO));;
  pSubMenu->InsertMenu(1, MF_BYPOSITION | MF_SEPARATOR);
  pSubMenu->InsertMenu(2, MF_BYPOSITION , ID_EDIT_COPY, _T("&Copy"));
  pSubMenu->InsertMenu(3, MF_BYPOSITION , ID_EDIT_CLEAR, _T(""));
  
  menu.LoadToolBar(IDR_MAINFRAME); 
  menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, point.x, point.y, this);
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Switzerland Switzerland
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions