WTL Outlook Bar 控件移植与使用指南

在进行ATL/WTL项目开发时,经常需要实现类似于Microsoft Outlook的导航栏功能。本文将介绍如何将Iuri Apollonio开发的MFC Outlook Bar控件移植到WTL项目中,并提供详细的使用指南。

概述

Iuri Apollonio开发的Outlook Bar控件原本是基于MFC的。本文将介绍如何将这个控件移植到WTL项目中。移植工作主要涉及三个ATL文件:

  • atloutbarctrl.h:包含WTL的COutBarCtrl类
  • atlgroupedit.h:包含WTL的CGroupEdit类,由COutBarCtrl类使用
  • atloutbarsplit.h:包含WTL的COutlookSplitterWindow类,由COutBarCtrl类使用

标题栏可以在atlcaptionbar.h中找到,包含了主要的CCaptionBar类。而flatbutton类可以在atlflatbutton.h中找到,包含了主要的CButtonST类。

COutlookSplitterWindow类是从WTL的CSplitterWindow类继承而来,为了实现左侧面板固定宽度的功能,需要添加额外的功能。这种功能在基类中对于右侧面板是存在的,但需要进行一些调整以使其表现得像Outlook的分隔器。原始的CGfxSplitterWindow并没有被移植,因为MFC和WTL的分隔器类存在差异。

需求

要使用这个控件,需要WTL库。这些库可以从Microsoft的官方网站下载。网上有许多文章介绍了如何下载和使用WTL库,因此本文不再赘述。

注意:这个控件使用了WTL的CString类和STL的std::list模板类。

如何在WTL应用中使用该控件

确保在项目中包含以下ATL文件:

#include "stdafx.h" #include "atlwin.h" #include "atlctrls.h" #include "atlmisc.h"

atlmisc.h是必须的,因为它包含了WTL CString类的定义。

在主框架类中添加头文件atloutbarctrl.h和atloutbarsplit.h,并声明Outlook Bar控件、Outlook Bar分隔器对象以及在Outlook Bar中使用的图像列表的实例。

COutBarCtrl wndBar; CImageList imaLarge, imaSmall; COutlookSplitterWindow m_splitter;

创建Outlook分隔器类,例如:

m_hWndClient = m_splitter.Create(m_hWnd, rect, NULL, WS_CHILD | WS_VISIBLE);

在MainFrame类的OnCreate函数中创建Outlook Bar控件,并设置图像列表,例如:

DWORD dwf = COutBarCtrl::fDragItems | COutBarCtrl::fEditGroups | COutBarCtrl::fEditItems | COutBarCtrl::fRemoveGroups | COutBarCtrl::fRemoveItems | COutBarCtrl::fAddGroups | COutBarCtrl::fAnimation; if (!wndBar.Create(WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), m_splitter.m_hWnd, 1234, dwf)) { DWORD word = GetLastError(); return 0; } wndBar.SetOwner(m_hWnd); imaLarge.Create(IDB_IMAGELIST, 32, 0, RGB(128, 128, 128)); imaSmall.Create(IDB_SMALL_IMAGELIST, 16, 0, RGB(0, 128, 128)); wndBar.SetImageList(&imaLarge, COutBarCtrl::fLargeIcon); wndBar.SetImageList(&imaSmall, COutBarCtrl::fSmallIcon); wndBar.SetAnimationTickCount(20); wndBar.SetAnimSelHighlight(200); wndBar.AddFolder("Folder 1", 0); wndBar.AddFolder("Folder 2", 1); wndBar.AddFolder("Folder 3", 2); wndBar.InsertItem(0, 0, "Item 1", 0, 0); wndBar.InsertItem(0, 1, "Item 2", 1, 0); wndBar.InsertItem(0, 2, "Item 3", 2, 0);

为了使分隔器表现得像Outlook分隔器,需要设置一些分隔器方法:

m_splitter.m_bFullDrag = false; // Draws the Ghost bar instead m_splitter.SetSplitterExtendedStyle(SPLIT_LEFTALIGNED); // Aligns the outlook bar to the left m_splitter.SetSplitterPanes(wndBar, m_list); // Set the outlook bar on the left pane m_splitter.SetSplitterPos(120); // width of the initial outlook bar

为了接收标签被选中时的事件,需要在消息映射中添加宏:

MESSAGE_HANDLER(WM_OUTBAR_NOTIFY, OnOutbarNotify)

在onNotify处理器中,捕获事件:

LRESULT OnOutbarNotify(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) { switch (wParam) { case NM_OB_ITEMCLICK: { int index = (int)lParam; CString cs, cs1; cs1 = wndBar.GetItemText(index); cs.Format("Clicked on %d - <%s>", (int)lParam, cs1); MessageBox(cs, "Outlook Bar", MB_OK); return 0; } case NM_OB_ONLABELENDEDIT: { OUTBAR_INFO *pOI = (OUTBAR_INFO *)lParam; return 1; } case NM_OB_ONGROUPENDEDIT: { OUTBAR_INFO *pOI = (OUTBAR_INFO *)lParam; return 1; } case NM_OB_DRAGITEM: { OUTBAR_INFO *pOI = (OUTBAR_INFO *)lParam; return 1; } } return 0; }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485