Outlook式样界面菜单和页面控制

本文将介绍两个可复用的C++类:CXTOutlookBar 和 CXTPagerCtrl,用它们可以实现Outlook风格的用户界面,这两个类出自Codejock软件公司,是其产品Xtreme Toolkit的一部分。根据该公司的许可条款,任何人都可以不受限制地免费使用这两个类的源代码。

 介绍 

CXTOutlookBar类派生于ListBox,主要实现 Outlook 界面式样控制。CXTPagerCtrl类用于容纳和滚动CXTOutlookBar窗口,这个类包装了与Windows窗口管理有关的(CWnd)API。两个类的使用都很简单,用法与标准的MFC类库一样,没有什么特别要求。

这个程序的主框架是两个切分的视图:左边的视图为 COutbarView,它派生于CView,包含Outlook式样控制机制和窗口管理;右边的视图为应用程序向导生成的视类,你在应用程序向导中可以自己规定这个类从哪个基类派生,例子程序是从CListView派生的。如果想在自己的程序中使用Outlook式样的控制,只要在包含Outlook式样的视类(如本文例子程序的COutbarView)中声明实例即可,例如:

    // 属性
protected:
CXTOutlookBar   m_wndOutlookBar;
CXTPagerCtrl    m_wndPager;      

然后在视类的WM_CREATE/OnCreate消息处理例程中创建窗口控制和Outlook菜单。此时还要添加Outlook菜单项并对它们进行初始化,并设置好按钮的尺寸,创建子窗口:

int COutbarView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;

// 创建页窗口
if (!m_wndPager.Create(WS_CHILD|WS_VISIBLE|PGS_VERT,
CRect(0,0,0,0), this, IDC_PAGER_CTRL ))
{
TRACE0("Failed to create CPagerCtrl...\n");
return -1;
}

// 以m_wndPager作为父窗口创建 Outlook 式样控制
if (!m_wndOutlookBar.Create( WS_CHILD | WS_VISIBLE | WS_TABSTOP,
CRect(0,0,0,0), &m_wndPager, IDC_OUTBAR ))
{
TRACE0("Failed to create COutlookBar...\n");
return -1;
}

// 设置接受消息的 CWnd 对象
m_wndOutlookBar.SetOwner(this);
m_wndOutlookBar.SetColors(RGB(0xff,0xff,0xff), RGB(0x3a,0x6e,0xa5));

// 添加 Outlook 控制菜单项
m_wndOutlookBar.AddMenuItem(IDI_ICON_LOGO,     _T("我的VC知识库") ),
m_wndOutlookBar.AddMenuItem(IDI_ICON_NOTES,    _T("技术论坛")     ),
m_wndOutlookBar.AddMenuItem(IDI_ICON_JOURNAL,  _T("在线杂志")     ),
m_wndOutlookBar.AddMenuItem(IDI_ICON_HLIGHT,   _T("精华区")       ),
m_wndOutlookBar.AddMenuItem(IDI_ICON_SOURCE,   _T("源代码")       ),
m_wndOutlookBar.AddMenuItem(IDI_ICON_COOLLIB,  _T("酷库")         ),
m_wndOutlookBar.AddMenuItem(IDI_ICON_VCKBASE,  _T("VCKBASE Today")),
m_wndOutlookBar.AddMenuItem(IDI_ICON_PUBLIC,   _T("开发联盟")     ),
m_wndOutlookBar.AddMenuItem(IDI_ICON_CONTACTS, _T("VC知识库")     ),
m_wndOutlookBar.AddMenuItem(IDI_ICON_DELETED,  _T("垃圾箱")),

// 在指定的索引处插入菜单项
m_wndOutlookBar.InsertMenuItem(0, IDI_ICON_INBOX,    _T("收件箱") ),
m_wndOutlookBar.InsertMenuItem(1, IDI_ICON_OUTBOX,   _T("发件箱") ),
m_wndOutlookBar.InsertMenuItem(2, IDI_ICON_CALENDAR, _T("日历") ),

// 设置 COutlookBar 所管理的子窗口以及按钮的尺寸(=15)
m_wndPager.SetChild(m_wndOutlookBar.GetSafeHwnd());
m_wndPager.SetButtonSize(15);

return 0;
}      

接下来我们对窗口的大小进行管理,因此要编写WM_SIZE/OnSize代码,这样将保证视图大小改变后页控制会作相应的位置调整,这一步你可以用类向导来做。

void COutbarView::OnSize(UINT nType, int cx, int cy) 
{
CView::OnSize(nType, cx, cy);

if(m_wndPager.GetSafeHwnd()) {
m_wndPager.MoveWindow(0,0,cx,cy);
}
}      

最后,我们的任务是添加针对页控制的PGN_SCROLL和PGN_CALCSIZE消息处理代码。它告诉我们何时有页滚动并允许设置Outlook菜单窗口的可滚动尺寸。除了PGN_消息处理之外,我们还需要添加XTWM_OUTBAR_NOTIFY消息处理。它将通知我们何时用户点击了Outlook菜单项。为此在COutbarView类的实现文件中(.cpp)添加下面的消息映射:

BEGIN_MESSAGE_MAP(COutbarView, CView)
//{{AFX_MSG_MAP(COutbarView)
...
//}}AFX_MSG_MAP
ON_MESSAGE(XTWM_OUTBAR_NOTIFY,  OnOutbarNotify)
ON_NOTIFY(PGN_SCROLL, IDC_PAGER_CTRL, OnPagerScroll)
ON_NOTIFY(PGN_CALCSIZE, IDC_PAGER_CTRL, OnPagerCalcSize)
END_MESSAGE_MAP()      

同时在实现文件中添加下面的成员函数:

BOOL COutbarView::OnPagerCalcSize(NMPGCALCSIZE* pNMPGCalcSize, LRESULT* pResult)
{
switch(pNMPGCalcSize->dwFlag)
{
case PGF_CALCWIDTH:
break;

case PGF_CALCHEIGHT:
pNMPGCalcSize->iHeight = m_wndOutlookBar.GetCount()
*(::GetSystemMetrics(SM_CYICON)*2);
break;
}

*pResult = 0;
return TRUE;
}

BOOL COutbarView::OnPagerScroll(NMPGSCROLL* /*pNMPGScroll*/, LRESULT* pResult)
{
*pResult = 0;
return TRUE;
}

void COutbarView::OnOutbarNotify(UINT lParam, LONG wParam)
{
switch( wParam ) // 控制 id.
{
case IDC_OUTBAR:
{
// 获得菜单项
XT_CONTENT_ITEM* pContentItems =
m_wndOutlookBar.GetMenuItem((int)lParam);
ASSERT(pContentItems);

AfxMessageBox(pContentItems->m_strText);
}
break;
}
}

在头文件中添加

// 产生消息映射函数
protected:
//{{AFX_MSG(COutbarView)
...
//}}AFX_MSG
afx_msg BOOL OnPagerScroll(NMPGSCROLL* pNMPGScroll, LRESULT * pResult);
afx_msg BOOL OnPagerCalcSize(NMPGCALCSIZE * pNMPGCalcSize, LRESULT* pResult);
DECLARE_MESSAGE_MAP()      

大功告成,编译运行程序吧......

虽然这个例子只是一个Demo,但你如果有兴趣,可以很容易扩充它的功能,使它更实用一些。

时间: 2024-11-02 17:33:24

Outlook式样界面菜单和页面控制的相关文章

Win10 UWP 开发系列:使用SplitView实现汉堡菜单及页面内导航

原文:Win10 UWP 开发系列:使用SplitView实现汉堡菜单及页面内导航 在Win10之前,WP平台的App主要有枢轴和全景两种导航模式,我个人更喜欢Pivot即枢轴模式,可以左右切换,非常方便.全景视图因为对设计要求比较高,自己总是做不出好的效果.对于一般的新闻阅读类App来说,Pivot更适合多个频道的展示,因为内容基本都是一样的. 到了Win10,微软模仿其他平台也推出了汉堡菜单,但并没有提供现成的控件,而是需要开发者通过一个名为SplitView的控件来实现.我个人并不觉得左上

vc60-VC(MFC)串口调试界面添加一个按钮控制两种颜色变换的指示灯。谢谢!!!

问题描述 VC(MFC)串口调试界面添加一个按钮控制两种颜色变换的指示灯.谢谢!!! 用MFC做出来一个只能发送和接受的界面之后,需要添加一个或两个按钮控制两种颜色变换.请问是指示灯吗?代码怎么写?谢谢. 解决方案 直接放一个static控件,准备两个图片,一个红灯一个绿灯 直接画http://blog.csdn.net/lujianfeiccie2009/article/details/7281996 当然,也可以不用先准备图片,而直接通过画圆.填充绘制出灯.

quality center-QC登陆主界面Quality Center页面出现的问题,一直显示loading...具体如图:

问题描述 QC登陆主界面Quality Center页面出现的问题,一直显示loading...具体如图: QC登陆主界面Quality Center页面出现的问题,一直显示loading...然后下面是...具体如图:请教各位大神... 解决方案 图呢?我记得QC需要个装个东西浏览器才能跑,如果装过了,QC登陆一般比较卡,多等会,不要点浏览器界面

jquery-web 个人中心点击左侧菜单刷新页面后,如何设置点击项为活动状态。

问题描述 web 个人中心点击左侧菜单刷新页面后,如何设置点击项为活动状态. 像饿了么.拉钩个人中心的左侧菜单,是怎么在刷新页面后还能项给加活动状态的. 解决方案 你说的活动状态是不是那个项上有个图标? 那种是存在数据库的状态,加载页面的时候自动获取的.

访问权限控制-menustrip怎样对子菜单进行权限控制,

问题描述 menustrip怎样对子菜单进行权限控制, menustrip怎样对子菜单进行权限控制,如图对基础资料设定,条码列印进行更细的权限设置 解决方案 无非就是递归遍历menustrip,得到菜单的名字或者tag,根据用户名,查询数据库,有没有对应的权限,如果没有,就禁用或者删除菜单. 解决方案二: C#Winform主窗体Load事件中对菜单权限进行控制jquery 权限控制菜单struts下通过过滤器进行权限控制

eclipse插件 java-eclispe的run菜单的run as...子菜单,怎么控制显示?

问题描述 eclispe的run菜单的run as...子菜单,怎么控制显示? 在eclispe的run菜单的run as...子菜单里面加上一个选项[Test Run],就是加一个launch shortcut在里面,扩展了org.eclipse.debug.ui.launchShortcuts扩展点,[Test Run]菜单功能正常可用. 问题:现在想选中项目右键时,通过自定义逻辑来控制[Test Run]是否显示,有大神知道怎么控制吗? 判断逻辑:获取选中项目中的pom.xml文件,解析文

在Winform界面菜单中实现动态增加【最近使用的文件】菜单项

在我们一些和文件处理打交道的系统中,我们往往需要记录下最近使用的文件,这样方便用户快速打开之前浏览或者编辑过的文件,这种在很多软件上很常见,本文主要介绍在Winform界面菜单中实现[最近使用的文件]动态菜单的处理,实现一个较为常用的功能. 在我上篇随笔<文字处理控件TX Text Control的使用>介绍的内容中,我针对性的对这个控件的使用做了一个全面的了解,发现其中案例代码总这部分的功能实现[最近使用的文件]挺好,于是把它进行了整理,把整个思路作为一篇随笔进行记录,希望对大家有所帮助.

Winform界面基于多页面数据的处理实现

我们在做Winform项目开发的时候,经常会发现有一些数据很多,需要通过不同的Tab页面分类来实现数据的录入和现实,例如体检数据,可能包含外科.内科.眼科.耳鼻喉科.口腔科.以及其他的检查等等内容,如果一次性放在一个窗口中现实,不太合理也不好看,如果通过多个Tab分类进行管理,则用户体验好很多. 如果分为多个Tab页面进行数据管理,最好的方法是,每个页面负责自己的数据存储及显示,由于数据可能是关联的,存储需要使用事务.保存的时候,可能每项都会有检查数据是否完备及有效性.那么我们应该实现类似这样的

类似于Outlook的导航菜单

菜单|导航 看到一个类似于Outlook的导般菜单,功能挺不错的,而且制作方法也较简单,特简单介绍一下,先请参看效果! 点击这里预览效果页面 制作方法: 1.在<body>插入代码: <SCRIPT>function showitem(id,name){return ("<span><a href='"+id+"' target=_self>"+name+"</a></span><