MFC Topics: Menu Fundamentals |
|
Introduction to the Main Menu |
A menu is a list of actions the user can perform on an application. The actions are presented in one or more groups. There are broad categories of menus: the main menu and the context menu. A main menu, also called a top-level menu, displays categories of menu items using a range of items called a menu bar:
|
When the user clicks an item of the menu bar, the item clicked opens its list: After a list has been displayed, the user can then use an item from the list. Each item of the list is primarily a word or a group of words on a line. Different menu items are used for different reasons. For example, some menu items simply display a word or a group of words. Some other items display a check mark. This indicates that the item toggles the availability or disappearance of an object. When a menu item is only meant to lead to a sub-menu, such a menu item is called a popup menu. There are two types of popup menus. If the menu displays on top of a window, which is the type of menu under the title bar, the word on top, which represents a category of menu, is a popup menu. If a menu item is equipped with an arrow in its right , which means the menu item has a submenu, such a menu item is also a popup menu. Popup menus are used only to represent a submenu. No inherent action is produced by clicking them, except that, when placed on top, such menu items allow opening the submenu. To create menus that belong to a group, menu items are separated by a horizontal line called a separator. Separators are created differently in MSVC 6 and MSVC 7.
There are two main ways you can create a main menu: Using a resource file or programmatically creating the menu items. You can create a resource file that has the .rc extension. The menu is created as text. If you create the file manually, you must also remember to create or edit the resource.h file in order to specify an identifier for each menu. The alternative, which we will use, is to "visually" create the menu in Visual Studio. When doing this, the studio itself would update the resource.h file as items are added or removed. To visually create a menu, first add a resource of type Menu using the Add Resource dialog box. The MFC library implements a Windows menu, from the Win32’s HMENU class, through the CMenu class. Based on this, if you want to programmatically create a menu, you can start by declaring a CMenu variable. Here is an example: #include <afxwin.h> class CExerciseApp : public CWinApp { public: virtual BOOL InitInstance(); }; class CMainFrame : public CFrameWnd { public: CMainFrame(); private: CMenu m_wndMainMenu; }; CMainFrame::CMainFrame() { Create(NULL, "Menus Fundamentals"); } BOOL CExerciseApp::InitInstance() { m_pMainWnd = new CMainFrame; m_pMainWnd->ShowWindow(SW_NORMAL); return TRUE; } CExerciseApp theApp; After declaring the variable, to indicate that you intend to create a menu, you must first call the CMenu::CreateMenu() method. Its syntax is: BOOL CreateMenu(); Here is an example: CMainFrame::CMainFrame() { Create(NULL, "Menus Fundamentals"); this->m_wndMainMenu.CreateMenu(); } Just in case something might go wrong, the MFC provides the VERIFY macro that you can use to make sure that the menu was rightly initialized. It can be used as follows: CMainFrame::CMainFrame() { Create(NULL, "Menus Fundamentals"); VERIFY(this->m_wndMainMenu.CreateMenu()); } After declaring the variable and calling CreateMenu(), you can start defining the characteristics of the menu. We will review the various characteristics in the next sections.
After creating a menu, before using it, you should associate it with a window frame that will carry it and present it to the user. To associate a menu with a window, you have various options. If you are using the CFrameWnd::Create() method to create the window, you can specify the name of the menu using the lpszMenuName argument: virtual BOOL Create( LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle = WS_OVERLAPPEDWINDOW, const RECT& rect = rectDefault, CWnd* pParentWnd = NULL, LPCTSTR lpszMenuName = NULL, DWORD dwExStyle = 0, CCreateContext* pContext = NULL ); Here is an example: class CMainFrame : public CFrameWnd { public: CMainFrame() { Create(NULL, "Resources Fundamentals", WS_OVERLAPPEDWINDOW, CRect(200, 120, 640, 400), NULL, MAKEINTRESOURCE(IDR_MAINFRAME)); } }; If you are programmatically creating the menu using a CMenu object, to assign it to a frame, you can call the CWnd::SetMenu() method. Its syntax is: BOOL SetMenu(CMenu* pMenu); Here is an example: CMainFrame::CMainFrame() { Create(NULL, "Menus Fundamentals"); VERIFY(this->m_wndMainMenu.CreateMenu()); // Do whatever here this->SetMenu(&m_wndMainMenu); } If a window already has a menu and you want to get a reference to that menu, you can call its CWnd::GetMenu() method. Its syntax is: CMenu *GetMenu() const; When using this method, if the window that calls it doesn’t have a menu, this method returns NULL. Otherwise, this method returns a pointer to the CMenu object of the window that called it. As stated already, The CMenu class is the MFC’s implementation of the HMENU handle. To get a handle to an existing CMenu object of an application, you can access the value of the CMenu::m_hMenu property, which is of type HMENU.
As introduced earlier, a menu is primarily a list of actions that can be performed on an application. The actions are generated when the user positions the mouse on a menu item or when one of these items is clicked. If the user clicks an item such as File on the main menu, the menu item generates a WM_INITMENUPOPUP message. To get the program ready to process these messages, in the previous lesson, we saw that you should create a message map. Here is an example: class CMainFrame : public CFrameWnd { public: CMainFrame() { Create(NULL, "Menus Fundamentals"); } DECLARE_MESSAGE_MAP() }; BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) END_MESSAGE_MAP() BOOL CExoApp::InitInstance() { . . . } If the MFC doesn’t provide a default function that processes your type of message, you should first implement the event that will process the message. Here is an example: class CMainFrame : public CFrameWnd { public: CMainFrame() { Create(NULL, "Menus Fundamentals"); } afx_msg void EndThisApplication(); DECLARE_MESSAGE_MAP() }; . . . void CMainFrame::EndThisApplication() { PostQuitMessage(0); } Once you have defined the method that will process the message, you can map it to a resource symbol in your message map section using the ON_COMMAND macro. Once this has been done, the application can process the message.
|
|
||
Home | Copyright © 2006-2007 FunctionX, Inc. | Next |
|