我想做一个在窗口有两个象标签式的按钮,然后有两个窗口可以通过他控制,并且两个窗口中显示的内容是动态的!

解决方案 »

  1.   

    就是TabView嘛,CodeProject和CodeGuru里面肯定有你适合使用的类的。==========================================================
    百尺竿头,卧薪尝胆
      

  2.   

    CPropertySheet加CPropertyPage也可實現Tab的功能.
    如我們建立DataLink的對話框就是屬於這种.不知你要的是哪种實現.
      

  3.   

    用TabView比较简单,每个标签页面中都有各自的初始化代码,可以实现动态显示。
      

  4.   

    给你我改的一个类,你自己用用: 
    #pragma once    //如果VC版本不支持此命令,改成if !defined...define...endif形式// TabSheet.h : header file
    //
     
    /////////////////////////////////////////////////////////////////////////////
    // CTabSheet window
    #define MAXPAGE 16    //最大显示16Tab页
     
    class CTabSheet : public CTabCtrl
    {
    // Construction
    public:
     CTabSheet();
     
    // Attributes
    public:
     
    // Operations
    public:
     
    // Overrides
     // ClassWizard generated virtual function overrides
     //{{AFX_VIRTUAL(CTabSheet)
     //}}AFX_VIRTUAL
     
    // Implementation
    public:
     int GetCurSel();
     int SetCurSel(int nItem);
     void Show();
     void SetRect();
     BOOL AddPage(LPCTSTR title, CDialog *pDialog, UINT ID);
     virtual ~CTabSheet();
     
     // Generated message map functions
    protected:
     LPCTSTR m_Title[MAXPAGE];
     UINT m_IDD[MAXPAGE];
     CDialog* m_pPages[MAXPAGE];
     int m_nNumOfPages;
     int m_nCurrentPage;
     //{{AFX_MSG(CTabSheet)
     afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
     //}}AFX_MSG
     
     DECLARE_MESSAGE_MAP()
    };
      

  5.   

    //Tabsheet.cpp文件
    #include "stdafx.h"
    #include "Property5.h"     // !!!这边改成你所用的工程文档名
    #include "TabSheet.h"
     
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
     
    /////////////////////////////////////////////////////////////////////////////
    // CTabSheet
     
    CTabSheet::CTabSheet()
    {
     m_nNumOfPages = 0;
     m_nCurrentPage = 0;
    }
     
    CTabSheet::~CTabSheet()
    {
    }
     BEGIN_MESSAGE_MAP(CTabSheet, CTabCtrl)
     //{{AFX_MSG_MAP(CTabSheet)
     ON_WM_LBUTTONDOWN()
     //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
     
    /////////////////////////////////////////////////////////////////////////////
    // CTabSheet message handlers
     
    BOOL CTabSheet::AddPage(LPCTSTR title, CDialog *pDialog,UINT ID)
    {
     if( MAXPAGE == m_nNumOfPages )
      return FALSE;
     
     m_nNumOfPages++;
     
     m_pPages[m_nNumOfPages-1] = pDialog;
     m_IDD[m_nNumOfPages-1] = ID;
     m_Title[m_nNumOfPages-1] = title;
     
     return TRUE;
    }
     
    void CTabSheet::SetRect()
    {
     CRect tabRect, itemRect;
     int nX, nY, nXc, nYc;
     
     GetClientRect(&tabRect);
     GetItemRect(0, &itemRect);
     
     nX=itemRect.left;
     nY=itemRect.bottom+1;
     nXc=tabRect.right-itemRect.left-2;
     nYc=tabRect.bottom-nY-2;
     
     m_pPages[0]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_SHOWWINDOW);
     for( int nCount=1; nCount < m_nNumOfPages; nCount++ )
      m_pPages[nCount]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_HIDEWINDOW);
     
    }
     
    void CTabSheet::Show()
    {
     for( int i=0; i < m_nNumOfPages; i++ )
     {
      m_pPages[i]->Create( m_IDD[i], this );
      InsertItem( i, m_Title[i] );
     }
     
     m_pPages[0]->ShowWindow(SW_SHOW);
     for( i=1; i < m_nNumOfPages; i++)
      m_pPages[i]->ShowWindow(SW_HIDE);
     
     SetRect();
     
    }
     
    void CTabSheet::OnLButtonDown(UINT nFlags, CPoint point) 
    {
     CTabCtrl::OnLButtonDown(nFlags, point);
     
     if(m_nCurrentPage != GetCurFocus())
     {
      m_pPages[m_nCurrentPage]->ShowWindow(SW_HIDE);
      m_nCurrentPage=GetCurFocus();
      m_pPages[m_nCurrentPage]->ShowWindow(SW_SHOW);
    //  m_pPages[m_nCurrentPage]->SetFocus();
     }
    }
     
    int CTabSheet::SetCurSel(int nItem)
    {
     if( nItem < 0 || nItem >= m_nNumOfPages)
      return -1;
     
     int ret = m_nCurrentPage;
     
     if(m_nCurrentPage != nItem )
     {
      m_pPages[m_nCurrentPage]->ShowWindow(SW_HIDE);
      m_nCurrentPage = nItem;
      m_pPages[m_nCurrentPage]->ShowWindow(SW_SHOW);
    //  m_pPages[m_nCurrentPage]->SetFocus();
      CTabCtrl::SetCurSel(nItem);
     }
     
     return ret;
    }
     
    int CTabSheet::GetCurSel()
    {
     return CTabCtrl::GetCurSel();
    }
      

  6.   

    先要制作子对话框类,这次的子对话框类不要从CPropertyPage继承,而是直接从CDialog继承。并且各个子对话框资源的属性应设置为:Style为Child, Border为None。
     
    在主对话框资源中,加入一个Tab Control,并且适当调整位置和大小。利用ClassWizard来为这个Tab Control创建一个CTabSheet的控件变量。
     
    在主对话框的OnInitDialog()加入:
     
    m_sheet.AddPage("tab1", &m_page1, IDD_DIALOG1);
    m_sheet.AddPage("tab2", &m_page2, IDD_DIALOG2);
    m_sheet.Show();
    就这样就可以在对话框上制作出一个完美的属性页了。效果和上图完全一样。 
    下面我就来讲讲CTabSheet类的细节内容。
     
    CTabSheet是从CTabCtrl继承来的,用于Tab Control的控件类。在类中有一个成员变量用来记录各子对话框的指针CDialog* m_pPages[MAXPAGE]; MAXPAGE是该类所能加载的标签的最大值。
     
    类中有一个AddPage方法,用于记录子对话框的指针和所使用对话框资源的ID号。
     BOOL CTabSheet::AddPage(LPCTSTR title, CDialog *pDialog,UINT ID)
    {
    if( MAXPAGE == m_nNumOfPages )
    return FALSE;
     
    //保存目前总的子对话框数
    m_nNumOfPages++;
     
    //记录子对话框的指针、资源ID、要在标签上显示的文字
    m_pPages[m_nNumOfPages-1] = pDialog;
    m_IDD[m_nNumOfPages-1] = ID;
    m_Title[m_nNumOfPages-1] = title;
     
    return TRUE;
    }
     在使用AddPage加入了若干子对话框后,必须调用CTabSheet的Show方法来真正生成标签和子对话框。 void CTabSheet::Show()
    {
    //利用CDialog::Create来创建子对话框,并且使用CTabCtrl::InsertItem来加上相应的标签
    for( int i=0; i < m_nNumOfPages; i++ )
    {
    m_pPages[i]->Create( m_IDD[i], this );
    InsertItem( i, m_Title[i] );
    }
     
    //由于对话框显示时默认的是第一个标签被选中,所以应该让第一个子对话框显示,其他子对话框隐藏
    m_pPages[0]->ShowWindow(SW_SHOW);
    for( i=1; i < m_nNumOfPages; i++)
    m_pPages[i]->ShowWindow(SW_HIDE);
     
    SetRect();
     
    }
     生成好标签和子对话框后,调用CTabSheet::SetRect来计算并调整属性页的大小。void CTabSheet::SetRect()
    {
    CRect tabRect, itemRect;
    int nX, nY, nXc, nYc;
     
    //得到Tab Control的大小
    GetClientRect(&tabRect);
    GetItemRect(0, &itemRect);
     
    //计算出各子对话框的相对于Tab Control的位置和大小
    nX=itemRect.left;
    nY=itemRect.bottom+1;
    nXc=tabRect.right-itemRect.left-2;
    nYc=tabRect.bottom-nY-2;
     
    //利用计算出的数据对各子对话框进行调整
    m_pPages[0]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_SHOWWINDOW);
    for( int nCount=1; nCount < m_nNumOfPages; nCount++ )
    m_pPages[nCount]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_HIDEWINDOW);
     
    }
     在单击标签栏后,应该是相应的子对话框显示,正在显示的子对话框应该隐藏。因此利用ClassWizard来处理WM_LBUTTONDOWN消息。void CTabSheet::OnLButtonDown(UINT nFlags, CPoint point) 
    {
    CTabCtrl::OnLButtonDown(nFlags, point);
     
    //判断是否单击了其他标签
    if(m_nCurrentPage != GetCurFocus())
    {
    //将原先的子对话框隐藏
    m_pPages[m_nCurrentPage]->ShowWindow(SW_HIDE);
    m_nCurrentPage=GetCurFocus();
    //显示当前标签所对应的子对话框
    m_pPages[m_nCurrentPage]->ShowWindow(SW_SHOW);
    }
     
    }
     这样利用CTabSheet这个类就可以轻松地在对话框上放置自己的属性页了,并且控件都分散在各子对话框类中,符合对象封装的思想。而且用这个方法来制作属性页就可以利用ClassWizard来轻松地生成消息映射处理Tab Control的消息了。例如:可以处理TCN_SELCHANGE消息来对切换了标签时进行一些动作。
      

  7.   

    看这个:
    http://www.vckbase.com/document/viewdoc.asp?id=398
      

  8.   

    //m_configTab是一个TabCtrl
    m_configTab.InsertItem(0,"System",0);
    m_configTab.InsertItem(1,"Color",1);
    m_configTab.InsertItem(2,"Others",2);// IMPORTANT: Tab pages should be created,IDD_SYSCONFIG is Dialog
    //m_dlgSysConfig,m_dlgColorConfig,m_dlgOtherConfig 是三个对话框窗口类,注意窗口应为Child类型。
    m_dlgSysConfig.Create(IDD_SYSCONFIG, &m_configTab);  m_dlgColorConfig.Create(IDD_COLORCONFIG, &m_configTab);
    m_dlgOtherConfig.Create(IDD_OTHERCONFIG, &m_configTab);

    m_dlgSysConfig.ShowWindow(SW_SHOW);
    m_dlgColorConfig.ShowWindow(SW_HIDE);
    m_dlgOtherConfig.ShowWindow(SW_HIDE);
      

  9.   

    m_configTab.GetClientRect(&tabRect);
    m_configTab.GetItemRect(0, &itemRect); nX=itemRect.left;
    nY=itemRect.bottom+1;
    nXc=tabRect.right;
    nYc=tabRect.bottom-nY-1;
    CRect rc(nX,nY,nXc,nYc);
    m_dlgSysConfig.MoveWindow(rc);
    m_dlgColorConfig.MoveWindow(rc);
    m_dlgOtherConfig.MoveWindow(rc);然后将三个对话框移动到tab内的位置