按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
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(IDB_CIRCLE);
hRectangle。LoadBitmap(IDB_RECTANGLE);
hText。LoadBitmap(IDB_TEXT);
// 。。。
}
工作间,此时,系统检测到资源已经在系统外部发生变化,询问是否
重组数据库,选择是,我们所需要的就已经全部准备完毕。下面给出
这一变化前后文件Menu。rc的变化情况。
//改变以前:
POPUP 〃&Help〃
BEGIN
MENUITEM 〃&About Menu。。。〃; ID_APP_ABOUT
MENUITEM 〃&I ’m Menu inserted〃; ID_HELP_INSERT
//上面这行代码我们在实现了消息映射后将将其删除
END
//改变以后:
POPUP 〃&Help〃
BEGIN
MENUITEM 〃&About Menu。。。〃; ID_APP_ABOUT
END
通过以上的比较我们不难发现,使用第二种方式进行修改是比较方便
的。
图5。 16 系统菜单改变后的任务条
…………………………………………………………Page 219……………………………………………………………
下面我们讲一下有关系统菜单的消息响应问题。如图5。16,在我们改
变系统菜单后,当在任务栏右单击鼠标时,弹出的系统菜单具有了与
原来不同的形式。
顺便提一下,如果我们不希望用户在程序外部直接退出程序,改变系
统菜单就是这个方法的一个途径。(如果将系统菜单设为NULL,用户
就只有进入应用程序进行选择了。当然,除非这是必要的,否则,不
要强迫用户改变他们的操作习惯。)
首先,我们必须取得系统菜单,这可以通过调用CWnd类的一个成员函
数GetSystemMenu)达到。此函数的原型为:
CMenu *GetSystemMenu(BOOL bRevert) const;
在以TRUE作为bRevert的值进行调用时,恢复原系统菜单设置。在更
多的情况下,我们以FALSE进行调用,此时我们可以对系统菜单进胁
僮鳌 5牵孟⑾煊??/FONT》OnSysmand函数,而且,此消息响
应函数是系统设定的,不允许程序员另行指定。
l 注意:
l 我们可以通过系统提供的Spy++来查看系统菜单的消息发送及响应
状况。至于详细的情况,在我们随后给出了详细的解释。与该消
息相应的代码,我们将用具有底纹的文字标出。
在本章的最后;我们不妨来看看怎样在程序中实现右击鼠标时出现的
上下文菜单;与前面我们所遇到的其他弹出式菜单在CmainFrame中实
现不同;上下文菜�