薛瑛
Windows以其良好的用户界面深受广大用户的喜爱,尤其是其IE4的推出增加了新颖的控制。选单栏就是其中一项,它结合了以往的选单和工具栏的特性,如果能将选单放置在工具栏上,既能响应选单消息又能随意拖动,那该多好!
由于在MFC类库中并没有提供CMenuBar类,用户不能像制作工具条那样定制选单栏,这给不少的开发人员带来了不便。本文提供了一种简单快速的方法很好地实现了选单栏的功能。
按钮是工具条的组成元素,它能够响应用户的点击,相应地进行处理。我们就利用这一特性来实现选单控制。
程序的开发环境是VC++ 6.0,Windows 98/2000/NT。
通过工具栏中的按钮可以直接调出打印界面
新建工程
首先在Visual Studio中选择NEW生成新的工程,我们选择单文档界面SDI。在资源编辑器中生成自己的选单,ID号为IDR_TOOL_MENU。接下来生成自己的工具栏。在主界面窗口MainFrame.h中加入工具栏定义:
class CMainFrame : public CFrameWnd
{
Protected:
CToolBar m_wndMenuBar;
}
在MainFrame.cpp的类CmainFrame::OnCreate()函数中加入生成代码:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndMenuBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD
WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS |
CBRS_FLYBY| CBRS_SIZE_DYNAMIC ))
{
TRACE0("Failed to create Menubar\n");
return -1; // fail to create
}
m_wndMenuBar.SetSizes(CSize(30,20),CSize(1,1));//设置工具栏按钮的大小
……
添加按钮及响应
程序 工具栏生成后,下一步我们就要在工具栏中加入按钮。按钮的数量是根据选单项的多少来决定的。
TBBUTTON button;
CString strItem;
CMenu mTopMenu;
mTopMenu.LoadMenu(IDR_TOOL_MENU);
UINT iPos;
for (iPos = 0; iPos < mTopMenu.GetMenuItemCount(); iPos++)
{ mTopMenu.GetMenuString(iPos, strItem, MF_BYPOSITION);
button.idCommand = iPos+1;
button.iBitmap = -1;
button.fsState = 0;
button.fsStyle = TBSTYLE_BUTTON;
button.iString = -1;
m_wndMenuBar.GetToolBarCtrl().InsertButton(iPos,&&button);
m_wndMenuBar.SetButtonText(iPos,strItem);
}
这里,我们用到了结构TBBUTTON,它定义了按钮的一些特性。其中最重要的是idCommand属性,它定义了按钮的ID命令号,用于在按钮按下时触发ON_ONCOMMAND 命令,我们将其定义成选单项的索引号(Index),fsStyle为按钮的风格,fsState为按钮的状态。通过调用GetToolBarCtrl获得ToolBar的Control类。此类提供了工具栏的通用控制。利用CtoolBarCtrl类可将按钮加入到工具栏中,用SetButtonText可设置按钮的显示文本。下面我们将编写处理按钮命令,以实现我们的选单控制。首先定义消息响应函数OnMenu(),代码如下:
MainFrame.h
CmainFrame::Public CframeWnd
{
protected:
//{{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
afx_msg void OnMenu(UINT nID);
DECLARE_MESSAGE_MAP()
}
在MainFrame.cpp 中加入如下代码:
#define MAX_MENU_SUBMENUS 20
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code !
ON_WM_CREATE()
//}}AFX_MSG_MAP
ON_COMMAND_RANGE(1,MAX_MENU_SUBMENUS, OnMenu)
END_MESSAGE_MAP()
其中,ON_COMMAND_RANGE宏将按