Home | API | MFC | C++ | C | Previous | Next

Programming Windows with MFC

Adding Menus

In windows, a menu bar is a horizontal bar most often displayed immediately below the caption bar and usually containing a list of drop-down menu items. These drop-down menus can contain either other menu items or nested sub menus.

MFC encapsulates menus and all associated actions in the CMenu class. MFC menus are usually created programmatically or from a resource file which can then be loaded into the application at run time.

To create and maintain menus programmatically, the developer will need to instantiate on object of the class CMenu and then use the following member functions: CreateMenu(), CreatePopupMenu(), and AppendMenu() to create the menu items.

CreateMenu

Is used to create a top-level menu. The prototype of this function is

BOOL CreateMenu( );

Returns nonzero if the menu creation was successful. 0 if menu creation failed

CreatePopupMenu

Creates a pop-up menu and attaches it to the CMenu object. The prototype of this function is

BOOL CreatePopupMenu( );

Return Nonzero if the pop-up menu was successfully created; 0 if menu creation failed

AppendMenu

Appends a new item to the end of a menu. The prototype of this function is

BOOL AppendMenu( UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL);
BOOL AppendMenu( UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp );

nFlags – Specifies information about the state of the new menu item.
nIDNewItem – Specifies either the command ID of the new menu item or, if nFlags is set to MF_POPUP, the menu handle ( HMENU) of a pop-up menu.
lpszNewItem – Specifies the content of the new menu item.
pBmp – Points to a CBitmap object that will be used as the menu item.

For more details reading
https://docs.microsoft.com/en-us/cpp/mfc/reference/cmenu-class?view=vs-2019#appendmenu

The ON_COMMAND macro

The ON_COMMAND macro in the message map links menu messages to a message response function. The prototype for this function is

ON_COMMAND( Id, mFuction )

where
id – is the menu items ID,
mFuction -is the name of the function that will handle that message.

To map a range of menu commands to a single message response use the ON_COMMAND_RANGE macro. The prototype for this macro is

ON_COMMAND_RANGE( id1, id2, mFunction )

where
id1 – Command ID at the beginning of a contiguous range of command IDs.
id2 – Command ID at the end of a contiguous range of command IDs.
mFunction – The name of the message-handler function to which the commands are mapped.

In order for this type of message mapping to work, the command IDs in the range must be consecutive.

Modifying Menus Programmatically

In addition to creating menus dynamically, menus can all be modified dynamically. The following table lists the CMenu member functions used to add, modify, and delete menu items.

InsertMenu

Inserts an item into a menu at a specified location. The prototype for this function is

BOOL InsertMenu( nPosition, nFlags, nIDNewItem, lpszNewItem );
BOOL InsertMenu( nPosition, nFlags, nIDNewItem, * pBmp );

where
nPosition – Specifies the menu item before which the new menu item is to be inserted.
nFlags – Specifie information about the state of the new menu item
nIDNewItem – Specifies either the command ID of the new menu item or, if nFlags is set to MF_POPUP, the menu handle (HMENU) of the pop-up menu.
lpszNewItem – Specifies the content of the new menu item.
pBmp – Points to a CBitmap object that will be used as the menu item.

Returns nonzero if the function is successful; otherwise 0.
For further reading
https://docs.microsoft.com/en-us/cpp/mfc/reference/cmenu-class?view=vs-2019#insertmenu

ModifyMenu

Changes the command ID, text, or other characteristics of a menu item.

BOOL ModifyMenu( nPosition, nFlags, nIDNewItem, lpszNewItem );
BOOL ModifyMenu( nPosition, nFlags, nIDNewItem, pBmp );

NPosition – Specifies the menu item to be changed.
nFlags, nIDNewItem, lpszNewItem-see insert menu

For further reading
https://docs.microsoft.com/en-us/cpp/mfc/reference/cmenu-class?view=vs-2019#modifymenu

DeleteMenu

Deletes a menu item and the submenu associated with it, if any. The prototype of this function is

BOOL DeleteMenu( UINT nPosition, UINT nFlags );

Where
nPosition – Specifies the menu item that is to be deleted
nFlags – Is used to interpret nPosition

Return nonzero if the function is successful; otherwise 0

For further reading
https://docs.microsoft.com/en-us/cpp/mfc/reference/cmenu-class?view=vs-2019#deletemenu

RemoveMenu

Deletes a menu item

BOOL RemoveMenu( UINT nPosition, UINT nFlags );

where
nPosition – Specifies the menu item to be removed.
nFlags – Specifies how nPosition is interpreted
Return nonzero if the function is successful; otherwise 0.

The difference between RemoveMenu and DeleteMenu is that if the item being removed has a submenu, then deleteMenu will remove the item and destroys the submenu, too. RemoveMenu removes the item but leaves the submenu extant in memory.

Before a menu is modified, the developer will need the CMenu pointer referencing the menu. MFC’s CWnd::GetMenu function returns a CMenu pointer for a window’s top-level menu or NULL if the window doesn’t have a top-level menu-

CMenu* pMenu = GetMenu ();
pMenu->DeleteMenu (1, MF_BYPOSITION);

The Popup or Context Menu

Popup or context menus are those which generally appear when the user right-clicks. This menu is often referred to as a context menu because the options in the menu often relate to what was right-clicked. The popup menu can be loaded from an existing resource or can be created dynamically with a call to the function CreatePopupMenu().

The cmenu member function TrackPopupMenu() displays a context menu. The function prototype is

BOOL TrackPopupMenu (UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect = NULL)

Where
nFlags – Specifies screen-position and mouse-position flags.
Use one of the following flags to specify how the function positions the shortcut menu horizontally.
TPM_CENTERALIGN – Centers the shortcut menu horizontally relative to the coordinate specified by the x parameter.
TPM_LEFTALIGN – Positions the shortcut menu so that its left side is aligned with the coordinate specified by the x parameter.
TPM_RIGHTALIGN – Positions the shortcut menu so that its right side is aligned with the coordinate specified by the x parameter.
Use one of the following flags to specify how the function positions the shortcut menu vertically.
TPM_BOTTOMALIGN – Positions the shortcut menu so that its bottom side is aligned with the coordinate specified by the y parameter.
TPM_TOPALIGN – Positions the shortcut menu so that its top side is aligned with the coordinate specified by the y parameter.
TPM_VCENTERALIGN – Centers the shortcut menu vertically relative to the coordinate specified by the y parameter.
x – Specifies the horizontal position in screen coordinates of the pop-up menu.
y – Specifies the vertical position in screen coordinates of the top of the menu on the screen.
pWnd – Identifies the window that owns the pop-up menu.
lpRect – Ignored.

Returns the result of calling TrackPopupMenu

The short program below demonstrates a simple menu structure. Clicking file>new will produce a messagebox and file>exit will close the application.


#include <afxwin.h>
#define ID_NEW 2002
#define ID_EXIT 2004
#define IDM_MENUITEM1 2005

class CSimpleApp : public CWinApp
{
public:
BOOL InitInstance();
};

class CMainFrame : public CFrameWnd
{
public:
CMainFrame();
void OnFileNew();
void OnExit();
afx_msg void OnRButtonDown( UINT, CPoint );
DECLARE_MESSAGE_MAP()
};


BOOL CSimpleApp::InitInstance(){
m_pMainWnd = new CMainFrame();
m_pMainWnd->ShowWindow(m_nCmdShow);
return TRUE;
}

CMainFrame::CMainFrame()
{
Create(NULL, "MFC Menu Example");
//Create main menu
CMenu *menu = new CMenu();
menu->CreateMenu();
//creare 2 submenu's
CMenu *subMenu1 = new CMenu();
CMenu *subMenu2 = new CMenu();

//make submenu popup
subMenu1->CreatePopupMenu();
subMenu2->CreatePopupMenu();

//append items to submenu
menu->AppendMenu(MF_POPUP|MF_STRING, (UINT)subMenu1->m_hMenu, TEXT("File") );
menu->AppendMenu(MF_POPUP|MF_STRING, (UINT)subMenu2->m_hMenu, TEXT("Help") );
subMenu1->AppendMenu(MF_STRING, ID_NEW, TEXT("New"));
subMenu1->AppendMenu(MF_STRING, ID_EXIT, TEXT("Exit"));
SetMenu(menu);
}
BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)
ON_COMMAND(ID_NEW ,OnFileNew)
ON_COMMAND(ID_EXIT ,OnExit)
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
END_MESSAGE_MAP()
CSimpleApp MFCApp1;

//respond to menu selection new by creating message box
afx_msg void CMainFrame::OnFileNew()
{
MessageBox(TEXT("New button clicked"),TEXT("menu demo"),MB_OK);
}
afx_msg void CMainFrame::OnExit()
{
PostMessage(WM_CLOSE,0,0);
}
//display context menu
afx_msg void CMainFrame::OnRButtonDown(UINT nFlags, CPoint point)
{
CMenu *contextmenu;
contextmenu = new CMenu();
contextmenu->CreatePopupMenu();//= CreatePopupMenu();
contextmenu->AppendMenu(MF_STRING,ID_NEW, TEXT("New"));
contextmenu->AppendMenu(MF_STRING,ID_EXIT, TEXT("Exit"));
ClientToScreen(&point);
contextmenu->TrackPopupMenu(TPM_RIGHTBUTTON,point.x,point.y, this, NULL);
}

Download Code


Home | API | MFC | C++ | C | Previous | Next
Creating a Simple Window | Processing Messages | Device Context | Working with Graphics | Mapping Modes | Text Output | Working with the Mouse | Dealing with Keyboard Input | Drawing Lines and Shapes | Adding Menus | Child Windows | Dialog Windows | Common Dialog Box | Working with Bitmaps | Common Controls | Toolbars | Document View Architecture | Multi Document Interface | Timers | MFC Collections Classes

Last Updated: 16 October 2022