VC Study Notes: Menu

Source: Internet
Author: User

VC Study Notes: Menu

 SkySeraph NOV.1sh 2010 HQU

Email-zgzhaobo@gmail.com QQ-452728574

Latest Modified Date: NOV.1sh 2010 HQU

Basic operations

  • Dynamic menu creation [1]

Steps:

① Create a dialog box project and declare a CMenu Class Object m_Menu in the dialog box header file.

② In the OnInitDialog function of the dialog box, add:

M_Menu.CreateMenu (); // create a menu window

CMenu m_PopMenu; // defines the menu Class Object

M_PopMenu.CreatePopupMenu (); // create a menu window

M_Menu.AppendMenu (MF_POPUP, (UINT) m_PopMenu.m_hMenu, "animal"); // Insert Menu

M_PopMenu.AppendMenu (MF_STRING, ID_MENUCAT, "cat"); // insert sub menu

M_PopMenu.AppendMenu (MF_STRING, ID_MENUDOG, "dog ");

M_PopMenu.AppendMenu (MF_STRING, ID_MENUMONKEY, "monkey ");

M_Menu.AppendMenu (MF_POPUP,-1, "plant"); // Insert the sibling menu

M_PopMenu.Detach (); // detach the menu handle

SetMenu (& m_Menu); // associate the menu with the window

③ Declare the menu handler in the header file of the dialog box

Afx_msg void OnMenucat ();

Afx_msg void OnMenudog ();

Afx_msg void OnMenumonkey ();

④ Add a message ing macro to the source file in the dialog box

ON_COMMAND (ID_MENUCAT, OnMenucat)

ON_COMMAND (ID_MENUDOG, OnMenudog)

ON_COMMAND (ID_MENUMONKEY, OnMenumonkey)

⑤ Add the message processing function implementation code to the source file in the dialog box

Void CCreateMenuDlg: OnMenucat ()

{

MessageBox ("cat menu pressed ");

}

 

Void CCreateMenuDlg: OnMenudog ()

{

MessageBox ("Dog menu pressed ");

}

 

Void CCreateMenuDlg: OnMenumonkey ()

{

MessageBox ("monkey menu pressed ");

}

Note:

Create a menu window through CreateMenu and associate it with the menu object.

Call CreatePopupmenu to create a pop-up window and associate it with the menu object.

Call AppendMenu to add a menu item.

Call Detach to Detach the menu handle from the menu object.

Finally, call SetMenu to allocate the created menu to the specified window.

 

  • Create a pop-up menu [1]

Steps:

① Create a dialog box project and declare a CMenu Class Object m_Menu in the header file.

② Insert a menu resource and set the menu

③ In the OnInitDialog function of the dialog box, add:

M_Menu.LoadMenu (IDR_MENU1); // load menu Resources

④ Right-click the dlg and choose OnRButtonUp from the shortcut menu to edit the code.

Void CPopupMenuDlg: OnRButtonUp (UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

CMenu * pMenu = m_Menu.GetSubMenu (0); // obtain the menu handle

CRect rect;

ClientToScreen (& point); // convert customer coordinates to screen coordinates

Rect. top = point. x; // The current horizontal coordinates of the mouse are used as the coordinates in the upper left corner of the pop-up menu.

Rect. left = point. y;

PMenu-> TrackPopupMenu (TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL,

Rect. top, rect. left, this, & rect); // display the pop-up menu

CDialog: OnRButtonUp (nFlags, point); // call the method of the base class

}

⑤ Add a menu to process events .. For example ..

Void CPopupMenuDlg: OnMenuadd ()

{

// TODO: Add your command handler code here

MessageBox ("menu pressed ");

}

Note:

First, create a menu resource and call the LoadMenu method to load the menu resource.

Call the GetSubMenu method to obtain a menu item in the pop-up menu.

Finally, call the TrackPopupMenu method to display a pop-up menu.

 

  • Create a pop-up menu method 2 [2]

<03.rar>>

  • Create Icon menu [2]

① Create a single document project, create a menu class CIconMenu, derived from CMenu

② Define menu information in the CIconMenu header file, define some member variables, and add the AttachMenu method to CIconMenu, as shown below:

/*************************************

The CMenuItemInfo structure is used to record menu item information.

*************************************/

Struct CMenuItemInfo

{

CString m_ItemText; // menu item text

Int m_IconIndex; // menu item index

Int m_ItemID; // menu tag-2 top menu,-1 pop-up menu, 0 separator bar, other common menus

};

/*************************************/

Public:

CMenuItemInfo m_ItemLists [MAX_MENUCOUNT]; // menu item information

Int m_index; // temporary Index

Int m_iconindex; // index of the menu item icon

CImageList m_imagelist; // stores the menu item icon

/*************************************/

BOOL CIconMenu: AttatchMenu (HMENU m_hmenu)

{

This-> Attach (m_hmenu );

Return TRUE;

}

③ Compile the conmenu class Constructor

CIconMenu: CIconMenu ()

{

M_index = 0;

M_iconindex = 0;

// Create an image list

M_imagelist.Create (16, 16, ILC_COLOR24 | ILC_MASK, 0, 0 );

// Add an icon

M_imagelist.Add (AfxGetApp ()-> LoadIcon (IDI_ICON1 ));

M_imagelist.Add (AfxGetApp ()-> LoadIcon (IDI_ICON2 ));

M_imagelist.Add (AfxGetApp ()-> LoadIcon (IDI_ICON3 ));

M_imagelist.Add (AfxGetApp ()-> LoadIcon (IDI_ICON4 ));

M_imagelist.Add (AfxGetApp ()-> LoadIcon (IDI_ICON5 ));

M_imagelist.Add (AfxGetApp ()-> LoadIcon (IDI_ICON6 ));

M_imagelist.Add (AfxGetApp ()-> LoadIcon (IDI_ICON7 ));

M_imagelist.Add (AfxGetApp ()-> LoadIcon (IDI_ICON8 ));

M_imagelist.Add (AfxGetApp ()-> LoadIcon (IDI_ICON9 ));

M_imagelist.Add (AfxGetApp ()-> LoadIcon (IDI_ICON10 ));

}

④ Add the ChangeMenuItem method to the CIconMenu class to modify the menu item information, so that it contains the MF_OWNERDRAW style, and store the menu item information in the m_ItemLists member variable.

BOOL CIconMenu: ChangeMenuItem (CMenu * m_menu, BOOL m_Toped)

{

If (m_menu! = NULL)

{

Int m_itemcount = m_menu-> GetMenuItemCount ();

For (int I = 0; I <m_itemcount; I ++)

{

M_menu-> GetMenuString (I, m_ItemLists [m_index]. m_ItemText, MF_BYPOSITION );

Int m_itemID = m_menu-> GetMenuItemID (I );

If (m_itemID =-1 & m_Toped)

{

M_itemID =-2; // top menu

};

M_ItemLists [m_index]. m_ItemID = m_itemID;

If (m_itemID> 0)

{

M_ItemLists [m_index]. m_IconIndex = m_iconindex;

M_iconindex + = 1;

}

M_menu-> ModifyMenu (I, MF_OWNERDRAW | MF_BYPOSITION | MF_STRING, m_ItemLists [m_index]. m_ItemID, (LPSTR) & (m_ItemLists [m_index]);

 

M_index + = 1;

CMenu * m_subMenu = m_menu-> GetSubMenu (I );

 

If (m_subMenu)

{

ChangeMenuItem (m_subMenu );

}

}

}

Return TRUE;

}

⑤ Rewrite the MeasureItem virtual method of the menu class to calculate the menu item size

Void CIconMenu: MeasureItem (LPMEASUREITEMSTRUCT lpStruct)

{

If (lpStruct-> CtlType = ODT_MENU)

{

LpStruct-> itemHeight = ITEMHEIGHT;

LpStruct-> itemWidth = ITEMWIDTH;

CMenuItemInfo * m_iteminfo;

M_iteminfo = (CMenuItemInfo *) lpStruct-> itemData;

LpStruct-> itemWidth = (CMenuItemInfo *) lpStruct-> itemData)-> m_ItemText.GetLength () * 10;

Switch (m_iteminfo-> m_ItemID)

{

Case 0: // Separator

{

LpStruct-> itemHeight = 1;

Break;

}

}

}

}

 

⑥ Add the member function DrawItemText to draw the menu item text, DrawMenuIcon to draw the menu item icon, DrawSeparater to draw the separation bar, DrawTopMenu to draw the top menu, and DrawComMenu to draw the gradient effect in the menu item area.

/*************************************** **********************

Function Description: draws the menu item text.

 

Parameter description: m_pdc identifies the canvas object, str identifies the menu text, and m_rect identifies the menu area.

**************************************** *********************/

Void CIconMenu: DrawItemText (CDC * m_pdc, LPSTR str, CRect m_rect)

{

M_rect.DeflateRect (20, 0 );

M_pdc-> DrawText (str, m_rect, DT_SINGLELINE | DT_VCENTER | DT_LEFT );

}

 

Void CIconMenu: DrawTopMenu (CDC * m_pdc, CRect m_rect, BOOL m_selected)

{

If (m_selected)

{

M_pdc-> SelectStockObject (BLACK_PEN );

M_pdc-> Rectangle (& m_rect );

M_rect.DeflateRect (1, 1 );

M_pdc-> FillSolidRect (m_rect, RGB (150,185,255 ));

}

Else

{

CRect rect;

AfxGetMainWnd ()-> GetClientRect (rect );

Rect. top = m_rect.top;

Rect. bottom = m_rect.bottom;

Rect. left = 360;

Rect. right + = 4;

// CRect c_rect (m_rect );

M_pdc-> FillSolidRect (& rect, RGB (200,187,255 ));

M_pdc-> FillSolidRect (& m_rect, RGB (200,187,255 ));

// M_pdc-> SelectStockObject (BLACK_PEN );

// M_pdc-> FillSolidRect (m_rect, RGB (100,185,255 ));

}

}

 

Void CIconMenu: DrawSeparater (CDC * m_pdc, CRect m_rect)

{

If (m_pdc! = NULL)

{

M_pdc-> Draw3dRect (m_rect, RGB (255, 0), RGB ));

}

}

 

Void CIconMenu: DrawComMenu (CDC * m_pdc, CRect m_rect, COLORREF m_fromcolor, COLORREF m_tocolor, BOOL m_selected)

{

If (m_selected)

{

 

M_pdc-> Rectangle (m_rect );

M_rect.DeflateRect (1, 1 );

Int r1, g1, b1;

// Read the color value of the gradient start point

R1 = GetRValue (m_fromcolor );

G1 = GetGValue (m_fromcolor );

B1 = GetBValue (m_fromcolor );

Int r2, g2, b2;

 

 

// Read the color value of the gradient end point

R2 = GetRValue (m_tocolor );

G2 = GetGValue (m_tocolor );

B2 = GetBValue (m_tocolor );

 

Float r3, g3, b3; // The degree (range) in which the RGB value of each vertex changes horizontally in the menu area)

 

R3 = (float) (r2-r1)/(float) (m_rect.Height ());

G3 = (float) (g2-g1)/(float) (m_rect.Height ());

B3 = (float) (b2-b1)/(float) (m_rect.Height ());

 

COLORREF r, g, B; // color value of each vertex in the horizontal direction of the menu area

CPen * m_oldpen;

 

For (int I = m_rect.top; I <m_rect.bottom; I ++)

{

R = r1 + (int) r3 * (i-m_rect.top );

G = g1 + (int) g3 * (i-m_rect.top );

B = b1 + (int) b3 * (i-m_rect.top );

 

CPen m_pen (PS_SOLID, 1, RGB (r, g, B ));

M_oldpen = m_pdc-> SelectObject (& m_pen );

M_pdc-> MoveTo (m_rect.left, I );

M_pdc-> LineTo (m_rect.right, I );

}

 

M_pdc-> SelectObject (m_oldpen );

}

Else

{

M_pdc-> FillSolidRect (m_rect, RGB (0x000000F9, 0x000000F8, 0x000000F7 ));

}

}

 

Void CIconMenu: DrawMenuIcon (CDC * m_pdc, CRect m_rect, int m_icon)

{

M_imagelist.Draw (m_pdc, m_icon, CPoint (m_rect.left + 2, m_rect.top + 4), ILD_TRANSPARENT );

}

 

7. Rewrite the DrawItem virtual method of the menu and draw the menu according to the different states of the menu item. The Code is as follows:

Void CIconMenu: DrawItem (LPDRAWITEMSTRUCT lpStruct)

{

If (lpStruct-> CtlType = ODT_MENU)

{

If (lpStruct-> itemData = NULL) return;

Unsigned int m_state = lpStruct-> itemState;

CDC * m_dc = CDC: FromHandle (lpStruct-> hDC );

// M_dc.Attach (lpStruct-> hDC );

 

CString str = (CMenuItemInfo *) (lpStruct-> itemData)-> m_ItemText;

LPSTR m_str = str. GetBuffer (str. GetLength ());

 

Int m_itemID = (CMenuItemInfo *) (lpStruct-> itemData)-> m_ItemID;

Int m_itemicon = (CMenuItemInfo *) (lpStruct-> itemData)-> m_IconIndex;

CRect m_rect = lpStruct-> rcItem;

 

M_dc-> SetBkMode (TRANSPARENT );

 

Switch (m_itemID)

{

Case-2:

{

 

DrawTopMenu (m_dc, m_rect, (m_state & ODS_SELECTED) | (m_state & 0x0040); // 0x0040 = ODS_HOTLIGHT

 

DrawItemText (m_dc, m_str, m_rect );

Break;

}

Case-1:

{

DrawItemText (m_dc, m_str, m_rect );

Break;

}

Case 0:

{

DrawSeparater (m_dc, m_rect );

Break;

}

Default:

{

DrawComMenu (m_dc, m_rect, 0xfaa0, 0xf00ff, m_state & ODS_SELECTED );

DrawItemText (m_dc, m_str, m_rect );

DrawMenuIcon (m_dc, m_rect, m_itemicon );

Break;

}

}

}

}

 

Introduce the CIconMenu header file in the framework class to define a member m_menu of the CIconMenu type. Process WM_DRAWITEM messages of the framework class and call the MeasureItem method of the m_menu object in its message processing function. The Code is as follows:

Void CMainFrame: OnMeasureItem (int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)

{

M_menu.MeasureItem (lpMeasureItemStruct );

// CFrameWnd: OnMeasureItem (nIDCtl, lpMeasureItemStruct );

}

 

Combine associates the m_menu object with the menu window in the application in the OnCreate method of the framework class. The Code is as follows:

M_menu.AttatchMenu (this-> GetMenu ()-> GetSafeHmenu ());

M_menu.ChangeMenuItem (& m_menu, TRUE );

 

 

  • Create Icon menu [1]

① Create a dialog box project, create a menu resource, set the menu, create a menu class CMenuIcon, derived from Cmenu

<IconMenu.rar>

 

Author: SKySeraph

Email/GTalk: zgzhaobo@gmail.com QQ: 452728574

From: http://www.cnblogs.com/skyseraph/

The copyright of this article is shared by the author and the blog. You are welcome to repost this article. However, you must keep this statement without the author's consent and provide the original article connection clearly on the article page. Please respect the author's Labor achievements.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.