我在做一个Splitter分隔的单文档多视的SDI应用,分左右两栏,但右边可能是多个不同的视图,其中有两个FormView的主要功能都是数据录入,界面上大部分是相同的(包括几个Edit,一个ListCtrl,和增、删、改按钮),但也有一些不同的地方。请大家给个思路,谢谢:)

解决方案 »

  1.   

    建立2个不同的CFormView派生类,然后动态创建,参考:
    http://www.czvc.com/down.asp?id=10
      

  2.   

    这是基本的代码,CMyFormView1,CMyFormView1是两个CFormView的派生类,构造函数改为Public即可
    BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) 
    { CRect rect;
    GetClientRect(&rect);
    //第一层
    if (!m_wndSplitter.CreateStatic(this, 1, 2))
    {
    return FALSE;
    }
    if (!m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CLeftView), 
    CSize(60, rect.Height()), pContext))
    {
    return FALSE;
    } if (!m_wndSplitter.CreateView(0, 1,
    RUNTIME_CLASS(CSubFrame), CSize(rect.Width()-PANEL_WIDTH, 150), pContext))
    {
    return FALSE;
    } m_pLeftView= (CLeftView* )m_wndSplitter.GetPane(0,0);
             m_pSubFrame = (CSubFrame* )m_wndSplitter.GetPane(0,1);
    return TRUE;}
    ......
    subFrame.h
    class CSubFrame : public CFrameWnd
    {
    DECLARE_DYNCREATE(CSubFrame)
    protected:
    CSubFrame();           // protected constructor used by dynamic creation// Attributes
    public: CMyFormView1   *m_pView1; 
    CMyFormView2   *m_pView2; 
    UINT m_nCurrentViewID; //手工标记的活动视图
    void SwitchToView(UINT nView);// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CSubFrame)
    protected:
    virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
    //}}AFX_VIRTUAL// Implementation
    protected:
    virtual ~CSubFrame(); // Generated message map functions
    //{{AFX_MSG(CSubFrame) //}}AFX_MSG
    public: DECLARE_MESSAGE_MAP()
    };
    sbuframe.cpp
    ......MPLEMENT_DYNCREATE(CSubFrame, CFrameWnd)CSubFrame::CSubFrame()
    {}CSubFrame::~CSubFrame()
    {
    }
    BEGIN_MESSAGE_MAP(CSubFrame, CFrameWnd)
    //{{AFX_MSG_MAP(CSubFrame)
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
    // CSubFrame message handlersBOOL CSubFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) 
    { m_pView1 = new CMyFormView1;
    ((CView*)m_pView1)->Create(NULL, NULL, 0L, CFrameWnd::rectDefault, this, 1, pContext);
    SetActiveView(m_pView1);
    m_pView1->ShowWindow(SW_SHOW);
    m_pView1->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
    m_nCurrentViewID = 1; m_pView2 = new CMyFormView2;
    ((CView*) m_pView2)->Create(NULL, NULL, 0L, CFrameWnd::rectDefault, this, 2, pContext);
    m_pView2->ShowWindow(SW_HIDE);
    RecalcLayout();

    return TRUE;
    }void CSubFrame::SwitchToView(UINT nView)
    {
    CView* pOldActiveView = GetActiveView();
    CView* pNewActiveView = NULL;
    CMainFrame* pFrame = (CMainFrame* )AfxGetMainWnd();
    switch (nView)
    {
    case 1:
    pNewActiveView = (CView*)m_pView1;
    break;
    case 2:
    pNewActiveView = (CView*)mm_pView2;
    break;
    }
    if (pNewActiveView)
    {
    // don't switch when views are the same
    if (pOldActiveView != pNewActiveView)
    {
    SetActiveView(pNewActiveView);
    pNewActiveView->ShowWindow(SW_SHOW);
    pNewActiveView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
    if (pOldActiveView)
    {
    pOldActiveView->ShowWindow(SW_HIDE);
    pOldActiveView->SetDlgCtrlID(m_nCurrentViewID);
    }
    m_nCurrentViewID = nView;
    }
    RecalcLayout();
    }
    }
      

  3.   

    谢谢大家的回复。goodboyws(深夜不眠者) ,你这段代码非常不错:)
    不过对于右边视图类型比较多的情况,还是动态生成比较好一些。
    另外我觉得在视图Create后最好显式调用一下OnInitialUpdate(好像不会自动调用) :)---
    可能我前面没说清楚,我现在的问题不是创建动态分隔窗口,而是如何在两个FormView间共用一些资源模板及对应的代码。因为这两个FormView的主要功能都是数据录入,界面上大部分是相同的(包括几个Edit,一个ListCtrl,和增、删、改按钮)。谢谢大家:)
      

  4.   

    要看你具体的差别程度,可以用一个公用的对话框作为子窗口分别贴到两个View上,如果差别小,也可以用一个变量做标记,在OnInitialUpdate里处理差别
      

  5.   

    如果是在OnCreateClient创建视图, OnInitialUpdate是不需要调用的,因为CFrameWnd
    随后会产生调用
      

  6.   

    goodboyws(深夜不眠者) ,非常感谢,我用一个变量做标记,达到了我想要的效果:)
      

  7.   

    我本来想建一个CFormView的基类来实现一些共同的属性,但还是这种办法简单,在OnInitialUpdate里显示、隐藏一些控件即可。