VS2008 前 MFC 缺乏 CTabView,為 SDI + CHtmlView + 分頁瀏覽器專案自行實作,支援:
CWnd 衍生類作為分頁視圖class CTabView : public CCtrlView, private CBasicSubClassWnd {
// 擴展標籤項
struct TC_EXTRA_ITEM {
TCITEMHEADER header; // 必須為第一成員
struct TAB_VIEW {
CWnd* pWnd;
BOOL bInner;
LPTSTR pszTitle;
LPVOID pData;
} view;
operator LPTCITEM() { return (LPTCITEM)this; }
};
// 主要介面
CWnd* AddView(CRuntimeClass*, CCreateContext*, LPCTSTR, int, LPVOID, BOOL);
BOOL AddView(CWnd*, LPCTSTR, int, LPVOID, BOOL);
CWnd* InsertView(int, CRuntimeClass*, ...);
BOOL InsertView(int, CWnd*, ...);
void RemoveView(int, BOOL);
void RemoveView(CWnd*, BOOL);
void RemoveAllView();
CWnd* GetActiveView() const;
int GetActiveViewIndex() const;
void SetActiveViewIndex(int);
// ... 標題/圖示/資料 存取器
virtual void ShortenTitle(LPCTSTR, CString&); // 省略號處理
virtual void OnViewActivated(int); // 切換回調
virtual void OnTabContextMenu(int, CPoint); // 右鍵選單
virtual BOOL UpdateTooltipText(LPNMTTDISPINFO); // 工具提示
virtual void DrawItem(LPDRAWITEMSTRUCT); // 自繪
};
CWnd* pWnd = (CWnd*)pClass->CreateObject();
if (!pWnd->Create(NULL, NULL, WS_CHILD, CRect(0,0,0,0), this, GetUniqueId(), pContext))
return NULL;
SetViewInner(iIndex, TRUE);
GetUniqueId() 從回收陣列取用或生成新 IDm_UniqueIDsTC_EXTRA_ITEM ti;
ti.header.mask = TCIF_PARAM | TCIF_TEXT | TCIF_IMAGE;
ti.header.pszText = (LPTSTR)(LPCTSTR)strShortTitle;
ti.view.pszTitle = _tcsdup(pszTitle); // 保存完整標題
ti.view.pWnd = pWnd;
ti.view.pData = pData;
GetTabCtrl().InsertItem(iIndex, ti);
繼承 CBasicSubClassWnd,重寫 SubWindowProc 攔截父視窗通知,轉發給虛擬函式 UpdateTooltipText/DrawItem。
class CMyTabView : public CTabView {
virtual void OnViewActivated(int idx) {
CWnd* p = GetView(idx);
if (p->IsKindOf(RUNTIME_CLASS(CHtmlView)))
((CHtmlView*)p)->Navigate2(_T("about:blank"));
}
virtual void DrawItem(LPDRAWITEMSTRUCT lp) {
// 自繪標籤外觀
}
};
MFC 9.0 (VS2008) 內建 CTabView,本實作可作為教學參考或舊專案維護基礎。
作者:天道酬勤