C语言实例教程(PDF格式)-第28部分
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
的第一部分为 菜单标题,其最后一部分则为标识该菜单项的
ID号。需要注意的是,具有子菜单的弹出式菜单项是没有标
识的ID号的。
l 我们程序的最初的菜单;并不包含程序执行后结果的一些菜单;最
初的菜单中仅仅包含前四幅图中的菜单。
l IDR_MAINFRAME0 MENU PRELOAD DISCARDABLE
l BEGIN
l POPUP 〃&File〃
l BEGIN
l MENUITEM 〃&NewtCtrl+N〃; ID_FILE_NEW
l MENUITEM 〃&Open。。。tCtrl+O〃; ID_FILE_OPEN
l MENUITEM 〃&SavetCtrl+S〃; ID_FILE_SAVE
l MENUITEM 〃Save &As。。。〃; ID_FILE_SAVE_AS
l MENUITEM SEPARATOR
l MENUITEM 〃&Print。。。tCtrl+P〃; ID_FILE_PRINT
l MENUITEM 〃Print Pre&view〃; ID_FILE_PRINT_PREVIEW
l MENUITEM 〃P&rint Setup。。。〃; ID_FILE_PRINT_SETUP
l MENUITEM SEPARATOR
l MENUITEM 〃Recent File〃; ID_FILE_MRU_FILE1; GRAYED
l MENUITEM SEPARATOR
…………………………………………………………Page 209……………………………………………………………
l MENUITEM 〃E&xit〃; ID_APP_EXIT
l END
l POPUP 〃&Edit〃
l BEGIN
l MENUITEM 〃&UndotCtrl+Z〃; ID_EDIT_UNDO
l MENUITEM SEPARATOR
l MENUITEM 〃Cu&ttCtrl+X〃; ID_EDIT_CUT
l MENUITEM 〃&CopytCtrl+C〃; ID_EDIT_COPY
l MENUITEM 〃&PastetCtrl+V〃; ID_EDIT_PASTE
l END
l POPUP 〃&View〃
l BEGIN
l MENUITEM 〃&Toolbar〃; ID_VIEW_TOOLBAR
l MENUITEM 〃&Status Bar〃; ID_VIEW_STATUS_BAR
l MENUITEM 〃&Long menu〃; ID_VIEW_LONGMENU
l END
l POPUP 〃&Draw〃
l BEGIN
l MENUITEM 〃&Line〃; ID_DRAW_LINE
l MENUITEM 〃&Circle〃; ID_DRAW_CIRCLE
l MENUITEM 〃&Rectangle〃; ID_DRAW_RECTANGLE
l MENUITEM 〃&Bitmap〃; ID_CHANGE
l END
…………………………………………………………Page 210……………………………………………………………
l POPUP 〃&Help〃
l BEGIN
l MENUITEM 〃&About Menu。。。〃; ID_APP_ABOUT
l END
l END
l
l IDR_MAINFRAME1 MENU DISCARDABLE
l BEGIN
l POPUP 〃&File〃
l BEGIN
l MENUITEM 〃&NewtCtrl+N〃; ID_FILE_NEW
l MENUITEM 〃&Open。。。tCtrl+O〃; ID_FILE_OPEN
l MENUITEM 〃&SavetCtrl+S〃; ID_FILE_SAVE
l MENUITEM 〃Save &As。。。〃; ID_FILE_SAVE_AS
l MENUITEM SEPARATOR
l MENUITEM 〃&Print。。。tCtrl+P〃; ID_FILE_PRINT
l MENUITEM 〃Print Pre&view〃; ID_FILE_PRINT_PREVIEW
l MENUITEM 〃P&rint Setup。。。〃; ID_FILE_PRINT_SETUP
l MENUITEM SEPARATOR
l MENUITEM 〃Recent File〃; ID_FILE_MRU_FILE1; GRAYED
l MENUITEM SEPARATOR
l MENUITEM 〃E&xit〃; ID_APP_EXIT
l END
…………………………………………………………Page 211……………………………………………………………
l POPUP 〃&View〃
l BEGIN
l MENUITEM 〃&Toolbar〃; ID_VIEW_TOOLBAR
l MENUITEM 〃&Status Bar〃; ID_VIEW_STATUS_BAR
l MENUITEM 〃&Normal menu〃; ID_VIEW_NORMALMENU
l END
l POPUP 〃&Dyncmodify〃
l BEGIN
l MENUITEM 〃&Insert a menuitem〃; ID_DYNCMODIFY_INSERT
l MENUITEM 〃&Delete a menuitem〃; ID_DYNCMODIFY_DELETE
l MENUITEM 〃&Append a menuitem〃; ID_DYNCMODIFY_APPEND
l MENUITEM 〃&Modify help〃; ID_DYNCMODIFY_MODIFY
l MENUITEM 〃M&odify system menu〃; ID_DYNCMODIFY_MODIFYSYSTEMMENU
l MENUITEM 〃&Reset system menu〃; ID_DYNCMODIFY_RESET
l END
l POPUP 〃&Help〃
l BEGIN
l MENUITEM 〃&About Menu。。。〃; ID_APP_ABOUT
l END
l END
l
l IDR_CONTEXTMENU MENU DISCARDABLE
l BEGIN
…………………………………………………………Page 212……………………………………………………………
l POPUP 〃dummy〃
l BEGIN
l MENUITEM 〃&Line〃; ID_DRAW_LINE
l MENUITEM 〃&Circle〃; ID_DRAW_CIRCLE
l MENUITEM 〃&Rectangle〃; ID_DRAW_RECTANGLE
l END
l END
图5。 11 上下文菜单的一个运行画面
为了建立弹出式菜单,在上述代码中,我们发现还有一个菜单
IDR_CONTEXTMENU没有提及。它在该文件中与其它菜单的表现形式是
一样的。下图为弹出式菜单的一个运行画面。
下面我们看看怎样改变菜单项的缺省名称。如图5。12所示,在
WorkSpace中于IDR-MAINFRAME上右击鼠标,在弹出式菜单中选择属
性项 (Property),在接下来的属性设置对话框中在ID设置区输入后
者从下拉列表选择所需的菜单ID号即可。依此处理其它各菜单项。
l 注意:
l 菜单项ID号的设置务请同我们给 出的保持一致,由于ID号是辨识
菜单消息的唯一手段,此处的差别将会导致你在下面的学习过程
中将不得不跟我们给 出的代码有一些差异。
…………………………………………………………Page 213……………………………………………………………
图5。 12 改变菜单项ID值
现在,试着运行一下我们的程序,会发现它并没有能比最初的
AppWizard建立的标准程序多做些什么。这是必然的,毕竟,我们还
没有编写一行让它动起来的代码吗 !不过不要紧,我们接下来所要做
的,就是这项工作。(不用担心IDR_MAINFRAME0对IDR_MAINFRAME的
替代会有什么不良结果,实际上,ClassWizard监测到这些,并已在
程序代码中作了相应的变动以反应这一变化。)
首先,由于对菜单的动态改变在菜单IDR_MAINFRAME1的菜单项中实
现,因此,我们所要做的第一步工作就是实现菜单IDR_MAINFRAME1对
菜单IDR_MAINFRAME0的动态替换。这可以用CWnd类的一个成员函数
SetMenu实现。函数SetMenu的原型为:
BOOL SetMenu(CMenu * pMenu);
其中pMenu为一指向欲替换原有菜单的一CMenu类的对象的指针,函数
的返回值仅仅在菜单没有发生改变时为0。
l 注意:
l 如果你以空值NULL作为指向CMenu的指针,那你的程序的菜单就算
消失了。除非在程序中以适当方式告诉用户重新得到菜单的方
法,用户很难再得到菜单了。不过,在一些情形下,实现菜单的
消隐/显示可以实现对屏幕显示空间的有效管理。
尽管通过第四章的学习,你已经掌握了一些在程序中添加消息响应函
数的方法,但基于文档/视结构的成员函数的添加还是有自己的很大
程度上的不同。在我们已经生成的程序中,添加对菜单消息的响应的
…………………………………………………………Page 214……………………………………………………………
函数是有一些自己的特殊性的。下面我们结合图示顺序讲解。
1。 在菜单项上或源代码编辑区中右击鼠标,或选择
View/ClassWizard…菜单项,打开ClassWizard对话框。
2。 在Class name:选项中,确认为CMainFrame,在Object IDs:中选
择ID_VIEW_LONGMENU;在Message:选项中选择MAND,如图5。13。
图5。 13 为菜单项增加消息响应函数
图5。 14 选择响应函数名称
3。 单击Add Class…为响应函数命名 (如图5。14所示),一般说,接
受系统提供的缺省名就足可以了。
4。 单击OK后进入源代码编辑区进行编辑。
如下所示,为我们为函数OnViewLongmenu所加的代码:
void CMainFrame::OnViewLongmenu()
{
// TODO: Add your mand handler code here
SetMenu(&hLongMenu);
…………………………………………………………Page 215……………………………………………………………
}
理解这段代码并不困难,但参数hLongMenu从何而来?这是我们在程序
中创建的一个标识菜单IDR_MAINFRAME1的CMenu类的一个对象。在文
件MainFrm。cpp的下示函数中我们对其进行了初始化 (这两处代码均是
手工加入的):
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
// 。。。
hLongMenu。LoadMenu(IDR_MAINFRAME1);
// 。。。
}
而其定义在头文件MainFrm。h中:
class CMainFrame : public CFrameWnd
{
// 。。。
CMenu hLongMenu;
// 。。。
}
对View菜单的前三个菜单项的响应涉及到GDI绘图的一些知识,读者
如果暂时弄不清楚,可以留待看过相应章节后再回头来理解。下面我
们看一看对菜单的动态操作。
…………………………………………………………Page 216……………………………………………………………
图5。 15 在程序中增加位图资源
在前面的第四章的那个例程中,我们对这类实现作了些简要的介绍,
在这里,我们结合本章的程序作一些更深入的介绍。
首先,对菜单的动态操作的几个函数,其最后一个参数都可以用一个
位图指针替代。本章例程中Draw菜单下的图符菜单即由此实现。当
然,要使用位图作为菜单项,首先必须创建位图资源。
在Visual C++菜单中选择Insert/Resource…;再在弹出的对话框中选
择Bitmap,如图5。15所示。
如果有现成的位图,可以选择Import…,当然,在很多情况下,我们
可以选New直接在资源编辑器中对它们进行创建、编辑。位图编辑器
的使用很容易掌握,在此不再赘述。图形可以参考前面的插图。下面
的代码摘自Menu。rc,以便读者在指定位图属性时作参考。
IDB_LINE BITMAP DISCARDABLE 〃resline。bmp〃
IDB_CIRCLE BITMAP DISCARDABLE 〃resbitmap1。bmp〃
IDB_RECTANGLE BITMAP DISCARDABLE 〃resrectangl。bmp〃
IDB_TEXT BITMAP DISCARDABLE 〃resbmp00001。bmp〃
同时,当然也应该注意映射的关系。只要与欲执行该功能的字符菜单
项的ID号一致,那么,它们所实现的功能就是一样的。下面的几行代
码摘自MainFrm。cpp
void CMainFrame::OnChange()
{
// TODO: Add your mand handler code here
if(!bBitmap)
…………………………………………………………Page 217……………………………………………………………
{
bBitmap=TRUE;
CMenu *pMenu=GetMenu();
CMenu *pSubMenu=pMenu…》GetSubMenu(3);
pSubMenu…》ModifyMenu(ID_DRAW_LINE;MF_BYMAND;ID_DRAW_LINE;&hLine);
pSubMenu…》ModifyMenu(ID_DRAW_CIRCLE;MF_BYMAND;ID_DRAW_CIRCLE;&hCircle);
pSubMenu…》ModifyMenu(ID_DRAW_RECTANGLE;
MF_BYMAND;ID_DRAW_RECTANGLE;&hRectangle);
pSubMenu…》ModifyMenu(ID_CHANGE;MF_BYMAND;ID_CHANGE;&hText);
}
else
{
bBitmap=FALSE;
CMenu *pMenu=GetMenu();
CMenu *pSubMenu=pMenu…》GetSubMenu(3);
pSubMenu…》ModifyMenu(ID_DRAW_LINE;MF_BYMAND;ID_DRAW_LINE;〃&Line〃);
pSubMenu…》ModifyMenu(ID_DRAW_CIRCLE;MF_BYMAND;ID_DRAW_CIRCLE;〃&Circle〃);
pSubMenu…》ModifyMenu(ID_DRAW_RECTANGLE;
MF_BYMAND;ID_DRAW_RECTANGLE;〃&Rectangle〃);
pSubMenu…》ModifyMenu(ID_CHANGE;MF_BYMAND;ID_CHANGE;〃&Bitmap〃);
}
}
而下面这段程序完成了位图资源的装入与初始化:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
// 。。。
…………………………………………………………Page 218……………………………………………………………
hLine。LoadBitmap(IDB_LINE);
hCircle。LoadBitmap(I