当前位置:编程学习 > C/C++ >>

多标签视图类CTabView的设计实现

在MFC9(在vc2008和vc2010中,已经有了CTabView的现成类)以前的版本中,有CListView,CTreeView,CEditView,CRichEditView等控件视图类,但就是没有类似的CTabView类,因工作需要,最近在做一个简单的多标签IE浏览器,开发环境是vs2005,基本框架是sdi + chtmlview + ctabview,因此自行封装实现了CTabView,并把它作为一个重要的基础类来维护使用。先来说下我这个CTabView类的特点及功能:
(1)CTabView本质上就是一种窗口容器,基于CCtrlView实现,能够容纳类型为CWnd的所有窗口,并作为它的子窗口(为描述方便,在这特称为视图页面),每个标签对应一个视图页面。
(2)扩展了标准的标签项数据结构TC_ITEM,即自定义了一个TC_EXTRA_ITEM扩展数据结构,该结构除包含标准的数据结构(第1个成员)外,还包括视图页面对象、内部标志、视图页面标题、视图页面关联数据4种类型数据,扩展数据大小需要在创建后插入标签前调用SetItemExtra设定。
(3)支持容纳外部窗口和创建内部窗口,前者是指容纳外面已经创建好的窗口;后者是根据窗口类型信息,由CTabView自己来管理创建视图页面。
(4)对于内部窗口的管理,为方便区分并有利于消息映射处理,因此窗口ID是唯一的,即在创建时分派一个新的不同的ID,销毁时回收到ID数组中。而外部窗口ID则由外部管理。
(5)提供激活视图页面后的自定义处理,表现为OnViewActivated虚函数。
(6)提供右键单击Tab标签后的自定义处理,表现为OnTabContextMenu虚函数。
(7)提供Tab标签提示信息的自定义处理,表现为UpdateTooltipText虚函数。
(8)提供CTabView视图类的自绘处理(须设定TCS_OWNERDRAWFIXED样式),表现为DrawItem虚函数。
(9)Tab标签的文本默认是简写的,即当长度超过最大值时,多余部分用省略号...代替,同时也支持自定义处理,表现为ShortenTitle虚函数。
(10)对上述特点7,为了能支持派生类自定义处理,由于提示文本消息的发送者是CToolTipCtrl窗口,而不是CTabView本身,所以不能像TCN_SELCHANGE,NM_RCLICK等通知消息可以使用反射宏来实现,因此使用了窗口子类化来捕获父窗口的TTN_GETDISPINFO通知消息实现的。这一行为也可以通过UpdateTooltipText来定制,当其返回值是TRUE时,表示允许消息默认被父窗口接收处理,否则,反之。
(11)对上述特点8,本可以重载OnChildNotify来实现WM_DRAWITEM消息的回调,但为了简洁,如同TTN_GETDISPINFO通知消息,也是使用窗口子类化来捕获实现的。
(12)对上述10和11的消息捕获处理,使用了CBasicSubClassWnd类来实现,表现为重写其SubWindowProc虚函数。

   接下来看看CTabView类的接口定义,如下所示
  1#ifndef _TABVIEW_H
  2#define _TABVIEW_H
  3
  4#include <afxwin.h>
  5#include "basic_subclasswnd.h"
  6
  7#define WC_TABVIEWA "SysTabControl32"
  8#define WC_TABVIEWW L"SysTabControl32"
  9
 10#if (defined(_UNICODE)||defined(UNICODE))
 11#define WC_TABVIEW WC_TABVIEWW
 12#else
 13#define WC_TABVIEW WC_TABVIEWA
 14#endif
 15
 16class CTabView : public CCtrlView,private CBasicSubClassWnd
 17{
 18    DECLARE_DYNCREATE(CTabView)
 19
 20    struct TAB_VIEW
 21    {
 22        CWnd*  pWnd;     // 视图页面窗口
 23        BOOL   bInner;   // 视图页面是否内部创建
 24        LPTSTR pszTitle; // 视图页面标题
 25        LPVOID pData;    // 视图页面数据
 26    };
 27
 28    //扩展TC_ITEM数据,第一个成员必须为TCITEMHEADER类型
 29    struct TC_EXTRA_ITEM
 30    {
 31        TCITEMHEADER header;
 32        TAB_VIEW  view;
 33        operator LPTCITEM() { return (LPTCITEM)this; }
 34    };
 35
 36public:
 37    CTabView();
 38    virtual ~CTabView();
 39
 40    CTabCtrl& GetTabCtrl() const;
 41
 42    //在最后增加视图页面
 43    CWnd* AddView(CRuntimeClass* pClass,CCreateContext* pContext=NULL,LPCTSTR pszTitle=NULL,
 44                  int iImage=-1,LPVOID pData=NULL,BOOL bActivate=TRUE);
 45    BOOL  AddView(CWnd* pWnd,LPCTSTR pszTitle=NULL,int iImage=-1,LPVOID pData=NULL,BOOL bActivate=TRUE);
 46    //在某处插入视图页面
 47    CWnd* InsertView(int iIndex,CRuntimeClass* pClass,CCreateContext* pContext=NULL,LPCTSTR pszTitle=NULL,
 48                    int iImage=-1,LPVOID pData=NULL,BOOL bActivate=TRUE);
 49    BOOL InsertView(int iIndex,CWnd* pWnd,LPCTSTR pszTitle=NULL,int iImage=-1,
 50                    LPVOID pData=NULL,BOOL bActivate=TRUE);
 51
 52    //移除视图页面
 53    void RemoveView(int iIndex,BOOL bDestroy=TRUE);
 54    void RemoveView(CWnd* pWnd,BOOL bDestroy=TRUE);
 55    //移除所有视图页面
 56    void RemoveAllView();
 57
 58    //获取活动视图页面
 59    CWnd* GetActiveView() const;
 60    int GetActiveViewIndex() const;
 61    //设置活动视图页面
 62    void SetActiveViewIndex(int iIndex);
 63    void SetActiveView(const CWnd* pWnd);
 64
 65    //按索引获取某个视图页面
 66    CWnd* GetView(int iIndex) const;
 67    //按窗口获取视图页面的索引
 68    int GetIndex(const CWnd* pWnd) const;
 69
 70    //获取视图页面数量
 71    int GetViewCount() const;
 72   
 73    //设置视图页面的标题
 74    BOOL SetViewTitle(int iIndex,LPCTSTR pszTitle);
 75    BOOL SetViewTitle(const CWnd* pWnd,LPCTSTR pszTitle);
 76    //获取视图页面的标题
 77    BOOL GetViewTitle(const CWnd* pWnd,LPTSTR& pszTitle) const;
 78    BOOL GetViewTitle(int iIndex,LPTSTR& pszTitle) const;
 79
 80    //设置视图页面的图像
 81    BOOL SetViewImage(const CWnd* pWnd,int iImage);
 82    BOOL SetViewImage(int iIndex,int iImage);
 83    //获取视图页面的图像
 84    BOOL GetViewImage(const CWnd* pWnd,int& iImage) const;
 85    BOOL GetViewImage(int iIndex,int& iImage) const;
 86
 87    //设置视图页面的数据
 88    BOOL SetViewData(int iIndex,LPVOID pData);
 89    BOOL SetViewData(const CWnd* pWnd,LPVOID pData);
 90    //获取视图页面的数据
 91    BOOL GetViewData(int iIndex,LPVOID& pData) const;
 92    BOOL GetViewData(const CWnd* pWnd,LPVOID& pData) const;
 93
 94&

补充:软件开发 , C语言 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,