• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

把选单加到工具栏的简便方法

发布: 2007-7-14 21:11 | 作者: 佚名    | 来源: 网络转载     | 查看: 27次 | 进入软件测试论坛讨论

领测软件测试网 薛瑛

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宏将按钮事件的消息ID映射到相应的OnMenu(uID)函数上。再利用OnMenu(uID)函数来进行选单控制。
void CMainFrame::OnMenu(UINT nID)
{
CMenu m_mnuTopMenu;
CRect rWindow,rButton;
m_mnuTopMenu.LoadMenu(IDR_MAINFRAME);
UINT iPos;
for (iPos = 0; iPos < m_mnuTopMenu.GetMenuItemCount(); iPos++)
{
if (iPos == nID-1)
{
m_wndMenuBar.GetWindowRect(&&rWindow);
m_wndMenuBar.GetItemRect( iPos, &&rButton);
rWindow.top += rButton.bottom;
rWindow.left += rButton.left;
m_wndMenuBar.GetToolBarCtrl().SetState(iPos+1,TBSTATE_PRESSED|TBSTATE_ENABLED);
// show popup menu
m_mnuTopMenu.GetSubMenu(iPos)-> TrackPopupMenu(
TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_VERTICAL,
rWindow.left,rWindow.top,this);
m_wndMenuBar.GetToolBarCtrl().SetState(iPos+1,TBSTATE_ENABLED);
break;
}
}
}

OnMenu()函数用按钮的ID号作为参数,首先判断发出命令的是哪一个按钮,计算出响应的选单项及显示位置,用CtoolBarCtrl类的SetState()设置按钮的状态,并调用Cmenu类的TrackPopupMenu()显示选单项。最后我们加入实现选单栏的任意拖放的程序代码:

m_wndMenuBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&&m_wndMenuBar);

本文所用方法简单、实用,用户可定制OnMenu()函数以实现更多的功能。

文章来源于领测软件测试网 https://www.ltesting.net/


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备2023014753号-2
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网