设计漂亮实用的菜单

转载 2006年06月25日 17:16:00
谈在VC中动态改变菜单

bull77 yesky

  大部分Windows应用程序都使用下拉式菜单实现自己特定的函数,它使编程更加方便,不需要在程序中增加多个按钮以完成这些操作。大多数情况下,我 们的程序编译生成后,菜单就确定了,不能再修改。然而,在很多情况下,程序要根据用户的自己设置产生不同的菜单以适应不同用户的要求,这就需要我们动态的 改变菜单。接下来我们就分析如何动态的生成不同的菜单。

  第一步:

  运行AppWizard生成一个工程mymenu,接受所有的默认设置,除了下面一步:在step 1中选Single Document ,点击Finish按钮,此时我们生成了一个工程。编译运行,我们可以发现程序默认生成的菜单,接下来我们要对这个菜单进行修改。

  第二步:

  添加一个菜单资源,按如下步骤:菜单中选择InsertàResouceàMenuàNew ,我们可以看到添加了一个ID号为IDR_MENU1的菜单资源,至于菜单中的各项你就随便添加了,为了我们下面的编程,请你添加几项,第一列要包含几个子菜单。

  第三步:

  添加一个对话框资源,按如下步骤:菜单中选择InsertàResouceàDialogàNew ,我们可以看到添加了一个ID号为IDD_DIALOG1的对话框资源,添加六个按钮,如下图:



ID号依次为ID_CLEAR, ID_GOONE ,ID_GOTWO, ID_ADD, ID_ADDITEM, ID_EDIT ,为对话框定义类名为CChangeMenu, 双击添加的六个按钮增加处理函数,用默认函数名。

  第四步:

  在IDR_MAINFRAME菜单中添加一项,ID号为ID_SET,名为"弹出设置对话框",为其添加处理函数,添加如下代码:

  CChangeMenu dlg;
  dlg.DoModal();

  当然,别忘了在文件的开头添加#include "changemenu . h"

  第五步:

  找到添加的六个按钮的处理函数,依次添加如下的代码:

  void CChangeMenu::OnClear()
   {
    AfxGetMainWnd()->SetMenu(NULL);
    AfxGetMainWnd()->DrawMenuBar();
   }

  void CChangeMenu::OnGoone()
   {
    if(!menu1){
     menu1.LoadMenu(IDR_MENU1);
     AfxGetMainWnd()->SetMenu(&menu1);
     AfxGetMainWnd()->DrawMenuBar();
     menu1.Detach();
    }
   }

  void CChangeMenu::OnGotwo()
   {
    if(!menu2){
     menu2.LoadMenu(IDR_MAINFRAME);
     AfxGetMainWnd()->SetMenu(&menu2);
     AfxGetMainWnd()->DrawMenuBar();
     menu2.Detach();
    }
   }

  void CChangeMenu::OnAdd()
   {
    static int x=400;
    AfxGetMainWnd()->GetMenu()->AppendMenu(MF_STRING,x,"mynew");
    AfxGetMainWnd()->DrawMenuBar();
    x++;
   }

  void CChangeMenu::OnAdditem()
   {
    static int y=500;
    AfxGetMainWnd()->GetMenu()->GetSubMenu(0)->InsertMenu(1,MF_BYPOSITION,y,"mynewitem");
    AfxGetMainWnd()->DrawMenuBar();
    y++;
   }

  void CChangeMenu::OnEdit()
   {
    AfxGetMainWnd()->GetMenu()->ModifyMenu(0,MF_BYPOSITION,402,"dfd");
    AfxGetMainWnd()->DrawMenuBar();
   }

  好了,到这里我们所有的功能就都实现了,快编译运行一下吧!怎么样?还满意吗?


如何用VC++5在菜单中增加位图或图标

天涯风铃


  我们在使用Windows 95时,可以注意到在“开始”组中的菜单项前都有一个图标,而且在Word 97中的菜单项前也有一个图标。这些图标不但让我们清楚地了解到屏幕上的各种工具按钮与各个菜单项之间的联系,而且还增加了应用程序界面的美观。那么,请 问如何用Visual C++ 5.0在应用程序菜单中增加图标?
  MFC的CMenu类有一个成员函数SetMenuItemBitmaps,可以用于往菜单中增加图标。具体方法如下:

  在应用程序的资源文件中添加想要增加的位图,并将其ID命名为IDB_OPEN1和IDB_OPEN2;---在应用程序的视图类中添加CBitmap类的对象,不妨取名为bm_open1和bm_open2。在视图类的构造函数中添加以下代码:

  bm_open1.LoadBitmap(IDB_OPEN1);bm_open2.LoadBitmap(IDB_OPEN2);(函数LoadBitmap用于加载位图到CBitmap类的对象)在视图类的成员函数OnDraw()中添加以下代码:

  CWnd*parent=GetParent();CMenu*pmenubar=parent-$#@62;GetMenu();    

  CMenu*pmenu=pmenubar-$#@62;GetSubMenu(2);

  pmenu-$#@62;SetMenuItemBitmaps(1,MF_BYPOSITION,&bm_open1,&bm_open2);

  前三行得到指向菜单的指针,第四行调用函数SetMenuItemBitmaps往菜单中增加图标,具体参数的含义可参见有关介绍MFC及其成员函数的书即可。


自绘菜单

闻怡洋


在这里提供一个C++类(CCustomMenu),该类是CMenu的子类,并且拥有自绘能力。它可以向你提供以下的功能:

设置字体颜色。
设置高亮度颜色。
设置高亮度时的风格。
设置选中时和在普通状态下的菜单显示的图标。
设置显示图标大小。
  在CCustomMenu中定义了结构MENUDATA,你必须根据你的需要填充该结构,并且在增加菜单时提供该结构的指针(调用AppendMenu,InsertMenu)。下面是一个例子:

1、定义CCustomMenu的实例,和MENUDATA结构变量。

CCustomMenu m_cCustomMenu;
MENUDATA menuData [8];
// as many menu items are present ,
//You should be able to use
//new and do the same

2、调用CreateMenu()设置有关参数。
m_customMenu.CreateMenu ();
m_customMenu.SetIconSize (25,25);
//This is to set the size of the Icon.
// This should be used only once for any menu
// in order to resize it, destroy and create the menu again with different size.
m_customMenu.SetHighlightStyle (Normal); //Or TextOnly, if you want the
// background color to remain the same
// and the Text color to change to the Highlight color.
// The following setXXXColor sets the menu colors.     //If you dont want to change any, Dont call these member functions.
m_customMenu.SetTextColor (RGB (255,0,0));
m_customMenu.SetBackColor (RGB (255,255,255));
m_customMenu.SetHighlightColor (RGB (0,0,255));
3、设置MENUDATA变量,并增加菜单项。
lstrcpy (menuData[0].menuText , "text1");
menuData[0].menuIconNormal= IDI_ICON1;
m_customMenu.AppendMenu (MF_OWNERDRAW,3,(LPCTSTR)menuData);

3、在你的窗口中重载OnMeasureItem(...)函数。
void CMyView::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
if ( lpMeasureItemStruct->CtlType == ODT_MENU &&
IsMenu((HMENU)lpMeasureItemStruct->i ID) &&
(lpMeasureItemStruct->itemID == (UINT)m_hMenuSub) )
{
m_customMenu.MeasureItem (lpMeasureItemStruct);
}
else
// let MFCs self-drawing handle it
CView::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
}

下面的函数将帮助你设置菜单属性。

void SetTextColor (COLORREF );
void SetBackColor (COLORREF);
void SetHighlightColor (COLORREF);
void SetIconSize (int, int);
void SetHighlightStyle (HIGHLIGHTSTYLE ); // HIGHLIGHTSTYLE : enum {Normal, TextOnly}
void SetHighlightTextColor (COLORREF);



下面是文件代码:
//*************************************************************************
// CustomMenu.h : header file
//

#if
!defined(AFX_CUSTOMMENU_H__FE5B01C3_1E02_11D1_B87A_0060979CDF6D__INCLUDED_)
#define AFX_CUSTOMMENU_H__FE5B01C3_1E02_11D1_B87A_0060979CDF6D__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
class MENUDATA
{
public:
MENUDATA () { menuIconNormal = -1; menuIconSelected = -1;};
char menuText[32];
UINT menuIconNormal;
UINT menuIconSelected;
};


typedef enum {Normal,TextOnly} HIGHLIGHTSTYLE;

///////////////////////////////////////////////////////////////////////////
//
// CCustomMenu window

class CCustomMenu : public CMenu
{
// Construction
public:
CCustomMenu();

// Attributes
public:

// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCustomMenu)
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CCustomMenu();
virtual void DrawItem( LPDRAWITEMSTRUCT);
virtual void MeasureItem( LPMEASUREITEMSTRUCT );
void SetTextColor (COLORREF );
void SetBackColor (COLORREF);
void SetHighlightColor (COLORREF);
void SetIconSize (int, int);
void SetHighlightStyle (HIGHLIGHTSTYLE );
void SetHighlightTextColor (COLORREF);

// Generated message map functions
protected:
COLORREF m_crText;
COLORREF m_clrBack;
COLORREF m_clrText;
COLORREF m_clrHilight;
COLORREF m_clrHilightText;
LOGFONT m_lf;
CFont m_fontMenu;
UINT m_iMenuHeight;
BOOL m_bLBtnDown;
CBrush m_brBackground,m_brSelect;
CPen m_penBack;
int m_iconX,m_iconY;
HIGHLIGHTSTYLE m_hilightStyle;

//{{AFX_MSG(CCustomMenu)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
};

///////////////////////////////////////////////////////////////////////////
//

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.

#endif //!defined(AFX_CUSTOMMENU_H__FE5B01C3_1E02_11D1_B87A_0060979CDF6D__INCLUDED_)

//*************************************************************************
// CustomMenu.cpp : implementation file
//

#include "stdafx.h"
#include "CustomMenu.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

///////////////////////////////////////////////////////////////////////////
//
// CCustomMenu

CCustomMenu::CCustomMenu()
{
m_clrText = GetSysColor (COLOR_MENUTEXT);
m_clrBack = GetSysColor (COLOR_MENU);
m_brBackground.CreateSolidBrush (m_clrBack);
m_penBack.CreatePen (PS_SOLID,0,m_clrBack);
m_crText = m_clrText;
m_bLBtnDown = FALSE;
m_iconX = GetSystemMetrics ( SM_CXMENUCHECK);
m_iconY = GetSystemMetrics (SM_CYMENUCHECK );

m_clrHilight = GetSysColor (COLOR_HIGHLIGHT);
m_brSelect.CreateSolidBrush (m_clrHilight);
m_clrHilightText = GetSysColor (COLOR_HIGHLIGHTTEXT);

ZeroMemory ((PVOID) &m_lf,sizeof (LOGFONT));
NONCLIENTMETRICS nm;
nm.cbSize = sizeof (NONCLIENTMETRICS);

//Get the system metrics for the Captionfromhere
VERIFY (SystemParametersInfo (SPI_GETNONCLIENTMETRICS,0,&nm,0));

m_lf = nm.lfMenuFont;
m_iMenuHeight = nm.iMenuHeight;
m_fontMenu.CreateFontIndirect (&m_lf);
}

CCustomMenu::~CCustomMenu()
{
if ((HBRUSH) m_brBackground != NULL)
m_brBackground.DeleteObject ();
if ((HFONT)m_fontMenu !=NULL)
m_fontMenu.DeleteObject ();
if ((HBRUSH)m_brSelect != NULL)
m_brSelect.DeleteObject ();
}



///////////////////////////////////////////////////////////////////////////
//
// CCustomMenu message handlers


void CCustomMenu::DrawItem (LPDRAWITEMSTRUCT lpDIS)
{
ASSERT(lpDIS != NULL);

CDC* pDC = CDC::FromHandle(lpDIS->hDC);
CRect rect;
HICON hIcon;
COLORREF crText = m_crText;
// draw the colored rectangle portion
rect.CopyRect(&lpDIS->rcItem);

// draw the up/down/focused/disabled state

UINT action = lpDIS->itemAction;
UINT state = lpDIS->itemState;
CString strText;
LOGFONT lf;
lf = m_lf;

CFont dispFont;
CFont *pFont;
//GetWindowText(strText);
if (lpDIS->itemData != NULL)
{
strText = (((MENUDATA*) (lpDIS->itemData))->menuText);
if ((((MENUDATA *)(lpDIS->itemData))->menuIconNormal) == -1)
hIcon = NULL;
else if (state & ODS_SELECTED)
{
if ((((MENUDATA *)(lpDIS->itemData))->menuIconSelected) != -1)
hIcon = AfxGetApp ()->LoadIcon (( (MENUDATA *)(lpDIS->itemData))->menuIconSelected);
else
hIcon = AfxGetApp()->LoadIcon (( (MENUDATA*)(lpDIS->itemData))->menuIconNormal);
}
else
hIcon = AfxGetApp()->LoadIcon ( ((MENUDATA*)(lpDIS->itemData))->menuIconNormal);

TRACE1 ("Draw for %s/n", strText);
}
else
{
strText.Empty();
hIcon = NULL;
}

if ( (state & ODS_SELECTED) )
{
// draw the down edges

CPen *pOldPen = pDC->SelectObject (&m_penBack);

//You need only Text highlight and thats what you get
if (m_hilightStyle != Normal)
{
pDC->FillRect (rect,&m_brBackground);
}
else
{
pDC->FillRect (rect,&m_brSelect);
}

pDC->SelectObject (pOldPen);
pDC->Draw3dRect (rect,GetSysColor (COLOR_3DHILIGHT),GetSysColor(COLOR_3DSHADOW));
lf.lfWeight = FW_BOLD;
if ((HFONT)dispFont != NULL)
dispFont.DeleteObject ();
dispFont.CreateFontIndirect (&lf);
crText = m_clrHilightText;

//While selected move the text a bit
TRACE0 ("SELECT,SELECTED/n");
}
else
{
CPen *pOldPen = pDC->SelectObject (&m_penBack);
pDC->FillRect (rect,&m_brBackground);
pDC->SelectObject (pOldPen);
// draw the up edges
pDC->Draw3dRect (rect,m_clrBack,m_clrBack);
if ((HFONT)dispFont != NULL)
dispFont.DeleteObject ();
dispFont.CreateFontIndirect (&lf); //Normal

TRACE0 ("SELECT, NORMAL/n");
}

// draw the text if there is any
//We have to paint the text only if the image is nonexistant
if (hIcon != NULL)
{
if(DrawIconEx (pDC->GetSafeHdc(),rect.left,rect.top,hIcon,
(m_iconX)?m_iconX:32,(m_iconY)?m_iconY:32,0,NULL,DI_NORMAL))
TRACE0("Wrote the icon successfully/n");
else
TRACE0 ("SORRY.NOGO/n");
}
//This is needed always so that we can have the space for check marks
rect.left = rect.left +((m_iconX)?m_iconX:32);

if ( !strText.IsEmpty())
{
// pFont->GetLogFont (&lf);

int iOldMode = pDC->GetBkMode();

pDC->SetBkMode( TRANSPARENT);

pDC->SetTextColor( crText);

pFont = pDC->SelectObject (&dispFont);
TRACE1( "About To DrawText %s/n",strText);
pDC->DrawText (strText,rect,DT_LEFT|DT_SINGLELINE|DT_VCENTER);
TRACE0("Done/n");
pDC->SetBkMode( iOldMode );
pDC->SelectObject (pFont); //set it to the old font
}
dispFont.DeleteObject ();
}

void CCustomMenu::MeasureItem( LPMEASUREITEMSTRUCT lpMIS )
{
CDC *pDC = AfxGetApp()->m_pMainWnd->GetDC();
CFont* pFont = pDC->SelectObject (&m_fontMenu);
int iconX = 0,iconY= 0;
TEXTMETRIC tm;
pDC->GetTextMetrics (&tm);
pDC->SelectObject (pFont);
AfxGetApp()->m_pMainWnd->ReleaseDC (pDC);

if (m_iconX)
iconX = m_iconX;
if (m_iconY)
iconY = m_iconY;

lpMIS->itemWidth = iconX + tm.tmAveCharWidth * lstrlen(((MENUDATA*)(lpMIS->itemData))->menuText) +10;
lpMIS->itemHeight = (iconY > (m_iMenuHeight+1))?iconY:m_iMenuHeight + 1;
}

void CCustomMenu::SetIconSize (int width, int height)
{
m_iconX = width;
m_iconY = height;
}

void CCustomMenu::SetTextColor (COLORREF clrText)
{
m_crText = clrText;
}

void CCustomMenu::SetBackColor (COLORREF clrBack)
{
m_clrBack = clrBack;
if ((HBRUSH)m_brBackground != NULL)
m_brBackground.DeleteObject ();
m_brBackground.CreateSolidBrush (clrBack);
}

void CCustomMenu::SetHighlightColor (COLORREF clrHilight)
{
m_clrHilight = clrHilight;
if ((HBRUSH)m_brSelect != NULL)
m_brSelect.DeleteObject ();
m_brSelect.CreateSolidBrush (clrHilight);
}

void CCustomMenu::SetHighlightTextColor (COLORREF clrHilightText)
{
m_clrHilightText = clrHilightText;
}


void CCustomMenu::SetHighlightStyle (HIGHLIGHTSTYLE hilightStyle)
{
m_hilightStyle = hilightStyle;
}
//*************************************************************************



在系统菜单中加子菜单
CPCW

系统菜单与其它菜单类似,你可以添加或删除项目,这需要使用CMenu 类的成员函数。下面的代码在你的系统菜单后面添加一个新菜单项:

CMenu *sysmenu;
sysmenu = m_pMainWnd->GetSystemMenu(FALSE);
sysmenu->AppendMenu(MF_STRING, 1000, "xxx");
参见MFC 帮助文件中的CMenu 类
举报

相关文章推荐

delphi像“开始”菜单一样漂亮的菜单项实例

====================================================== 注:本文源代码点此下载 =============================...

推荐Jquery 40个漂亮的导航菜单设计

在网站上看到以下一些漂亮的导航菜单,很酷 很炫耀,推荐给大家。点击超链接即可进入详细页面 Utah Travel Lift Interactive Mai...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

30 +漂亮的jQuery菜单导航(一)

目前,jQuery的菜单正变得越来越流行。我们可以使用jQuery创造美化菜单,通过一些鼠标操作让菜单变的有吸引力和有趣。        jQuery菜单插件,用于创建与动态(动画)背景菜单。每个菜...

Android:制作漂亮的菜单

主菜单包括File、Edit和Help三个菜单项。File菜单有New、Open和Save子菜单项;Edit菜单有Cut、Copy和Paste子菜单项;Help菜单有About和Exit子菜单项。其中...

漂亮实用的日历

站长特效网,站长必备的高质量网页特效和广告代码。zzjs.net,站长js特效。 网页特效 一个很漂亮实用的日历 站长特效网欢迎您 //创建一个数组,用于存放每个月的天...

1278 hdu 漂亮面料的设计

现在的CAD技术已经能够很方便地设计出漂亮的面料,如图(b)所示。图(a)是所对应的组织图,它表示纱线的交织规律,经过分析表明:组织规律可以用一个二维矩阵准确描述出来。 图(a)的描述矩阵为...

hdu1278 漂亮面料的设计(模拟)

漂亮面料的设计 Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total...

20个漂亮的HTML5网站设计

本文转载自互联网,如涉及到版权问题,请及时联系博主,我将第一时间删除,我的个人邮箱veryszhang@gmail.com 1.Hush Selected 访问网站 2. The Joe B...

分享10个免费漂亮的DIV+CSS常用菜单

css菜单持续更新中.... 1.具有动感弹力效果的漂亮蓝色二级横向导航菜单   2. 蓝色圆角横向二级下拉菜单导航栏   3.js蓝色效果横向二级导航菜...

漂亮的dialog

先上效果图片吧: 代码如下:  提示信息
  • zz_mm
  • zz_mm
  • 2012-09-03 16:58
  • 1210
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)