www.gusucode.com > VC++的窗体TabView标签切换实现-源码程序 > VC++的窗体TabView标签切换实现-源码程序/code/TabCtrlView.cpp
// TabCtrlView.cpp : implementation file // Download by http://www.NewXing.com #include "stdafx.h" #include "Tab2.h" #include "TabCtrlView.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CTabCtrlView IMPLEMENT_DYNCREATE(CTabCtrlView, CView) CTabCtrlView::CTabCtrlView() { } CTabCtrlView::~CTabCtrlView() { } BEGIN_MESSAGE_MAP(CTabCtrlView, CWnd) //{{AFX_MSG_MAP(CTabCtrlView) ON_WM_SIZE() ON_WM_PAINT() ON_WM_ERASEBKGND() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CTabCtrlView drawing void CTabCtrlView::OnDraw(CDC* pDC) { //CDocument* pDoc = GetDocument(); // TODO: add draw code here } ///////////////////////////////////////////////////////////////////////////// // CTabCtrlView diagnostics #ifdef _DEBUG void CTabCtrlView::AssertValid() const { //CView::AssertValid(); } void CTabCtrlView::Dump(CDumpContext& dc) const { //CView::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CTabCtrlView message handlers BOOL CTabCtrlView::HandleTabs(int iSel) { CWnd* pWnd = AfxGetMainWnd(); switch(iSel) { case 0: pWnd->SendMessage(WM_MYMESSAGE, ID_VIEW1, 0); break; case 1: pWnd->SendMessage(WM_MYMESSAGE, ID_VIEW2, 0); break; case 2: pWnd->SendMessage(WM_MYMESSAGE, ID_VIEW3, 0); break; default: ASSERT(0); return FALSE; } return TRUE; } void CTabCtrlView::SetTab(int iTab) { m_TabCtl.SetCurSel(iTab); } BOOL CTabCtrlView::CreateStatic(CWnd * pParentWnd, DWORD dwstyle, UINT nID) { ASSERT(pParentWnd!= NULL); ASSERT(dwstyle & WS_CHILD); ASSERT(!(dwstyle & SPLS_DYNAMIC_SPLIT)); ASSERT(nID != 0); // create with the same wnd-class as mdi-frame (no erase bkgnd) if (!CreateEx(0, NULL, NULL, dwstyle, 0, 0, 0, 0, pParentWnd->m_hWnd, (HMENU)nID, NULL)) return FALSE;// create invisible //create the tab control DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS; dwstyle |= TCS_TABS; BOOL iResult=m_TabCtl.Create(dwstyle, CRect(0,0,0,0), this, 1000); if(!iResult) return FALSE; //overide this function to provide your tabs InitTabs(this); return TRUE; } CView * CTabCtrlView::CreateView(CRuntimeClass * pViewClass, SIZE sizeInit, CCreateContext * pContext) { #ifdef _DEBUG ASSERT_VALID(this); ASSERT(pViewClass != NULL); ASSERT(pViewClass->IsDerivedFrom(RUNTIME_CLASS(CWnd))); ASSERT(AfxIsValidAddress(pViewClass, sizeof(CRuntimeClass), FALSE)); #endif BOOL bSendInitialUpdate = FALSE; CCreateContext contextT; if (pContext == NULL) { // if no context specified, generate one from the currently selected // client if possible CView* pOldView = NULL; if (pOldView != NULL && pOldView->IsKindOf(RUNTIME_CLASS(CView))) { // set info about last pane ASSERT(contextT.m_pCurrentFrame == NULL); contextT.m_pLastView = pOldView; contextT.m_pCurrentDoc = pOldView->GetDocument(); if (contextT.m_pCurrentDoc != NULL) contextT.m_pNewDocTemplate = contextT.m_pCurrentDoc->GetDocTemplate(); } pContext = &contextT; bSendInitialUpdate = TRUE; } CWnd* pWnd; TRY { pWnd = (CWnd*)pViewClass->CreateObject(); if (pWnd == NULL) AfxThrowMemoryException(); } CATCH_ALL(e) { TRACE0("out of memory creating a splitter pane.\n"); // note: delete_exception(e) not required return (CView*) NULL; } END_CATCH_ALL ASSERT_KINDOF(CWnd, pWnd); ASSERT(pWnd->m_hWnd == NULL); // not yet created DWORD dwstyle = AFX_WS_DEFAULT_VIEW; // create with the right size (wrong position) CRect rect(CPoint(0,0), sizeInit); if (!pWnd->Create(NULL, NULL, dwstyle,rect, this, 0, pContext)) { TRACE0("warning: couldn't create client pane for splitter.\n"); // pwnd will be cleaned up by postncdestroy return (CView*) NULL; } m_ActiveView = (CView*) pWnd; return m_ActiveView; } //调节窗口之间的大小关系 void CTabCtrlView::OnSize(UINT nType, int cx, int cy) { if (nType != SIZE_MINIMIZED && cx > 0 && cy > 0) RecalcLayout(); CWnd::OnSize(nType, cx, cy); return; } void CTabCtrlView::RecalcLayout() { CWnd* pWnd = (CWnd*) GetActiveView(); //得到CTabCtrlView的窗口的客户区大小 CRect rect; GetClientRect(&rect); m_TabCtl.RecalcLayout(rect, pWnd); } CView* CTabCtrlView::GetActiveView() { return m_ActiveView; } void CTabCtrlView::OnPaint() { CPaintDC dc(this); // device context for painting } void CTabCtrlView::InitTabs(CTabCtrlView * pView) { TC_ITEM TabCtrlItem; TabCtrlItem.mask = TCIF_TEXT ; TabCtrlItem.pszText = "CView1"; m_TabCtl.InsertItem( 0, &TabCtrlItem ); TabCtrlItem.pszText = "CView2"; m_TabCtl.InsertItem( 1, &TabCtrlItem ); TabCtrlItem.pszText = "CView3"; m_TabCtl.InsertItem( 2, &TabCtrlItem ); m_TabCtl.SetView(pView); return; } ///////////////////////////////////////////////////////////////////////////// // CViewTabCtrl CViewTabCtrl::CViewTabCtrl() { } CViewTabCtrl::~CViewTabCtrl() { } BEGIN_MESSAGE_MAP(CViewTabCtrl, CTabCtrl) //{{AFX_MSG_MAP(CViewTabCtrl) ON_NOTIFY_REFLECT(TCN_SELCHANGE, OnSelchange) ON_WM_ERASEBKGND() ON_WM_SIZE() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CViewTabCtrl message handlers void CViewTabCtrl::SetView(CTabCtrlView * pView) { m_pView=pView; return; } void CViewTabCtrl::RecalcLayout(CRect & rect, CWnd * pWnd) { //标签控件占据CTabCtrlView的客户区 SetWindowPos(NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER); //调整要显示的视窗口位置,使其占据标签控件的显示区 AdjustRect(FALSE, &rect); pWnd->SetWindowPos( NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER); } BOOL CViewTabCtrl::HandleTabs(int sel) { return m_pView->HandleTabs(sel); } void CViewTabCtrl::OnSelchange(NMHDR* pNMHDR, LRESULT* pResult) { int iSel = GetCurSel(); HandleTabs(iSel); *pResult = 0; } BOOL CTabCtrlView::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default return FALSE;//CWnd::OnEraseBkgnd(pDC); } BOOL CViewTabCtrl::OnEraseBkgnd(CDC* pDC) { CRect Rect; m_pView->m_ActiveView->GetWindowRect(&Rect); ScreenToClient(&Rect); //去掉视窗口的显示的区域,防止ERASE覆盖视窗口 pDC->ExcludeClipRect(&Rect); return CTabCtrl::OnEraseBkgnd(pDC); }