按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
在本章的最后;我们不妨来看看怎样在程序中实现右击鼠标时出现的
上下文菜单;与前面我们所遇到的其他弹出式菜单在CmainFrame中实
现不同;上下文菜单要在类CmenuView中实现。从本质上来说,实现上
下文菜单时发送的消息与标准的菜单消息并没有什么两样,它们都发
送ON_MAND消息。但是,由于上下文菜单的特殊性,我们首先必须
保证我们能接收到这样的消息。同时,由于上下文菜单中没有顶层菜
单,我们对它们的跟踪有一定的特殊性。我们采用CMenu类的一个成
员函数TrackPopupMenu来实现。该函数的原型为:
BOOL TrackPopupMenu(UINT nFlags; int x; int y; CWnd* pWnd; LPCRECT lpRect =
NULL )
该函数中,参数nFlags指明屏幕位置与鼠标位置风格,x;y为一依赖
于前面所指定风格的上下文菜单的屏幕位置坐标,pWnd为一指向拥有
该菜单的窗口指针,而lpRect指明用户不会丢失掉上下文菜单的矩形
域。参数nFlags可以取以下值:
屏幕位置风格:TPM_CENTERALIGN;TPM_LEFTALIGN,TPM_RIGHTALIGN
…………………………………………………………Page 220……………………………………………………………
鼠标位置风格:TPM_LEFTBUTTON,TPM_RIGHTBUTTON
至于说它们的取值是可以互相取 “或”的,而它们的实际效果,我们
希望读者通过实践具体看看。下面的程序段摘自例程中文件
CMenuView。cpp中:
void CMenuView::OnRButtonDown(UINT nFlags; CPoint point)
{
// TODO: Add your message handler code here and/or call default
CMenu ContextMenu;
if(!ContextMenu。LoadMenu(IDR_CONTEXTMENU))
AfxThrowResourceException();
CMenu *pPopupMenu=ContextMenu。GetSubMenu(0);
ASSERT(pPopupMenu!=NULL);
ClientToScreen(&point);
pPopupMenu…》TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON;
point。x;point。y;AfxGetMainWnd());
CView::OnRButtonDown(nFlags; point);
}
下面我们对这一段代码作简要分析:
程序中先装入该菜单 (使用LoadMenu装入),接下来由于上下文菜单
的定位使用屏幕坐标,所以使用了一个CWnd类的成员函数
ClientToScreen,然后使用了TrackPopupMenu将菜单以上下文方式显
示,最后,程序调用CView类的通用代码处理一些平常信息。
l 注意:
l 由于该函数在类CMenuView中实现,在使用ClassWizard时务请注
意基类的选择。如 图5。17所示 (如果错选 了CMaimFrame类,程序
最后所调用的处理例程为CWnd类的处理函数,上下文菜单的显示
就成了问题)。
…………………………………………………………Page 221……………………………………………………………
图5。 17 选择上下文菜单实现的基类
在本章的最后,我们给出一部分关键性代码,其中手工加入的部分以
具有底纹的文字给出 (基于版面方面的考虑,我们对一些重复性的代
码略去了)。
l 注意:
l 由于菜单项的选择标记及使能实现较简单,此处省去了该部分。
但实现时需调用消息响应WM_INITMENU。
l 为了节省篇幅,在程序中我们没有在窗口变化后进行重绘,这部
分的详细内容请参见GDI绘图一节。
// MainFrm。cpp : 类CMainFrame 的实现
//
#include 〃stdafx。h〃
// 。。。
IMPLEMENT_DYNCREATE(CMainFrame; CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame; CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_MAND(ID_VIEW_NORMALMENU; OnViewNormalmenu)
…………………………………………………………Page 222……………………………………………………………
ON_MAND(ID_DRAW_LINE; OnDrawLine)
ON_MAND(ID_DRAW_CIRCLE; OnDrawCircle)
ON_MAND(ID_DRAW_RECTANGLE; OnDrawRectangle)
ON_MAND(ID_DYNCMODIFY_INSERT; OnDyncmodifyInsert)
ON_MAND(ID_HELP_INSERT; OnHelpInsert)
ON_MAND(ID_APP_EXIT; OnAppExit)
ON_MAND(ID_DYNCMODIFY_APPEND; OnDyncmodifyAppend)
ON_MAND(ID_HELP_APPEND; OnHelpAppend)
ON_MAND(ID_DYNCMODIFY_DELETE; OnDyncmodifyDelete)
ON_MAND(ID_DYNCMODIFY_MODIFY; OnDyncmodifyModify)
ON_MAND(ID_DYNCMODIFY_MODIFYSYSTEMMENU; OnDyncmodifyModifysystemmenu)
ON_MAND(ID_DYNCMODIFY_RESET; OnDyncmodifyReset)
ON_MAND(ID_CHANGE; OnChange)
ON_WM_SYSMAND()
//此处为系统菜单消息响应声明,改变系统菜单后的消息处理必须声明该响应
ON_MAND(ID_FILE_NEW; OnFileNew)
ON_MAND(ID_VIEW_LONGMENU; OnViewLongmenu)
//}}AFX_MSG_MAP
END_MESSAGE_MAP( )
//以上函数映射部分仅供读者选用菜单ID时参考。但是,
//将这部分代码与实现系统菜单时的消息映射作一对比是有意义的。
static UINT indicators'' =
{
ID_SEPARATOR; // status line indicator
ID_INDICATOR_CAPS;
ID_INDICATOR_NUM;
…………………………………………………………Page 223……………………………………………………………
ID_INDICATOR_SCRL;
};
//此处为状态栏上的分配,具体我们在后面会有提及。
/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction
CMainFrame::CMainFrame()
{
// TODO: add member initialization code here
bInsert=TRUE;//防止菜单被重复插入的控制变量
bAppend=TRUE;//防止菜单被重复加入的控制变量
bDelete=TRUE;//防止菜单被重复删除的控制变量
bModify=TRUE;//防止菜单被重复修改的控制变量
bBitmap=FALSE;//标识是否使用了图符菜单
}
//在CMainFrame类的构造函数中,我们加入了一部分支持菜单动态
//处理控制的BOOL型变量,它们的定义在函数CMainFrame。h中
// 。。。
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
// 。。。
// 提示: 以下部分代码用于控制工具条提示及工具条本身实现,
//如果不需要可以将下面两行代码移去
m_wndToolBar。SetBarStyle(m_wndToolBar。GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
//提示:下面三行代码控制工具条是否可以移动,如果你并不
//希望工具条可以在屏幕内移动,可以删去它们。
…………………………………………………………Page 224……………………………………………………………
m_wndToolBar。EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
hLongMenu。LoadMenu(IDR_MAINFRAME1);
hNormalMenu。LoadMenu(IDR_MAINFRAME0);
hLine。LoadBitmap(IDB_LINE);
hCircle。LoadBitmap(IDB_CIRCLE);
hRectangle。LoadBitmap(IDB_RECTANGLE);
hText。LoadBitmap(IDB_TEXT);
//以上几行代码装入资源 (菜单,位图),但由于上下文菜单
//处理机制不一样,其资源并不在此处装入。
ret