菜单设计.docx

上传人:b****1 文档编号:1657236 上传时间:2023-05-01 格式:DOCX 页数:22 大小:423.86KB
下载 相关 举报
菜单设计.docx_第1页
第1页 / 共22页
菜单设计.docx_第2页
第2页 / 共22页
菜单设计.docx_第3页
第3页 / 共22页
菜单设计.docx_第4页
第4页 / 共22页
菜单设计.docx_第5页
第5页 / 共22页
菜单设计.docx_第6页
第6页 / 共22页
菜单设计.docx_第7页
第7页 / 共22页
菜单设计.docx_第8页
第8页 / 共22页
菜单设计.docx_第9页
第9页 / 共22页
菜单设计.docx_第10页
第10页 / 共22页
菜单设计.docx_第11页
第11页 / 共22页
菜单设计.docx_第12页
第12页 / 共22页
菜单设计.docx_第13页
第13页 / 共22页
菜单设计.docx_第14页
第14页 / 共22页
菜单设计.docx_第15页
第15页 / 共22页
菜单设计.docx_第16页
第16页 / 共22页
菜单设计.docx_第17页
第17页 / 共22页
菜单设计.docx_第18页
第18页 / 共22页
菜单设计.docx_第19页
第19页 / 共22页
菜单设计.docx_第20页
第20页 / 共22页
亲,该文档总共22页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

菜单设计.docx

《菜单设计.docx》由会员分享,可在线阅读,更多相关《菜单设计.docx(22页珍藏版)》请在冰点文库上搜索。

菜单设计.docx

菜单设计

选择资源面板,在Menu(菜单)节点下,双击IDR_MAINFRAME页节点,在编辑区就会将当前应用程序的菜单打开。

如图1-37所示。

该菜单是由MFC应用程序框架所提供的初始菜单。

我们要修改此菜单,添加我们所需要的菜单项。

在修改菜单之前,我们先了解一些菜单编辑的相关知识。

我们都知道,Windows的菜单是一种分级菜单,我们在菜单编辑区中用鼠标选择“文件(F)”菜单项,会打开该菜单项的下级菜单,如图1-38所示。

我们可以称“文件(F)”菜单项为第一级菜单,而其下级菜单为第二级菜单,如果第二级菜单还有下级菜单,选择该第二级菜单,其下级菜单会自动打开,这些菜单就是第三级菜单,以此类推。

选中菜单项后可以按“Delete”键将该菜单项删除,如果该菜单项有下级菜单,这些下级菜单将同时被删除,所以在删除具有下级菜单的菜单项之前,系统会进行讯问是否删除,选择“确定”将会进行删除。

初始菜单中的“文件(F)”和“编辑(E)”两个第一级菜单在我们的应用程序中是不需要的,我们可以将这两个一级菜单删除。

看图1-38,我们注意到在一级菜单项“帮助(H)”右侧有一个虚线矩形框,此处就是用来添加菜单项的,因为它在一级菜单栏上,所以添加的是一级菜单。

同样的,在“文件(F)”菜单项下的二级菜单“退出(X)”下,也有一个虚线矩形框,此处也可以添加菜单项,只是此处添加的是二级菜单。

我们可以用鼠标左键选择虚线矩形框,并按住鼠标左键不放,就可以挪动菜单项的位置。

比如,我们可以将一级菜单的虚线矩形框移到所有一级菜单的最左边,这样我们创建的菜单就会出现在最左边。

如图1-39所示,该菜单已经删除了“文件(F)”和“编辑(E)”两个一级菜单。

其它菜单项的位置也可以如此进行移动,这样我们就可以自由的调整菜单项的显示顺序。

现在我们来添加菜单。

在添加菜单之前,我们需要首先确定我们希望添加什么样的菜单项,菜单的结构是什么样的。

前面所介绍的绘图函数按照所绘制的图形可以大致分为两类,一类绘制的是线形的图形,另一类绘制的是封闭区域图形。

按照此分类,我们将创建下表中所列结构的菜单。

其中MoveTo函数因为本身并不绘制图形,所以单独作为一个二级菜单项,它没有下级菜单。

ID是菜单项的标志符,应用程序框架通过ID来区分各种资源。

一级菜单

二级菜单

三级菜单

ID

绘图函数

线形绘图函数

LineTo

ID_DRAW_LINETO

Polyline

ID_DRAW_POLYLINE

Arc

ID_DRAW_ARC

AngleArc

ID_DRAW_ANGLEARC

PolyBezier

ID_DRAW_POLYBEZIER

区域绘图函数

Rectangle

ID_DRAW_RECTANGLE

RoundRect

ID_DRAW_ROUNDRECT

Ellipse

ID_DRAW_ELLIPSE

Pie

ID_DRAW_PIE

Chord

ID_DRAW_CHORD

Polygon

ID_DRAW_POLYGON

用鼠标双击虚线矩形框,会出现“MenuItemProperties”(菜单项属性)对话框。

该对话框用于设置菜单项属性,如果双击的是一个已经存在的菜单项,则该对话框显示该菜单项的各种属性。

该对话框有两个分页:

“General”(通用属性)和“ExtendedStyles”(扩展类型)。

在“ExtendedStyles”页中只有一个“Right-to-leftorderandalignment”复选框,选择该复选框,菜单项标题将由右到左显示,并向右对齐。

通常情况我们都不会选择它。

在“General”页中可以设置菜单的各种属性。

“Caption”输入框。

用于输入菜单标题,应用程序执行时,该标题是我们所看到的菜单项的文字。

“Pop-up”复选框。

选中此复选框表示此菜单项具有下级菜单,此时“ID”下拉输入框,“Prompt”(说明)输入框及“Separator”复选框将处于灰色无效状态。

“ID”下拉输入框。

不选择“Pop-up”复选框,“ID”下拉输入框可以输入,在此输入此菜单项的ID。

下拉列表中会列出当前应用程序中所有已经使用的ID。

同时,如果此ID可以输入,则必须输入,否则系统将自动生成一个ID。

“Separator”复选框。

选中该复选框,菜单项将变成一条菜单分隔线,此时除“Caption”外,其它属性将都不能进行设置,而“Caption”虽然可以输入,但是一旦在“Caption”中输入值,则“Separator”复选框的选择将自动取消。

“Checked”复选框。

选中该复选框,应用程序运行时将在该菜单项前预先设置一个检查符号。

“Inactive”复选框。

选中该复选框,在应用程序运行时该菜单项不出现。

“Grayed”复选框。

选中该复选框,该菜单项以灰色显示,表示此菜单项不可用。

“Help”复选框。

选中该复选框,应用程序运行时将自动检查菜单项的合法性。

“Prompt”输入框。

用于输入菜单项的说明,当应用程序运行时,如果鼠标悬停在菜单项上,该说明将在状态栏中显示。

“Break”下拉框。

在此下拉框中有三项可选:

“None”,“Column”,“Bar”。

它们决定菜单的显示样式,默认是“None”。

选择“Column”,菜单项将以列的方式进行排列;选择“Bar”,菜单项以列的方式进行排列的同时将由竖线分隔开。

读者可以自行设置来观察效果,本应用程序的菜单都采用默认的“None”。

同时要注意的是,一个菜单项选择了非默认的菜单样式,所有的同级菜单项都将受到影响,如果同级菜单项中既有选择“Column”的,也有选择“Bar”的,则菜单样式将为“Bar”所指定的样式。

我们在当前打开的菜单项属性对话框中选择“Pop-up”复选框,并在“Caption”输入框输入“绘图函数”,关闭对话框,我们将看到“绘图函数”一级菜单已经创建。

同时在该菜单项下有一个虚线矩形框,我们可以双击它来输入下级菜单。

如图1-41所示。

双击图1-41中“绘图函数”菜单项下的虚线矩形框,在打开的菜单项属性对话框中,选择“Pop-up”复选框,并在“Caption”输入框输入“线形绘图函数”,关闭对话框,这样就创建了“线形绘图函数”二级菜单。

如图1-42所示。

双击图1-42中“线形绘图函数”菜单项右侧的虚线矩形框,在打开的菜单项属性对话框中,不选择“Pop-up”复选框,在“Caption”输入框输入“LineTo”,在“ID”下拉输入框中输入“ID_DRAW_LINETO”,然后关闭对话框,这样就创建了“LineTo”三级菜单。

如图1-43所示。

按照上述方法,可以将我们所需要的菜单项创建出来,二级菜单项输入“Caption”,并且选择“Pop-up”复选框,三级菜单项不选择“Pop-up”复选框,输入“Caption”和“ID”,具体值在菜单结构表中已经列出。

创建完的菜单如图1-44所示。

我们可以在“线形绘图函数”菜单项和“区域绘图函数”菜单项之间加上一条分隔线。

双击“区域绘图函数”菜单项下的虚线矩形框,在打开的菜单项属性对话框中选择“Separator”复选框。

然后关闭对话框,并将该菜单项移动到“区域绘图函数”菜单项上面。

其结果如图1-45所示。

此时我们运行应用程序,可以看到应用程序菜单已经是我们所创建的了。

但是各菜单项都处于灰色不可用状态,这是因为我们还没有为各菜单项连接处理函数。

下面我们将用ClassWizard(类向导)为菜单项来连接处理函数。

1.1.1使用ClassWizard为菜单项连接处理函数

在VisualStudioC++6.0开发环境中,选中“View”菜单下的“ClassWizard”菜单项,或者按“Ctrl+W”的快捷键组合,将出现“MFCClassWizard”(MFC类向导)对话框。

如图1-46所示。

MFC类向导的功能很多,在进行MFC编程的时候经常会用到。

我们现在只介绍MFC类向导中我们将用到的功能,其它功能等到后面用到的时候再详细介绍。

MFC类向导对话框有“MessageMaps”等五个分页,其中“MessageMaps”分页是我们最常用到的。

为菜单项连接处理函数也是在这一分页中。

在MFC类向导对话框的“MessageMaps”分页中,“Project:

”下拉框中是当前正在编辑的项目名称,图1-46中显示的就是我们现在所编辑的项目的名称DrawTest;“Classname:

”下拉框中列出了当前项目中所包含的类,图1-46中当前正在显示的是CMainFrame类,我们可以通过下拉列表来选择其它类;“ObjectIDs:

”列表框中显示的是当前选择的类以及应用程序中所有的资源ID;“Messages:

”列表框中显示的是“ObjectIDs:

”列表框中所选中的类或者ID所代表的资源所支持的MFC系统消息,在图1-46中“ObjectIDs:

”列表框中选中了CMainFrame类,表示“Messages:

”列表框中显示的CMainFrame类所支持的MFC系统消息;“Memberfunctions:

”列表框中显示的是选中的类当前已有的成员函数。

我们在“Classname:

”下拉框中选择CDrawTestView类,然后在“ObjectIDs:

”列表框中选中ID_DRAW_LINETO,这是为我们刚才创建的菜单中的“LineTo”三级菜单所设置的ID。

在“ObjectIDs:

”列表框中我们可以看到所设置的所有ID。

选中ID_DRAW_LINETO后,我们会看到在“Messages:

”列表框中列出了它所支持的MFC系统消息,也就是菜单项所支持的MFC系统消息。

而在“Memberfunctions:

”列表框中列出了CDrawTestView类当前所有的成员函数。

如图1-47所示。

从图1-47中可以看到,菜单项支持两种消息:

COMMAND消息和UPDATE_COMMAND_UI消息。

COMMAND消息是鼠标单击菜单项时应用程序发出的消息,UPDATE_COMMAND_UI消息是菜单项形成或者发生改变时应用程序发出的消息。

我们是要为菜单项连接用户点击时的处理函数,所以选择COMMAND消息。

此时,右侧的“AddFunction”按钮变为可用,我们可以点击此按钮,或者双击COMMAND消息,都可以打开“AddMemberFunction”(添加成员函数)对话框,如图1-48所示。

在对话框的“Memberfunctionname:

”输入框中,显示的是MFC类向导为新的成员函数所自动生成的一个函数名,我们可以修改函数名,但是建议还是采用生成的函数名称。

在对话框下端,列出了这个处理函数是针对ID为ID_DRAW_LINETO资源的COMMAND消息所创建的处理函数。

点击OK按钮,则此成员函数就被加入到CDrawTestView类中。

如图1-49所示。

前面选择CDrawTestView类,就是为了将菜单项的处理函数加入到该类中,当然这个处理函数也可以加入到其它类中,但是CDrawTestView类是视图类,用于进行图形绘制的处理函数最好还是放在该类中。

在“Memberfunctions:

”列表框中我们可以看到刚才添加的成员函数,并且处于选中状态,我们可以双击该成员函数,或者点击右侧“EditCode”按钮,系统会自动定位到OnDrawLineto函数处,让用户进行代码编写。

当应用程序运行时,如果用户点击“LineTo”菜单项,则应用程序框架会自动调用OnDrawLineto函数。

我们编写OnDrawLineto函数,用它来演示LineTo绘图函数,输入如下代码:

voidCDrawTestView:

:

OnDrawLineto()

{

//TODO:

Addyourcommandhandlercodehere

CClientDCdc(this);

dc.MoveTo(300,300);

dc.LineTo(400,400);

}

按照上面的方法,添加其它菜单项的处理函数,我们可以在MFC类向导中一次把所有要添加的处理函数都添加完,再对其进行编辑。

编写“Polyline”菜单项处理函数,输入如下代码:

voidCDrawTestView:

:

OnDrawPolyline()

{

//TODO:

Addyourcommandhandlercodehere

CClientDCdc(this);

POINTp[5];

p[0].x=300;p[0].y=200;

p[1].x=400;p[1].y=200;

p[2].x=400;p[2].y=300;

p[3].x=350;p[3].y=350;

p[4].x=320;p[4].y=220;

dc.Polyline(p,5);

}

编写“Arc”菜单项处理函数,输入如下代码:

voidCDrawTestView:

:

OnDrawArc()

{

//TODO:

Addyourcommandhandlercodehere

CClientDCdc(this);

dc.Arc(100,200,300,300,280,120,120,280);

}

编写“AngleArc”菜单项处理函数,输入如下代码:

voidCDrawTestView:

:

OnDrawAnglearc()

{

//TODO:

Addyourcommandhandlercodehere

CClientDCdc(this);

dc.MoveTo(450,100);

dc.AngleArc(550,200,50,90,270);

}

编写“PolyBezier”菜单项处理函数,输入如下代码:

voidCDrawTestView:

:

OnDrawPolybezier()

{

//TODO:

Addyourcommandhandlercodehere

CClientDCdc(this);

POINTp[7];

p[0].x=200;p[0].y=100;

p[1].x=200;p[1].y=200;

p[2].x=300;p[2].y=200;

p[3].x=400;p[3].y=300;

p[4].x=500;p[4].y=400;

p[5].x=300;p[5].y=400;

p[6].x=100;p[6].y=450;

dc.PolyBezier(p,7);

}

编写“Rectangle”菜单项处理函数,输入如下代码:

voidCDrawTestView:

:

OnDrawRectangle()

{

//TODO:

Addyourcommandhandlercodehere

CClientDCdc(this);

dc.Rectangle(450,100,650,250);

}

编写“RoundRect”菜单项处理函数,输入如下代码:

voidCDrawTestView:

:

OnDrawRoundrect()

{

//TODO:

Addyourcommandhandlercodehere

CClientDCdc(this);

dc.RoundRect(650,250,850,400,20,20);

}

编写“Ellipse”菜单项处理函数,输入如下代码:

voidCDrawTestView:

:

OnDrawEllipse()

{

//TODO:

Addyourcommandhandlercodehere

CClientDCdc(this);

dc.Ellipse(450,400,650,500);

}

编写“Pie”菜单项处理函数,输入如下代码:

voidCDrawTestView:

:

OnDrawPie()

{

//TODO:

Addyourcommandhandlercodehere

CClientDCdc(this);

dc.Pie(100,300,300,400,280,220,120,380);

}

编写“Chord”菜单项处理函数,输入如下代码:

voidCDrawTestView:

:

OnDrawChord()

{

//TODO:

Addyourcommandhandlercodehere

CClientDCdc(this);

dc.Chord(100,400,300,500,280,320,120,480);

}

编写“Polygon”菜单项处理函数,输入如下代码:

voidCDrawTestView:

:

OnDrawPolygon()

{

//TODO:

Addyourcommandhandlercodehere

CClientDCdc(this);

POINTp[4];

p[0].x=300;p[0].y=150;

p[1].x=350;p[1].y=1;

p[2].x=420;p[2].y=200;

p[3].x=350;p[3].y=150;

dc.Polygon(p,4);

}

那么应用程序是如何将菜单项和处理函数实际连接起来的呢?

我们可以看一下CDrawTestView类的类文件的类声明之前有一个BEGIN_MESSAGE_MAP宏,在这个宏中,应用程序完成了资源ID与其处理函数的实际连接,现在该宏内容如下:

BEGIN_MESSAGE_MAP(CDrawTestView,CView)

//{{AFX_MSG_MAP(CDrawTestView)

ON_COMMAND(ID_DRAW_LINETO,OnDrawLineto)

ON_COMMAND(ID_DRAW_POLYLINE,OnDrawPolyline)

ON_COMMAND(ID_DRAW_ARC,OnDrawArc)

ON_COMMAND(ID_DRAW_ANGLEARC,OnDrawAnglearc)

ON_COMMAND(ID_DRAW_POLYBEZIER,OnDrawPolybezier)

ON_COMMAND(ID_DRAW_RECTANGLE,OnDrawRectangle)

ON_COMMAND(ID_DRAW_ROUNDRECT,OnDrawRoundrect)

ON_COMMAND(ID_DRAW_ELLIPSE,OnDrawEllipse)

ON_COMMAND(ID_DRAW_PIE,OnDrawPie)

ON_COMMAND(ID_DRAW_CHORD,OnDrawChord)

ON_COMMAND(ID_DRAW_POLYGON,OnDrawPolygon)

//}}AFX_MSG_MAP

//Standardprintingcommands

ON_COMMAND(ID_FILE_PRINT,CView:

:

OnFilePrint)

ON_COMMAND(ID_FILE_PRINT_DIRECT,CView:

:

OnFilePrint)

ON_COMMAND(ID_FILE_PRINT_PREVIEW,CView:

:

OnFilePrintPreview)

END_MESSAGE_MAP()

可见,正是在这个宏中完成了菜单项和处理函数的实际连接。

这部分代码是由系统自动添加的,用户并不需要自己编写,用户只需要知道实际连接在代码上是如何实现的就可以了。

同时,我们可以看一下这些处理函数在头文件中的声明。

打开CDrawTestView类的头文件,可以看到处理函数的声明如下:

protected:

//{{AFX_MSG(CDrawTestView)

afx_msgvoidOnDrawLineto();

afx_msgvoidOnDrawPolyline();

afx_msgvoidOnDrawArc();

afx_msgvoidOnDrawAnglearc();

afx_msgvoidOnDrawPolybezier();

afx_msgvoidOnDrawRectangle();

afx_msgvoidOnDrawRoundrect();

afx_msgvoidOnDrawEllipse();

afx_msgvoidOnDrawPie();

afx_msgvoidOnDrawChord();

afx_msgvoidOnDrawPolygon();

//}}AFX_MSG

同样,这些声明也是由系统自动添加的,不需要用户自己编写。

运行应用程序,我们可以通过选择菜单项来看对应的绘图函数的执行结果。

此时,如果把应用程序窗口最小化,然后再恢复该窗口,我们就会看到原来在视图区所绘制的图形已经没有了,这是因为我们现在所编写的绘图代码是OnDraw函数所调用不到的。

因此在窗口重画的时候,并不能把原来已有的图形重新绘制出来。

为了能使绘制的图形在视图重画的时候能够正确显示,就需要将图形的相关数据先存储起来,然后在OnDraw函数中将这些图形重新绘制一遍。

具体的做法我们将在下一章中详细介绍。

1.1.2主动视图重画

前面我们介绍了OnDraw函数是在应用程序窗口需要重新绘制的时候,由应用程序框架来自动调用的。

有时候,我们需要通过程序代码来引起视图重画,即引起OnDraw函数的调用。

MFC提供了相应的函数,使我们可以主动引发视图重画。

主动视图重画可以分为两种类型:

全部重画和局部重画。

1

1.1

1.2

1.3

1.4

1.5

1.5.1

1.5.2

1.5.3

1.5.3.1全部重画

全部重画可以通过调用窗口类的Invalidate函数来实现,其函数声明如下:

voidCWnd:

:

Invalidate(BOOLbErase=TRUE);

参数bErase为TRUE时,应用程序在调用OnDraw函数之前会先清空视图区;如果为FALSE,则不清空。

Invalidate函数在调用的时候可以不传入参数,此时默认bErase为TRUE。

这里需要注意的是,调用Invalidate函数后,应用程序框架并不是马上调用OnDraw函数进行重画,而是等到调用Invalidate函数的函数执行完毕之后,才会调用OnDraw函数,所以调用Invalidate函数通常写在函数执行的最后一句。

1.5.3.2局部重画

全部重画是针对整个视图区进行重画,而有时候,绘图工作只是在视图区中的一个局部区域进行的,此时进行全部重画,会造成一些不必要的资源浪费,有时还会使屏幕产生闪烁的现象。

针对这种问题,可以采用局部重画的方法——使指定的区域无效,而不是全部视图区都失效。

局部重画通过调用InvalidateRect函数或者InvalidateRgn函数来实现。

◆InvalidateRect的函数声明如下:

voidCWnd:

:

InvalidateRect(LPCRECTlpRect,BOOLbErase=TRUE);

其中参数lpRect指定了一个矩形区域,如果该参数传入NULL的话,代表的是整个视图区。

参数bErase的含义与Invalidate函数中的相同,只是此处清空

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2