欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Visual C++中Tab View的多種實現(xiàn)方法

 更新時間:2014年10月17日 09:28:35   投稿:shichen2014  
這篇文章主要介紹了Visual C++中Tab View的多種實現(xiàn)方法,包括了CTabCtrl控件、CSheetCtrl標簽選擇窗口以及靜態(tài)分割窗口等實現(xiàn)Tab View的方法,需要的朋友可以參考下

本文實例講述了Visual C++中Tab View的多種實現(xiàn)方法,分享給大家供大家參考。具體如下:

一、引言

標簽控件(Tab Control)是VC++編程中經(jīng)常使用的控件之一,它允許在單個對話框或窗口中設(shè)置多個頁面,每個頁面代表一組控件。當某個頁面的標簽被選中時,該頁 面內(nèi)的控件就會被顯示出來。標簽控件使得在有限的窗口空間內(nèi)可以顯示更多的信息,而且分類清晰。同時,VC++提供了以文檔/視圖 (Document/View)結(jié)構(gòu)方式開發(fā)應(yīng)用程序的簡單方法,在文檔中保存數(shù)據(jù),在視圖中顯示數(shù)據(jù)。無論是在SDI還是MDI的程序中,每個文檔可以 對應(yīng)一個或多個是視圖,但常常在顯示數(shù)據(jù)時,需要將同一組數(shù)據(jù)用不同的視圖顯示,如列表視圖、樹型視圖等,或者用一個視圖顯示一部分數(shù)據(jù),用另一個視圖顯 示另一部分數(shù)據(jù),并且希望能在同一個顯示區(qū)顯示,在需要時進行切換。將標簽控制運用到多視圖的切換中,就形成了Tab View。
通過上面的分析,我們不難發(fā)現(xiàn),實現(xiàn)一個Tab View主要要完成以下兩方面的工作:

① 實現(xiàn)一個標簽窗口。它要具有繪制窗口、響應(yīng)用戶選擇、判斷處理用戶選擇等功能。本文對Tab View 實現(xiàn)方法的分類就是根據(jù)標簽窗口不同劃分的。

② 多個視圖之間的切換。根據(jù)標簽窗口判斷用戶選擇的結(jié)果,從多個視圖中選擇一個,在顯示區(qū)中顯示。

本文分析和總結(jié)了三種Tab View的實現(xiàn)方法:

1)利用CTabCtrl控件實現(xiàn)Tab View.
2)利用CSheetCtrl標簽選擇窗口實現(xiàn)Tab View.
3)利用靜態(tài)分割窗口實現(xiàn)Tab View.

二、CTabCtrl控件實現(xiàn)Tab View

CTabCtrl是MFC類庫中定義的標準控件類,通過對消息TCN-SELCHANGE的處理以及運用函數(shù)GetCurSel()、 SetCurSel()等,可以很好地完成響應(yīng)、判斷和設(shè)置標簽控制的工作,因此利用CTabCtrl控件實現(xiàn)Tab View是較容易的方法。

1.實現(xiàn)的主要類

復(fù)制代碼 代碼如下:
//要切換顯示的視窗口類
class CMyView1 : public CListView
class CMyView2 : public CView
     //派生的標簽控件類
class CViewTabCtrl : public CTabCtrl
     //定義了Tab view的主窗口
class CTabCtrlView : public CWnd
{
    protected:
       CViewTabCtrl m_TabCtl;
    …
}
class CMainFrame : public CFrameWnd
{
      CTabCtrlView m_TabView;
 …
}

2.窗口之間的父子關(guān)系以及位置關(guān)系
下述代碼確定各窗口之間的位置關(guān)系。
復(fù)制代碼 代碼如下:
void CTabCtrlView::RecalcLayout()
{    …
  CRect rect;
  // CTabCtrlView窗口的客戶區(qū)大小
  GetClientRect(&rect);
  m_TabCtl.RecalcLayout(rect, pWnd);
  …
}
void CViewTabCtrl::RecalcLayout(CRect & rect, CWnd * wnd)
{
  //標簽控件占據(jù)CTabCtrlView窗口的客戶區(qū)
  SetWindowPos(NULL, rect.left, rect.top, rect.right - rect.left,
        rect.bottom - rect.top, SWP_NOZORDER);
  //調(diào)整要顯示的視窗口位置,使其占據(jù)標簽控件的顯示區(qū)
  AdjustRect(FALSE, &rect);
  wnd->SetWindowPos(NULL, rect.left, rect.top, rect.right - rect.left,
      rect.bottom - rect.top, SWP_NOZORDER);
}

3.多個視之間切換的實現(xiàn)
視的切換主要完成下面的工作:
復(fù)制代碼 代碼如下:
// 步驟1:設(shè)置當前活動的子窗口的ID
CView* pOldActiveView = GetActiveView();
::SetWindowLong(pOldActiveView->m_hWnd, GWL_ID, m_nCurrentExample);
// 步驟2:生成一個新的與所選擇的視窗口對應(yīng)的運行時類
CRuntimeClass* pNewViewClass;
switch (nViewID)// nViewID各個視圖的標識
{
 case ID_MYVIEW1:
     pNewViewClass = RUNTIME_CLASS(CMyView1);
     break;
 case ID_MYVIEW2:
     pNewViewClass = RUNTIME_CLASS(CMyView2);
     break;
  default:
    ASSERT(0);
    return;
}
// 步驟3:準備新視圖類的相關(guān)上下文,創(chuàng)建新的視
CCreateContext Context;
Context.m_pNewViewClass = pNewViewClass;
Context.m_pCurrentDoc = GetActiveDocument();
CView* pNewView = m_TabView.CreateView(pNewViewClass, CSize(100,100), &Context);
if (pNewView != NULL)
{
         // 步驟4:顯示新的視圖
         pNewView->ShowWindow(SW_SHOW);
         SetActiveView(pNewView);
         …
         // 步驟5:關(guān)閉舊的視圖
         pOldActiveView->DestroyWindow();
}

在視圖切換過程中,都需要重新生成新視圖,關(guān)閉舊的視圖。但在某些情況下,希望多個視圖窗口能夠同時存在,在某時刻只顯示一個,而隱藏其它的窗口。可以通過定義下面的數(shù)據(jù)結(jié)構(gòu)和變量,將每次加入的新視圖的窗口信息保存。
復(fù)制代碼 代碼如下:
typedef struct
{
         CWnd *pWnd;   //窗口指針
         char szLabel[32]; //標簽窗口對應(yīng)該視圖的字符串
}TCB_ITEM;
//將每次如入的視圖信息保存到列表中
CList <TCB_ITEM *,TCB_ITEM *> m_Views;

在切換時,通過函數(shù)SetWindowPos()中設(shè)置參數(shù)SWP_SHOWWINDOW或SWP_HIDEWINDOW來顯示選中的新視圖,或隱藏舊視圖。采用這種方法,使對視圖操作更加靈活,可以很方便在Tab View中添加和刪除不同視圖。

三、CSheetCtrl標簽選擇窗口實現(xiàn)Tab View

CSheetCtrl不是MFC類庫中的類,用它來實現(xiàn)Tab View的方法和上一個方法基本相同。在程序員大本營網(wǎng)站的VC編程源代碼集的[其它控制]分類中,” A Tab-like Sheet Ctrl”程序含有該類源代碼,但在使用時要將窗口的切換改為視圖切換。

1.標簽窗口的創(chuàng)建

CSheetCtrl實現(xiàn)的Attach( )函數(shù),是它與外部的接口。在CTabSheetCtrl 中定義CSheetsWnd m_Sheet ,初始化過程中,通過調(diào)用m_Sheet.Attach( this)將CSheetCtrl創(chuàng)建為CTabSheetCtrl窗口的子窗口。

復(fù)制代碼 代碼如下:
BOOL CSheetsWnd::Attach(CWnd * pWndParent, COLORREF rgbBackground)
{
     //確定了標簽窗口的大小和位置
     CRect rect = GetRect(pWndParent);
     …
     BOOL bResult = Create( … , rect , …);
     …
     return bResult;
}
CRect CSheetsWnd::GetRect(CWnd* pWndParent)
{
     CRect rect;
     pWndParent->GetClientRect(rect);
     rect.top = rect.bottom - GetSystemMetrics(SM_CYVTHUMB);
     return rect;
}

2.查找所選視圖窗口

CSheetCtrl實現(xiàn)了類似于CTabCtrl的功能,如繪制標簽窗口、判斷用戶的選擇等。它本身并沒有保存任何有關(guān)視圖的信息,在視圖切換時,它通過其父窗口來查找用戶所選的視圖窗口。

復(fù)制代碼 代碼如下:
//得到父窗口的第一個的視圖子窗口指針函數(shù)
CWnd* CSheetsWnd::GetFirstView()
{
     m_pViewFind = GetParent()->GetWindow(GW_CHILD);
     // m_hWnd存放的是CSheetCtrl標簽窗口
     //排除CSheetCtrl標簽窗口
         while (m_pViewFind && m_pViewFind->m_hWnd == m_hWnd)
              m_pViewFind = m_pViewFind->GetWindow(GW_HWNDNEXT);
         return m_pViewFind;
}  
//得到下一個視圖窗口指針函數(shù)
CWnd* CSheetsWnd::GetNextView()
{
         if (m_pViewFind)
         {
             m_pViewFind = m_pViewFind->GetWindow(GW_HWNDNEXT);
             while (m_pViewFind && m_pViewFind->m_hWnd == m_hWnd)
                  m_pViewFind = m_pViewFind->GetWindow(GW_HWNDNEXT);
             return m_pViewFind;
         }
         return NULL;
}

按一定的順序得到所有父窗口(CTabSheetCtrl)的子窗口(CMyView1、CMyView2)指針后,根據(jù)每個子窗口的標題所占空間位置,來確定所選擇的視圖窗口。
復(fù)制代碼 代碼如下:
//獲得第一個視圖窗口指針
CWnd* pChild = GetFirstView();
while (pChild)
{
  CRect rect(cx,0,0,0);
  //rect返回繪制該窗口的標題所需的矩形大小
  pDC->DrawText(GetViewTitle(pChild), rect, DEFAULTFORMATDRAWTEXT | DT_CALCRECT);
  rect.top = 0;
  rect.bottom = m_DrawRect.Height();
  if ((aPointX > cx - LRB) && (aPointX   <= cx + rect.Width() + LRB))// aPointX鼠標位置的橫坐標
  break;//找到所選視圖
  //獲得下一個視圖窗口的指針
  pChild = GetNextView();
  int next = rect.Width() + 6 + LRB;
  cx += next;
}

四、靜態(tài)分割窗口實現(xiàn)Tab View

用靜態(tài)分割窗口CSplitterWnd實現(xiàn)Tab View,其主要的設(shè)計思想是通過分割窗口,使用splitter窗口的Pane(0,0)作為切換視的顯示區(qū),Pane(0,1)顯示類似圖3的高級標 簽窗口CWndTab。CSplitterWnd窗口完成了上面兩種方法中CTabCtrlView和CTabSheetView的工作,作為視的窗口和 標簽窗口的容器。此方法的源代碼,在程序員大本營網(wǎng)站也有。

五、結(jié)束語

筆者通過分析了多個相關(guān)程序的源代碼,并且在實際編程過程中,根據(jù)需要實現(xiàn)了自己的Tab View。在此簡要地總結(jié)了三種實現(xiàn)Tab View 的方法,希望對讀者的編程能有所幫助。

相關(guān)文章

  • C語言模擬實現(xiàn)atoi函數(shù)的實例詳解

    C語言模擬實現(xiàn)atoi函數(shù)的實例詳解

    這篇文章主要介紹了C語言模擬實現(xiàn)atoi函數(shù)的實例詳解的相關(guān)資料,atoi函數(shù),主要功能是將一個字符串轉(zhuǎn)變?yōu)檎麛?shù),這里就實現(xiàn)這樣的函數(shù),需要的朋友可以參考下
    2017-08-08
  • 關(guān)于C++中引用的定義與使用詳解

    關(guān)于C++中引用的定義與使用詳解

    這篇文章主要介紹了關(guān)于C++中引用和指針的區(qū)別,概念:引用是為已存在的變量取了一個別名,引用和引用的變量共用同一塊內(nèi)存空間,需要的朋友可以參考下
    2023-07-07
  • 一篇文章帶你了解C語言函數(shù)的可重入性

    一篇文章帶你了解C語言函數(shù)的可重入性

    這篇文章主要為大家詳細介紹了C語言函數(shù)的可重入性,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • C++?中如何結(jié)束?while?(cin>>str)?的輸入

    C++?中如何結(jié)束?while?(cin>>str)?的輸入

    這篇文章主要介紹了C++?中如何結(jié)束?while?(cin>>str)?的輸入,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • c語言如何實現(xiàn)兩數(shù)之和

    c語言如何實現(xiàn)兩數(shù)之和

    這篇文章主要介紹了c語言如何實現(xiàn)兩數(shù)之和,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • C語言中程序如何調(diào)用Python腳本

    C語言中程序如何調(diào)用Python腳本

    由于python有很多功能強大的開源庫,有時候在寫C語言程序的時候又想利用一下python強大的模塊,那么C語言中程序如何調(diào)用Python腳本,感興趣的小伙伴們可以參考一下
    2021-05-05
  • 嵌入式C實戰(zhàn)項目開發(fā)技巧:對一個有規(guī)律的數(shù)組表進行位移操作的方法

    嵌入式C實戰(zhàn)項目開發(fā)技巧:對一個有規(guī)律的數(shù)組表進行位移操作的方法

    今天小編就為大家分享一篇關(guān)于嵌入式C實戰(zhàn)項目開發(fā)技巧:對一個有規(guī)律的數(shù)組表進行位移操作的方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • c++中try catch的用法小結(jié)

    c++中try catch的用法小結(jié)

    這篇文章主要介紹了c++中try catch的用法小結(jié),需要的朋友可以參考下
    2018-01-01
  • 深入理解C++內(nèi)鏈接與外鏈接的意義

    深入理解C++內(nèi)鏈接與外鏈接的意義

    鏈接描述了名稱在整個程序或一個翻譯單元中如何引用或不引用同一實體,下面這篇文章主要給大家介紹了關(guān)于C++內(nèi)鏈接與外鏈接意義的理解,需要的朋友可以參考下
    2021-11-11
  • C++實現(xiàn)LeetCode(148.鏈表排序)

    C++實現(xiàn)LeetCode(148.鏈表排序)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(148.鏈表排序),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07

最新評論