分享
 
 
 

VC++的菜单控制和自绘菜单。

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

菜单控制

为什么即使调用EnableMenuItem菜单项后,菜单项还处于禁止状态

需要将CFrameWnd:: m_bAutomenuEnable设置为FALSE,如果该数据成员为TRUE(缺省值),工作框将自动地禁止没有ON_UPDATE_COMMAND_UI或者ON_COMMAND的菜单项。

//Disable MFC from automatically disabling menu items.

m_bAuoMenuEnable=FALSE;

//Now enable the menu item.

CMenu* pMenu=GetMenu ();

ASSERT_VALID (pMenu);

pMenu->EnableMenuItem (ID_MENU_ITEM,MF_BYCOMMAND | MF_ENABLED);

如何给系统菜单添加一个菜单项

给系统菜单添加一个菜单项需要进行下述三个步骤:

首先,使用Resource Symbols对话(在View菜单中选择Resource Symbols...

可以显示该对话)定义菜单项ID,该ID应大于0x0F而小于0xF000;

其次,调用CWnd::GetSystemMenu获取系统菜单的指针并调用CWnd:: Appendmenu将菜单项添加到菜单中。下例给系统菜单添加两个新的菜单项:

int CMainFrame:: OnCreate (LPCREATESTRUCT lpCreateStruct)

{

//Make sure system menu item is in the right range.

ASSERT (IDM_MYSYSITEM &0xFFF0)==IDM_MYSYSITEM);

ASSERT (IDM-MYSYSITEM<0xF000);

//Get pointer to system menu.

CMenu* pSysmenu=GetSystemmenu (FALSE);

ASSERT_VALID (pSysMenu);

//Add a separator and our menu item to system menu.

CString StrMenuItem (_T ("New menu item"));

pSysMenu->Appendmenu (MF_SEPARATOR);

pSysMenu->AppendMenu (MF_STRING, IDM_MYSYSITEM, strMenuitem);

}

现在,选择系统菜单项时用户应进行检测。使用ClassWizard处理

WM_SYSCOMMAND消息并检测用户菜单的nID参数:

void CMainFrame:: OnSysCommand (UINT nID,LPARAM lParam)

{

//Determine if our system menu item was selected.

if ( (nID & 0xFFF0)==IDM_MYSYSITEM)

{

//TODO-process system menu item

}

else

CMDIFrameWnd:: OnSysCommand (nID, lParam);

}

最后,一个设计良好的UI应用程序应当在系统菜单项加亮时在状态条显示一个帮助信息,这可以通过增加一个包含系统菜单基ID的串表的入口来实现。

如何确定顶层菜单所占据的菜单行数

这可以通过简单的减法和除法来实现。首先,用户需要计算主框窗口的高度和客户区;其次,从主框窗口的高度中减去客户区、框边界以及标题的高度;最后,除以菜单栏的高度。下例成员函数是一个计算主框菜单所占据的行数的代码实现。

int CMainFrame:: GetMenuRows ()

{

CRect rcFrame,rcClient;

GetWindowRect (rcFrame);

GetClientRect (rcClient);

return (rcFrame.Height () -rcClient.Height ()-

:: GetSystemMetrics (SM_CYCAPTION) -

(:: getSystemMetrics (SM_CYFRAME) *2)) /

:: GetSystemMetrics (SM_CYMENU);

}

自绘菜单

闻怡洋译

在这里提供一个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->itemID) &&

(lpMeasureItemStruct->itemID == (UINT)m_hMenuSub) )

{

m_customMenu.MeasureItem (lpMeasureItemStruct);

}

else

// let MFC's 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;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有