文档结构为单文档,现想动态生成一个CForm的视图类,高手请请教!

解决方案 »

  1.   

    SDI的MainFrame的OnCreate中动态创建一FormView: CRuntimeClass* pRC = RUNTIME_CLASS(CViewClients);
     CViewClients*  m_wndViewClients = (CViewClients*)pRC->CreateObject();       
     m_wndViewClients->Create(NULL,NULL,AFX_WS_DEFAULT_VIEW, CRect(0,0,0,0),  this, AFX_IDW_PANE_FIRST, NULL);
      

  2.   

    但是这样做会出错C:\Documents and Settings\Administrator\桌面\fz20031\MainFrm.cpp(103) : error C2248: 'Create' : cannot access protected member declared in class 'CFormView'
       c:\program files\microsoft visual studio\vc98\mfc\include\afxext.h(756) : see declaration of 'Create'
      

  3.   


         把派生于CFormView的CViewClients类的protected构造函数改为public即可。
      

  4.   

    你直接把        CRuntimeClass* pRC = RUNTIME_CLASS(CViewClients);
          CViewClients*  m_wndViewClients = (CViewClients*)pRC->CreateObject();  句改成:      CViewClients*  m_wndViewClients = new  CViewClients;
          构造函数还是 public 。   试一试。
      

  5.   

    哈哈,我试了一下:终于找到你同样的错误。
       改为:
       CView*  m_wndViewClients = new  CViewClients;     再Create必定成功。   通过父类指针的虚调用机制,即可正确调用到该protected member。   你要理解实际发生的事情:
       CViewClients  public  CFormView public CView public CWnd   
       CWnd 的 Create是public virtual function,所以这里m_wndViewClients->Create(...)
       是调用的是public的CWnd::Create(...),但由于该函数是
       virtual function,于是进行运行时对象判别,发现是一个派生类CFormView对象,于是调 
       用CFormView::Create(...),如果你在CViewClients中重载该
       virtual function,它同样调用CViewClients::Create(...),即使它是protected。   多查查MSDN。看一下MFC的源文件。   
       
      

  6.   

    谢谢啦。
    我昨天已经这样改了,运行成功,但是出现了一个更奇怪的事情。当显示先建的那个视图(现在基类为CView)时,视图中什么也没有,我已经在DRAW函数中添加了一些代码,但是没有显示。
      

  7.   

    可能原因:
      1.view  Create时显式调用OnInitialUpdate()没有。
      2.view  显示时有没有设定失效区Invalidate() ,InvalidateRect
      3.view  的坐标映射方式。
      

  8.   

    我现在急着要完成这个项目.谁帮我看看.分数好说.
    //这是在APP中动态创建一个CView的视图.开始的视图基于CFormView.
    CView *pActiveView=((CFrameWnd *)m_pMainWnd)->GetActiveView();
    m_pOldView=pActiveView;
    m_pNewView=(CView *)new CDialogRecordShow;
    CDocument* pCurrentDoc=((CFrameWnd *)m_pMainWnd)->GetActiveDocument();
    CCreateContext newContext;
    newContext.m_pNewViewClass=NULL;
    newContext.m_pNewDocTemplate=NULL;
    newContext.m_pLastView=NULL;
    newContext.m_pCurrentFrame=NULL;
    newContext.m_pCurrentDoc=pCurrentDoc; UINT viewID=AFX_IDW_PANE_FIRST+1;
    CRect rect(0,0,0,0);
    m_pNewView->Create(NULL,"AnyWindowName",WS_CHILD,rect,m_pMainWnd,viewID,&newContext);
    m_pNewView->SendMessage(WM_INITIALUPDATE,0,0);
    //视图切换函数
    CView * CFz2003App::SwitchView()
    {
        CView * pActiveView=((CFrameWnd *)m_pMainWnd)->GetActiveView();
    CView * pNewView =NULL;
    if(pActiveView==m_pOldView)
    pNewView=m_pNewView;
    else
    pNewView=m_pOldView;
    UINT temp=::GetWindowLong(pActiveView->m_hWnd,GWL_ID);
    ::SetWindowLong(pActiveView->m_hWnd,GWL_ID,::GetWindowLong(pNewView->m_hWnd,GWL_ID));
    ::SetWindowLong(pActiveView->m_hWnd,GWL_ID,temp);
    pActiveView->ShowWindow(SW_HIDE);
    pNewView->ShowWindow(SW_SHOW);
    //m_pNewView->OnInitialUpdate();
    ((CFrameWnd *)m_pMainWnd)->SetActiveView(pNewView);
    ((CFrameWnd *)m_pMainWnd)->RecalcLayout();
    pNewView->Invalidate();
    //((CFrameWnd *)m_pMainWnd)->UpdateWindow();
    return pActiveView;}

    void CFz2003App::OnShow() 
    {
        SwitchView();
    // TODO: Add your command handler code here

    }
      

  9.   

    pNewView  show  之前需加上:
             
    pNewView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);