Click here to Skip to main content
Click here to Skip to main content

Owner drawn menu with bitmaps, icons, and colors

, 8 Sep 2002
Rate this:
Please Sign up or sign in to vote.
Use application resources to create your owner drawn menu. 

Sample Image - MenuCH.jpg

Introduction

The article presents an implementation of an owner drawn menu with the Windows XP and Icon select style. To use this code download the demo project. The demo project has 3 menu styles which demonstrate how to create XP menu and Icon selected menu. To add owner drawn menus to your own project follow these 6 steps:

Step 1

Add the following files to your project:

  • MenuCH.cpp
  • MenuCH.h

Step 2

In MainFrm.h - add this line to the top of the file:

#include "MenuCH.h"

Step 3

In MainFrm.h - Add CMainFrame member variables of type CMenuCH.

protected:  // control bar embedded members
    CStatusBar  m_wndStatusBar;
    CToolBar    m_wndToolBar;
    CMenuCH    m_FileMenu, m_EditMenu,
        m_ViewMenu, m_HelpMenu;
    CMenuCH    m_ElementMenu;
    CMenuCH    GraphMenu,ColorMenu;

Step 4

In MainFrm.cpp - place the following statements in CMainFrame()

/////////////////////////////////////////////////////////
// CMainFrame construction/destruction

CMainFrame::CMainFrame()
{
    // TODO: add member initialization code here
    m_FileMenu.CreatePopupMenu();
    m_FileMenu.SetMenuHeight(20);
    m_FileMenu.SetMenuWidth(150);
    m_FileMenu.SetMenuType(MIT_XP);
    m_FileMenu.AppendMenu(MF_ENABLED,ID_FILE_NEW,
        "&New\tCtrl+N",IDB_NEW);
    m_FileMenu.AppendMenu(MF_ENABLED,ID_FILE_OPEN,
        "&Open\tCtrl+O",IDB_OPEN);
    m_FileMenu.AppendMenu(MF_ENABLED,ID_FILE_CLOSE,
        "&Close");
    m_FileMenu.AppendMenu(MF_ENABLED,ID_FILE_SAVE,
        "&Save\tCtrl+S",IDB_SAVE);
    m_FileMenu.AppendMenu(MF_ENABLED,ID_FILE_SAVE_AS,
        "Save &As...");
    m_FileMenu.AppendMenu(MF_SEPARATOR,0,"");
    m_FileMenu.AppendMenu(MF_ENABLED,ID_FILE_PRINT,
        "&Print...",IDB_PRINT);
    m_FileMenu.AppendMenu(MF_ENABLED,ID_FILE_PRINT_PREVIEW,
        "Print Pre&view");
    m_FileMenu.AppendMenu(MF_ENABLED,ID_FILE_PRINT_SETUP,
        "P&rint Setup...");
    m_FileMenu.AppendMenu(MF_SEPARATOR,0,"");
    m_FileMenu.AppendMenu(MF_ENABLED,ID_APP_EXIT,
        "E&xit");

    m_EditMenu.CreatePopupMenu();
    m_EditMenu.SetMenuHeight(20);
    m_EditMenu.SetMenuWidth(165);
    m_EditMenu.SetMenuType(MIT_XP);
    m_EditMenu.AppendMenu(MF_ENABLED,ID_EDIT_UNDO,
        "Redo\tCtrl+Z",IDB_UNDO);
    m_EditMenu.AppendMenu(MF_ENABLED,ID_EDIT_REDO,
        "Undo\tCtrl+Y",IDB_REDO);
    m_EditMenu.AppendMenu(MF_SEPARATOR,0,"");
    m_EditMenu.AppendMenu(MF_ENABLED,ID_EDIT_CUT, 
        "Cut\tCtrl+X",IDB_CUT);
    m_EditMenu.AppendMenu(MF_ENABLED,ID_EDIT_COPY, 
        "Copy\tCtrl+C",IDB_COPY);
    m_EditMenu.AppendMenu(MF_ENABLED,ID_EDIT_PASTE,
        "Paste\tCtrl+V",IDB_PASTE);


    m_ViewMenu.CreatePopupMenu();
    m_ViewMenu.SetMenuHeight(20);
    m_ViewMenu.SetMenuWidth(170);
    m_ViewMenu.SetMenuType(MIT_XP);
    m_ViewMenu.AppendMenu(MF_ENABLED,ID_VIEW_TOOLBAR, 
        "&Toolbar");
    m_ViewMenu.AppendMenu(MF_ENABLED,ID_VIEW_STATUS_BAR,
        "&Status Bar");

    m_HelpMenu.CreatePopupMenu();
    m_HelpMenu.SetMenuHeight(20);
    m_HelpMenu.SetMenuWidth(160);
    m_HelpMenu.SetMenuType(MIT_XP);
    m_HelpMenu.AppendMenu(MF_ENABLED,ID_APP_ABOUT,
        "&About BmpMenuDemo...",IDB_HELP);

    GraphMenu.CreateMenu();
    GraphMenu.AppendMenu(MF_ENABLED,ID_GRAPHPART1BOX,"",
        NULL,AfxGetApp()->LoadIcon(IDI_LINE));
    GraphMenu.AppendMenu(MF_ENABLED,ID_GRAPHPART2BOX,"",
        NULL,AfxGetApp()->LoadIcon(IDI_GRAPHIC));
    GraphMenu.AppendMenu(MF_ENABLED|MF_MENUBREAK,ID_GRAPHPART3BOX,
        "",NULL,AfxGetApp()->LoadIcon(IDI_CIRCLE));
    GraphMenu.AppendMenu(MF_ENABLED,ID_GRAPHPART4BOX,"",
        NULL,AfxGetApp()->LoadIcon(IDI_POLYGON));
    GraphMenu.AppendMenu(MF_ENABLED|MF_MENUBREAK,
        ID_GRAPHPART5BOX,"",NULL,AfxGetApp()->LoadIcon(IDI_ARC));
    GraphMenu.AppendMenu(MF_ENABLED,ID_GRAPHPART6BOX,"",
        NULL,AfxGetApp()->LoadIcon(IDI_TEXT));

    m_ElementMenu.CreatePopupMenu();
    m_ElementMenu.SetMenuType(MIT_ICON);
    m_ElementMenu.AppendMenu(MF_SEPARATOR,0,"");
    m_ElementMenu.AppendMenu(MF_POPUP,
        (UINT)GraphMenu.m_hMenu,"Element");

    ColorMenu.CreatePopupMenu();
    ColorMenu.SetMenuHeight(18);
    ColorMenu.SetMenuWidth(6);
    ColorMenu.SetMenuType(MIT_COLOR);
    char clrValue[64];
    for(int i=1; i<=16; i++)
    {
        wsprintf(clrValue,"%d",rgbColors[i-1]);
        if( i%4 == 1 )
            ColorMenu.AppendMenu(MF_MENUBREAK|MF_ENABLED,
            i,clrValue);
        else
            ColorMenu.AppendMenu(MF_ENABLED,i,clrValue);
    }
    m_ElementMenu.AppendMenu(MF_POPUP,(UINT)ColorMenu.m_hMenu,
        "Colors");
}

Step 5

In MainFrm.cpp - Add CMainFrame member function CreateMenu() and place the following statements:

///////////////////////////////////////////////////////
// CMainFrame message handlers
void CMainFrame::CreateMenu()
{
    CMenu* pMenu = this->GetMenu();
    pMenu->RemoveMenu(0,MF_BYPOSITION);
    pMenu->RemoveMenu(0,MF_BYPOSITION);
    pMenu->RemoveMenu(0,MF_BYPOSITION);
    pMenu->RemoveMenu(0,MF_BYPOSITION);
    pMenu->RemoveMenu(0,MF_BYPOSITION);

    pMenu->InsertMenu(0,MF_BYPOSITION|MF_POPUP,
        (UINT)m_FileMenu.m_hMenu,"&File");  
    pMenu->InsertMenu(1,MF_BYPOSITION|MF_POPUP,
        (UINT)m_EditMenu.m_hMenu,"&Edit");
    pMenu->InsertMenu(2,MF_BYPOSITION|MF_POPUP,
        (UINT)m_ViewMenu.m_hMenu,"&View");
    pMenu->InsertMenu(3,MF_BYPOSITION|MF_POPUP,
        (UINT)m_HelpMenu.m_hMenu,"&Help");
    pMenu->InsertMenu(4,MF_BYPOSITION|MF_POPUP,
        (UINT)m_ElementMenu.m_hMenu,"&Element");
}

Step 6

In MainFrm.cpp - call CreateMenu() in CMainFrame::OnCreate.

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
    ...

        CreateMenu();
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

chia hung liu
Web Developer
Taiwan Taiwan
I'm a software engineer for a R&D department developing specialised user interface software for the automation industry.
 
I enjoy coding and researching algorithm.

Comments and Discussions

 
GeneralThanks Bro It works vote 5+ Pinmemberomkarpardeshi12327-Sep-12 2:28 
GeneralCFont PinmemberVishal Lakhanpal24-Apr-07 5:20 
Questionhow to set my menus back color by API directly? Pinmemberzhyaaa12310-Oct-06 20:41 
QuestionHow to use CMenuCH in mouse right click popup menu? Pinmembermaohbao10-Oct-06 2:22 
AnswerRe: How to use CMenuCH in mouse right click popup menu? Pinmemberdenny lu10-Jun-07 0:02 
Generalwhy the hot key can't work Pinmemberjohnxie30-Mar-06 16:32 
GeneralMenu access keys PinmemberOle Martin Brynildsen19-Apr-05 23:31 
GeneralI only want to change font for menu caption PinsussAnonymous15-Oct-03 19:36 
GeneralJust what I wanted PinsussAlton Williams30-May-03 23:26 
QuestionNon Doc/View application compatible? PinmemberSteveBob31-Dec-02 11:35 
QuestionWhy? Pinmemberhien_ng8028-Oct-02 1:33 
AnswerRe: Why? Pinmemberchia hung liu1-Jan-03 15:41 
GeneralI have problem with PopUp Menu Pinmemberthanh200224-Oct-02 7:31 
GeneralRe: I have problem with PopUp Menu PinsussAnonymous27-Oct-02 16:20 
GeneralCMenuCh PinmemberOld Timer25-Sep-02 8:49 

I used the CMenuCH class in a dialog application and it worked just fine.
 
I added the following;
 
int MainDialog::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
//...other stuff
 
CreateMenu();
}
 
void CWoodCalcDlg::CreateMenu()
{
CMenu* pMenu = this->GetMenu();
pMenu->RemoveMenu(0,MF_BYPOSITION);
pMenu->RemoveMenu(0,MF_BYPOSITION);
 
pMenu->InsertMenu(0,MF_BYPOSITION|MF_POPUP,(UINT)m_FileMenu.m_hMenu,"&File");
pMenu->InsertMenu(1,MF_BYPOSITION|MF_POPUP,(UINT)m_ToolsMenu.m_hMenu,"&Tools");
pMenu->InsertMenu(2,MF_BYPOSITION|MF_POPUP,(UINT)m_HelpMenu.m_hMenu,"&Help");
}
 
CMainDialog::CMainDialog(CWnd* pParent /*=NULL*/)
: CDialog(CMainDialog::IDD, pParent)
{

m_FileMenu.CreatePopupMenu();
m_FileMenu.SetMenuHeight(20);
m_FileMenu.SetMenuWidth(50);
m_FileMenu.SetMenuType(MIT_XP);
m_FileMenu.AppendMenu(MF_ENABLED, IDOK,"E&xit",IDB_BM_EXIT);
 
//....etc.
}
 
In CMenuCH::AppendMenu I removed the foloowing line;
if( !(nFlags & MF_POPUP) ) //not handled popup menu
and in CMainDialog I over raod the OnMeasureItem method
as follows;
 
void CWoodCalcDlg::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
lpMeasureItemStruct->itemHeight = 20;
lpMeasureItemStruct->itemWidth = 50;
 
CDialog::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
}
 
Everything works OK but in some cases I still get a warning;
Warning: unknown WM_MEASUREITEM for menu item 0x190273.
 
Haven't gone into it much yet as it works fine.
 
Mike
 


 
Everybody gotta be somebody
GeneralRe: CMenuCh Pinmemberchia hung liu13-Oct-02 15:38 
QuestionCan be used in a dialog based application? Pinmemberchen23-Sep-02 7:21 
AnswerRe: Can be used in a dialog based application? Pinmemberchia hung liu29-Sep-02 15:23 
GeneralRe: Can be used in a dialog based application? Pinmemberchen29-Sep-02 16:20 
GeneralRe: Can be used in a dialog based application? Pinmemberchia hung liu2-Oct-02 23:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140827.1 | Last Updated 9 Sep 2002
Article Copyright 2002 by chia hung liu
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid