菜单编程_静态添加

1.

新建一个MFC单文档应用程序,取名Menu

在IDM_NAINFRAME中添加一个菜单test ->右键-> ClassWizard… 分别在CMainFrame、CMenuDoc、CMenuApp、CMenuView中添加对Test菜单项的COMMAND消息。

MessageBox("ManinFrame clicked");

AfxMessageBox("Doc clicked");

AfxMessageBox("App clicked");

MessageBox("clicked");

命令消息传递顺序:view类-doc类-frame类-app类

 

2.

消息的分类(如下图)

创建标记菜单:

在新建菜单上创建一个标记菜单,在CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)函数中添加:

    //    GetMenu()->GetSubMenu(0)->CheckMenuItem(0,MF_BYPOSITION|MF_CHECKED);//添加标记

    GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_FILE_NEW,MF_BYCOMMAND|MF_CHECKED);//添加标记第二种方法

注释:

UINT CheckMenuItem( UINT nIDCheckItem, UINT nCheck );

Return Value

The previous state of the item: MF_CHECKED or MF_UNCHECKED, or 0xFFFFFFFF if the menu item did not exist.

Parameters

nIDCheckItem

Specifies the menu item to be checked, as determined by nCheck.

nCheck

Specifies how to check the menu item and how to determine the item's position in the menu. The nCheck parameter can be a combination of MF_CHECKED or MF_UNCHECKED with MF_BYPOSITION or MF_BYCOMMAND flags. These flags can be combined by using the bitwise OR operator. They have the following meanings:

  • MF_BYCOMMAND   Specifies that the parameter gives the command ID of the existing menu item. This is the default.
  • MF_BYPOSITION   Specifies that the parameter gives the position of the existing menu item. The first item is at position 0.
  • MF_CHECKED   Acts as a toggle with MF_UNCHECKED to place the default check mark next to the item.
  • MF_UNCHECKED   Acts as a toggle with MF_CHECKED to remove a check mark next to the item.

Remarks

Adds check marks to or removes check marks from menu items in the pop-up menu. The nIDCheckItem parameter specifies the item to be modified.

The nIDCheckItem parameter may identify a pop-up menu item as well as a menu item. No special steps are required to check a pop-up menu item. Top-level menu items cannot be checked. A pop-up menu item must be checked by position since it does not have a menu-item identifier associated with it.

-------------------------------------------------------------------------------

CMenu::GetSubMenu

CMenu* GetSubMenu( int nPos ) const;

Return Value

A pointer to a CMenu object whose m_hMenu member contains a handle to the pop-up menu if a pop-up menu exists at the given position; otherwise NULL. If a CMenu object does not exist, then a temporary one is created. The CMenu pointer returned should not be stored.

Parameters

nPos

Specifies the position of the pop-up menu contained in the menu. Position values start at 0 for the first menu item. The pop-up menu's identifier cannot be used in this function.

Remarks

Retrieves the CMenu object of a pop-up menu.

----------------------------------------------------------------------------------

CheckMenuItem

The CheckMenuItem function sets the state of the specified menu item's check-mark attribute to either selected or clear.

Note  The CheckMenuItem function has been superseded by the SetMenuItemInfo function. You can still use CheckMenuItem, however, if you do not need any of the extended features of SetMenuItemInfo.

DWORD CheckMenuItem(

HMENU hmenu, // handle to menu

UINT uIDCheckItem, // menu item to check or uncheck

UINT uCheck // menu item options

);

Parameters

hmenu

[in] Handle to the menu of interest.

uIDCheckItem

[in] Specifies the menu item whose check-mark attribute is to be set, as determined by the uCheck parameter.

uCheck

[in] Specifies flags that control the interpretation of the uIDCheckItem parameter and the state of the menu item's check-mark attribute. This parameter can be a combination of either MF_BYCOMMAND, or MF_BYPOSITION and MF_CHECKED or MF_UNCHECKED.

Value

Meaning

MF_BYCOMMAND

Indicates that the uIDCheckItem parameter gives the identifier of the menu item. The MF_BYCOMMAND flag is the default, if neither the MF_BYCOMMAND nor MF_BYPOSITION flag is specified.

MF_BYPOSITION

Indicates that the uIDCheckItem parameter gives the zero-based relative position of the menu item.

MF_CHECKED

Sets the check-mark attribute to the selected state.

MF_UNCHECKED

Sets the check-mark attribute to the clear state.

 

Return Values

The return value specifies the previous state of the menu item (either MF_CHECKED or MF_UNCHECKED). If the menu item does not exist, the return value is -1.

Remarks

An item in a menu bar cannot have a check mark.

The uIDCheckItem parameter identifies a item that opens a submenu or a command item. For a item that opens a submenu, the uIDCheckItem parameter must specify the position of the item. For a command item, the uIDCheckItem parameter can specify either the item's position or its identifier.

3.

设置缺省菜单,在CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)函数中添加:

//GetMenu()->GetSubMenu(0)->SetDefaultItem(1,TRUE);//设置缺省菜单

//GetMenu()->GetSubMenu(0)->SetDefaultItem(ID_FILE_OPEN);

GetMenu()->GetSubMenu(0)->SetDefaultItem(5,TRUE);

注释:

CMenu::SetDefaultItem

BOOL SetDefaultItem( UINT uItem, BOOL fByPos = FALSE );

Return Value

If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, use the Win32 function GetLastError, as described in the Platform SDK.

Parameters

uItem

Identifier or position of the new default menu item or - 1 for no default item. The meaning of this parameter depends on the value of fByPos.

fByPos

Value specifying the meaning of uItem. If this parameter is FALSE, uItem is a menu item identifier. Otherwise, it is a menu item position.

Remarks

This member function implements the behavior of the Win32 function SetMenuDefaultItem, as described in the Platform SDK.

 

4.

创建一个图形标记菜单,在CMainFrame中添加成员变量:

private:

    CBitmap m_bitmap;

CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)函数中添加:

CString str;

str.Format("x=%d,y=%d",GetSystemMetrics(SM_CXMENUCHECK),

GetSystemMetrics(SM_CYMENUCHECK));//获取菜单图形标记的尺寸

MessageBox(str);

m_bitmap.LoadBitmap(IDB_BITMAP1);

GetMenu()->GetSubMenu(0)->SetMenuItemBitmaps(0,MF_BYPOSITION,&m_bitmap,&m_bitmap);

注释:

GetSystemMetrics

The GetSystemMetrics function retrieves various system metrics (widths and heights of display elements) and system configuration settings. All dimensions retrieved by GetSystemMetrics are in pixels.

int GetSystemMetrics(
  int
						nIndex   // system metric or configuration setting
);
				

Parameters

nIndex

[in] Specifies the system metric or configuration setting to retrieve. All SM_CX* values are widths. All SM_CY* values are heights.

SM_CXMENUCHECK,
SM_CYMENUCHECK

Dimensions, in pixels, of the default menu check-mark bitmap.

-----------------------------------------------------------------------------------

SetMenuItemBitmaps

The SetMenuItemBitmaps function associates the specified bitmap with a menu item. Whether the menu item is selected or clear, the system displays the appropriate bitmap next to the menu item.

BOOL SetMenuItemBitmaps(
  HMENU
						hMenu,               // handle to menu
  UINT
						uPosition,            // menu item
  UINT
						uFlags,               // options
  HBITMAP
						hBitmapUnchecked,  // handle to unchecked bitmap
  HBITMAP
						hBitmapChecked
					// handle to checked bitmap
);
				

Parameters

hMenu

[in] Handle to the menu containing the item to receive new check-mark bitmaps.

uPosition

[in] Specifies the menu item to be changed, as determined by the uFlags parameter.

uFlags

[in] Specifies how the uPosition parameter is interpreted. The uFlags parameter must be one of the following values.

Value

Meaning

MF_BYCOMMAND

Indicates that uPosition gives the identifier of the menu item. If neither MF_BYCOMMAND nor MF_BYPOSITION is specified, MF_BYCOMMAND is the default flag.

MF_BYPOSITION

Indicates that uPosition gives the zero-based relative position of the menu item.

 

hBitmapUnchecked

[in] Handle to the bitmap displayed when the menu item is not selected.

hBitmapChecked

[in] Handle to the bitmap displayed when the menu item is selected.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If either the hBitmapUnchecked or hBitmapChecked parameter is NULL, the system displays nothing next to the menu item for the corresponding check state. If both parameters are NULL, the system displays the default check-mark bitmap when the item is selected, and removes the bitmap when the item is not selected.

When the menu is destroyed, these bitmaps are not destroyed; it is up to the application to destroy them.

The selected and clear bitmaps should be monochrome. The system uses the Boolean AND operator to combine bitmaps with the menu so that the white part becomes transparent and the black part becomes the menu-item color. If you use color bitmaps, the results may be undesirable.

Use the GetSystemMetrics function with the CXMENUCHECK and CYMENUCHECK values to retrieve the bitmap dimensions.

5.

使菜单不可用,变灰

CMainFrame::CMainFrame()函数中添加:

m_bAutoMenuEnable=FALSE;

CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)函数中添加:

GetMenu()->GetSubMenu(0)->EnableMenuItem(1,MF_BYPOSITION|MF_DISABLED|MF_GRAYED);

注释:

CMenu::EnableMenuItem

UINT EnableMenuItem( UINT nIDEnableItem, UINT nEnable );

Return Value

Previous state (MF_DISABLED, MF_ENABLED, or MF_GRAYED) or –1 if not valid.

Parameters

nIDEnableItem

Specifies the menu item to be enabled, as determined by nEnable. This parameter can specify pop-up menu items as well as standard menu items.

nEnable

Specifies the action to take. It can be a combination of MF_DISABLED, MF_ENABLED, or MF_GRAYED, with MF_BYCOMMAND or MF_BYPOSITION. These values can be combined by using the bitwise OR operator. These values have the following meanings:

  • MF_BYCOMMAND   Specifies that the parameter gives the command ID of the existing menu item. This is the default.
  • MF_BYPOSITION   Specifies that the parameter gives the position of the existing menu item. The first item is at position 0.
  • MF_DISABLED   Disables the menu item so that it cannot be selected but does not dim it.
  • MF_ENABLED   Enables the menu item so that it can be selected and restores it from its dimmed state.
  • MF_GRAYED   Disables the menu item so that it cannot be selected and dims it.

Remarks

Enables, disables, or dims a menu item. The CreateMenu, InsertMenu, ModifyMenu, and LoadMenuIndirect member functions can also set the state (enabled, disabled, or dimmed) of a menu item.

Using the MF_BYPOSITION value requires an application to use the correct CMenu. If the CMenu of the menu bar is used, a top-level menu item (an item in the menu bar) is affected. To set the state of an item in a pop-up or nested pop-up menu by position, an application must specify the CMenu of the pop-up menu.

When an application specifies the MF_BYCOMMAND flag, Windows checks all pop-up menu items that are subordinate to the CMenu; therefore, unless duplicate menu items are present, using the CMenu of the menu bar is sufficient.

Example

// The code fragment below shows how to disable (and gray out) the 
// File\New menu item.
// NOTE: m_bAutoMenuEnable is set to FALSE in the constructor of 
// CMainFrame so no ON_UPDATE_COMMAND_UI or ON_COMMAND handlers are 
// needed, and CMenu::EnableMenuItem() will work as expected.

 

CMenu* mmenu = GetMenu();
CMenu* submenu = mmenu->GetSubMenu(0);
submenu->EnableMenuItem(ID_FILE_NEW, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);

----------------------------------------------------------------------------------------------------------

6.

如何取消整个菜单,

CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)函数中添加:

SetMenu(NULL);//取消菜单

CMenu menu;//在这是局部变量,一般会有问题,应设置成CMainFrame的成员变量

menu.LoadMenu(IDR_MAINFRAME);//加载菜单

SetMenu(&menu);

menu.Detach();

注释:

SetMenu

The SetMenu function assigns a new menu to the specified window.

BOOL SetMenu(
  HWND
						hWnd,  // handle to window
  HMENU
						hMenu
					// handle to menu
);
				

Parameters

hWnd

[in] Handle to the window to which the menu is to be assigned.

hMenu

[in] Handle to the new menu. If this parameter is NULL, the window's current menu is removed.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The window is redrawn to reflect the menu change. A menu can be assigned to any window that is not a child window.

The SetMenu function replaces the previous menu, if any, but it does not destroy it. An application should call the DestroyMenu function to accomplish this task.

----------------------------------------------------------------------------------------------------

The CMenu class is an encapsulation of the Windows HMENU. It provides member functions for creating, tracking, updating, and destroying a menu.

Create a CMenu object on the stack frame as a local, then call CMenu's member functions to manipulate the new menu as needed. Next, call CWnd::SetMenu to set the menu to a window, followed immediately by a call to the CMenu object's Detach member function. The CWnd::SetMenu member function sets the window's menu to the new menu, causes the window to be redrawn to reflect the menu change, and also passes ownership of the menu to the window. The call to Detach detaches the HMENU from the CMenu object, so that when the local CMenu variable passes out of scope, the CMenu object destructor does not attempt to destroy a menu it no longer owns. The menu itself is automatically destroyed when the window is destroyed.

7.

命令更新,

在View-> ClassWizard… 中添加对ID_EDIT_CUT的UPDATE_COMMAND_UI消息,然后在CMainFrame::OnUpdateEditCut(CCmdUI* pCmdUI)函数中添加:

pCmdUI->Enable();//默认为TRUE

这样剪切菜单就变成了可有状态。

注释:

CCmdUI

CCmdUI does not have a base class.

The CCmdUI class is used only within an ON_UPDATE_COMMAND_UI handler in a CCmdTarget-derived class.

When a user of your application pulls down a menu, each menu item needs to know whether it should be displayed as enabled or disabled. The target of a menu command provides this information by implementing an ON_UPDATE_COMMAND_UI handler. Use ClassWizard to browse the command user-interface objects in your application and create a message-map entry and function prototype for each handler.

When the menu is pulled down, the framework searches for and calls each ON_UPDATE_COMMAND_UI handler, each handler calls CCmdUI member functions such as Enable and Check, and the framework then appropriately displays each menu item.

A menu item can be replaced with a control-bar button or other command user-interface object without changing the code within the ON_UPDATE_COMMAND_UI handler.

The following table summarizes the effect CCmdUI's member functions have on various command user-interface items.

-------------------------------------------------------------------------------------------------------

CCmdUI Class Members

Data Members

m_nID

The ID of the user-interface object.

m_nIndex

The index of the user-interface object.

m_pMenu

Points to the menu represented by the CCmdUI object.

m_pSubMenu

Points to the contained sub-menu represented by the CCmdUI object.

m_pOther

Points to the window object that sent the notification.

 

Operations

Enable

Enables or disables the user-interface item for this command.

SetCheck

Sets the check state of the user-interface item for this command.

SetRadio

Like the SetCheck member function, but operates on radio groups.

SetText

Sets the text for the user-interface item for this command.

ContinueRouting

Tells the command-routing mechanism to continue routing the current message down the chain of handlers.

如果我们需要将工具栏上的某个图标与某个菜单项相关联,我们只需要它们的ID号设置成同一个就可以了。

再做一个使新建菜单项不能使用状态的操作,同样对ID_FILE_NEW添加UPDATE_COMMAND_UI消息,然后在CMainFrame::OnUpdateEditCut(CCmdUI* pCmdUI)函数中添加:

if(ID_FILE_NEW==PcmdUI->m_nID)//m_nID是CCmdUI的成员变量,保存了与这个UI当前相关的菜单项

pCmdUI->Enable(FALSE);

当然也可以通过索引实现,

if(0==pCmdUI->m_nIndex)

        pCmdUI->Enable(FALSE);

注意:如果对前面的菜单的状态也用索引来判断,那工具栏上的剪切图标将不会变成可用状态;而用ID号来判断,则工具栏上的剪切则会变成可用状态。

8.

添加右键弹出菜单功能,首先选择Project ->Add To Project -> Components and Controls… 在弹出的对话框中选择visual C++ Components -> Pop up Menu 选择插入,"Insert the Pop-up Menu Component?" 选择确定,增加弹出菜单到CMenuView类当中,ID暂不修改,OK!

运行点右键可以看到,增加了弹出菜单!

在资源中打开CG_IDR_POPUP_MENU_VIEW,可以看到增加的三个菜单项,

下面手动创建一个弹出菜单:

新建一个菜单,添加两个菜单项 IDM_SHOW 、 IDM_EXIT ,并在视类中添加WM_RBUTTONDOWN消息响应函数,并在CMenuView::OnRButtonDown(UINT nFlags, CPoint point)函数中添加:

CMenu menu;

menu.LoadMenu(IDR_MENU1);

CMenu *pPopup=menu.GetSubMenu(0);

ClientToScreen(&point);//把给定的点所在的客户区坐标转换成屏幕坐标

pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point.x,point.y,this);//显示弹出菜单

注释:

TrackPopupMenu

The TrackPopupMenu function displays a shortcut menu at the specified location and tracks the selection of items on the menu. The shortcut menu can appear anywhere on the screen.

To specify an area of the screen the menu should not overlap, use the TrackPopupMenuEx function.

BOOL TrackPopupMenu(
  HMENU
						hMenu,         // handle to shortcut menu
  UINT
						uFlags,         // options
  int
						x,               // horizontal position
  int
						y,               // vertical position
  int
						nReserved,       // reserved, must be zero
  HWND
						hWnd,           // handle to owner window
  CONST RECT
					*prcRect
					// ignored
);
				

Return Values

If you specify TPM_RETURNCMD in the uFlags parameter, the return value is the menu-item identifier of the item that the user selected. If the user cancels the menu without making a selection, or if an error occurs, then the return value is zero.

If you do not specify TPM_RETURNCMD in the uFlags parameter, the return value is nonzero if the function succeeds and zero if it fails. To get extended error information, call GetLastError.

Remarks

To display a context menu for a notification icon, the current window must be the foreground window before the application calls TrackPopupMenu or TrackPopupMenuEx. Otherwise, the menu will not disappear when the user clicks outside of the menu or the window that created the menu (if it is visible). However, when the current window is the foreground window, the second time this menu is displayed, it displays and then immediately disappears. To correct this, you must force a task switch to the application that called TrackPopupMenu at some time in the near future. This is done by posting a benign message to the window or thread, as shown in the following code sample:

   SetForegroundWindow(hDlg);

 

   // Display the menu
   TrackPopupMenu(   hSubMenu,
                     TPM_RIGHTBUTTON,
                     pt.x,
                     pt.y,
                     0,
                     hDlg,
                     NULL);

 

   PostMessage(hDlg, WM_NULL, 0, 0);
			

---------------------------------------------------------------------------------------------------------

ClientToScreen

The ClientToScreen function converts the client-area coordinates of a specified point to screen coordinates.

BOOL ClientToScreen(
  HWND
						hWnd,       // handle to window
  LPPOINT
						lpPoint  // screen coordinates
);
				

Parameters

hWnd

[in] Handle to the window whose client area is used for the conversion.

lpPoint

[in/out] Pointer to a POINT structure that contains the client coordinates to be converted. The new screen coordinates are copied into this structure if the function succeeds.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

Remarks

The ClientToScreen function replaces the client-area coordinates in the POINT structure with the screen coordinates. The screen coordinates are relative to the upper-left corner of the screen. Note, a screen-coordinate point that is above the window's client area has a negative y-coordinate. Similarly, a screen coordinate to the left of a client area has a negative x-coordinate.

All coordinates are device coordinates.

 

CView::OnRButtonDown(nFlags, point);

对IDM_SHOW菜单项做消息响应,分别在CMainFrame、CMenuView中添加WM_COMMAND消息响应,在CMenuView::OnShow()添加:

MessageBox("View Show");

CMainFrame::OnShow()添加:

MessageBox("MainFrame Show");

如果删除View类中的OnShow()函数后,运行,可以看出弹出菜单并不响应CMainFrame::OnShow()函数,如果要对它响应,则要修改CMenuView::OnRButtonDown(UINT nFlags, CPoint point)中的:

pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point.x,point.y,GetParent());

//其中Getparent()是获取框架类窗口的指针

同样如果这样修改后,再加上View类中的OnShow()函数后,最先响应的仍然是view类中的响应函数。

 

posted @ 2011-03-30 18:55  维唯为为  阅读(399)  评论(0编辑  收藏  举报