我现在自定义一个CView类,我想把它加载到对话框中,如何实现,
程序基于对话框制作(动态加载),

解决方案 »

  1.   

    An alternative to the often asked view-in-dialog problem using a dialog bar
    By thom_as In this article I show an alternative to the tricky (and thus often unstable) attempts to create a view on a dialog.  
    http://www.codeproject.com/dialog/View_in_Dialog.asp
      

  2.   

    http://www.codeguru.com/dialog/vwindlg.html上的例子很好,很简单。而且有源码下载,祝你成功。
      

  3.   

    转摘
    // ==========================================
    // DialogViewManager.h - YangTze - 2001.09.13
    // ==========================================#if !defined(AFX_DIALOGVIEWMANAGER_H__C2BC5B6F_E22E_460A_96AE_DFA61B9D749C__INCLUDED_)
    #define AFX_DIALOGVIEWMANAGER_H__C2BC5B6F_E22E_460A_96AE_DFA61B9D749C__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    // DialogViewManager.h : header file
    //#include <afxtempl.h>/////////////////////////////////////////////////////////////////////////////
    // CDialogViewManager command targetclass CDialogViewManager : public CCmdTarget
    {
        DECLARE_DYNCREATE(CDialogViewManager)    CDialogViewManager();           // protected constructor used by dynamic creation// Attributes
    public:protected:    // Embeded type and structure
        typedef struct _DVMITEM
        {
            CView *pView;
        } DVMITEM,*PDVMITEM;
        typedef CMap<UINT,UINT,DVMITEM*,DVMITEM*> CMapID2DVMItem;    CMapID2DVMItem m_mapID2DVMItem;
        CDialog *m_pParentDialog;// Operations
    public:
        void RemoveAll(void);
        void DeleteView(CRuntimeClass *pViewClass);
        void DeleteView(UINT nIDRectangle);
        CView * GetView(CRuntimeClass *pViewClass);
        CView * GetView(UINT nIDRectangle);
        BOOL AddView(UINT nIDRectangle,CRuntimeClass *pViewClass);
        void UnInstall(void);
        void Install2Dialog(CDialog *pParentDialog);// Overrides
        // ClassWizard generated virtual function overrides
        //{{AFX_VIRTUAL(CDialogViewManager)
        //}}AFX_VIRTUAL// Implementation
    protected:#ifdef _DEBUG
        virtual void Dump(CDumpContext& dc) const;
        virtual void AssertValid() const;
    #endifpublic:
        virtual ~CDialogViewManager();    // Generated message map functions
        //{{AFX_MSG(CDialogViewManager)
            // NOTE - the ClassWizard will add and remove member functions here.
        //}}AFX_MSG    DECLARE_MESSAGE_MAP()
    };///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_DIALOGVIEWMANAGER_H__C2BC5B6F_E22E_460A_96AE_DFA61B9D749C__INCLUDED_)
    // ============================================
    // DialogViewManager.cpp - YangTze - 2001.09.13
    // ============================================#include "stdafx.h"
    #include <afxpriv.h>
    #include "DlgView.h"#include "DialogViewManager.h"#ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif/////////////////////////////////////////////////////////////////////////////
    // CDialogViewManagerIMPLEMENT_DYNCREATE(CDialogViewManager, CCmdTarget)CDialogViewManager::CDialogViewManager()
    {
        m_pParentDialog=NULL;
    }CDialogViewManager::~CDialogViewManager()
    {
        UnInstall();
    }
    BEGIN_MESSAGE_MAP(CDialogViewManager, CCmdTarget)
        //{{AFX_MSG_MAP(CDialogViewManager)
            // NOTE - the ClassWizard will add and remove mapping macros here.
        //}}AFX_MSG_MAP
    END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
    // CDialogViewManager message handlersvoid CDialogViewManager::Install2Dialog(CDialog *pParentDialog)
    {
        ASSERT(pParentDialog);
        ASSERT(::IsWindow(pParentDialog->GetSafeHwnd()));
        m_pParentDialog=pParentDialog;
    }void CDialogViewManager::UnInstall()
    {
        RemoveAll();
        m_pParentDialog=NULL;
    }BOOL CDialogViewManager::AddView(UINT nIDRectangle, CRuntimeClass *pViewClass)
    {
        BOOL bSuccess=FALSE;
        DVMITEM *pdvmi;
        if(m_mapID2DVMItem.Lookup(nIDRectangle,pdvmi)||(!m_pParentDialog)||(!::IsWindow(m_pParentDialog->GetSafeHwnd())))
        {
        }
        else
        {
            ASSERT_VALID_IDR(nIDRectangle);
            ASSERT(pViewClass!=NULL||pViewClass->IsDerivedFrom(RUNTIME_CLASS(CView)));
            ASSERT(m_pParentDialog!=NULL);
            CWnd *pWnd=NULL;
            CCreateContext *pContext=new CCreateContext;
            if(pContext)
            {
                pContext->m_pNewViewClass=pViewClass;
                pContext->m_pCurrentDoc=NULL;
                pContext->m_pCurrentFrame=NULL;
                pContext->m_pLastView=NULL;
                pContext->m_pNewDocTemplate=NULL;
                try
                {
                    pWnd=DYNAMIC_DOWNCAST(CWnd,pViewClass->CreateObject());
                    if(!pWnd) AfxThrowUserException();
                    ASSERT_KINDOF(CWnd,pWnd);
                    ASSERT(pWnd->m_hWnd==NULL);
                    CWnd *pCtrl=m_pParentDialog->GetDlgItem(nIDRectangle);
                    ASSERT(pCtrl);
                    pCtrl->ShowWindow(SW_HIDE);
                    CRect rect;
                    pCtrl->GetWindowRect(&rect);
                    m_pParentDialog->ScreenToClient(&rect);
                    pWnd->Create(NULL,NULL,AFX_WS_DEFAULT_VIEW,CRect(0,0,0,0),m_pParentDialog,0,pContext);
                    CView *pView=DYNAMIC_DOWNCAST(CView,pWnd);
                    ASSERT_KINDOF(CView,pView);
                    pView->MoveWindow(&rect);
                    DVMITEM *pdvmi=new DVMITEM;
                    pdvmi->pView=pView;
                    m_mapID2DVMItem[nIDRectangle]=pdvmi;
                    bSuccess=TRUE;
                }
                catch(...)
                {
                    TRACE1("Can not create a view in dialog( %d ).\n",m_pParentDialog);
                }
            }
            if(pContext) delete pContext;
        }
        return bSuccess;
    }CView * CDialogViewManager::GetView(UINT nIDRectangle)
    {
        ASSERT_VALID(this);
        UINT nID;
        DVMITEM *pdvmi;
        POSITION pos=m_mapID2DVMItem.GetStartPosition();
        while(pos)
        {
            m_mapID2DVMItem.GetNextAssoc(pos,nID,pdvmi);
            if(nID==nIDRectangle)
            {
                return pdvmi->pView;
            }
        }
        return NULL;
    }
      

  4.   

    CView * CDialogViewManager::GetView(CRuntimeClass *pViewClass)
    {
        ASSERT_VALID(this);
        UINT nID;
        DVMITEM *pdvmi;
        POSITION pos=m_mapID2DVMItem.GetStartPosition();
        while(pos)
        {
            m_mapID2DVMItem.GetNextAssoc(pos,nID,pdvmi);
            if(pdvmi->pView->IsKindOf(pViewClass))
            {
                return pdvmi->pView;
            }
        }
        return NULL;
    }void CDialogViewManager::DeleteView(UINT nIDRectangle)
    {
        ASSERT_VALID(this);
        UINT nID;
        DVMITEM *pdvmi;
        POSITION pos=m_mapID2DVMItem.GetStartPosition();
        while(pos)
        {
            m_mapID2DVMItem.GetNextAssoc(pos,nID,pdvmi);
            if(nID==nIDRectangle)
            {
                ASSERT(pdvmi->pView);
                ASSERT_VALID(pdvmi->pView);
                ASSERT(::IsWindow(pdvmi->pView->m_hWnd));
                pdvmi->pView->ShowWindow(SW_HIDE);
                pdvmi->pView->SendMessage(WM_CLOSE,0,0);
                m_mapID2DVMItem.RemoveKey(nID);
                delete pdvmi;
            }
        }
    }void CDialogViewManager::DeleteView(CRuntimeClass *pViewClass)
    {
        ASSERT_VALID(this);
        UINT nID;
        DVMITEM *pdvmi;
        POSITION pos=m_mapID2DVMItem.GetStartPosition();
        while(pos)
        {
            m_mapID2DVMItem.GetNextAssoc(pos,nID,pdvmi);
            if(pdvmi->pView->IsKindOf(pViewClass))
            {
                ASSERT(pdvmi->pView);
                ASSERT_VALID(pdvmi->pView);
                ASSERT(::IsWindow(pdvmi->pView->m_hWnd));
                pdvmi->pView->ShowWindow(SW_HIDE);
                pdvmi->pView->SendMessage(WM_CLOSE,0,0);
                m_mapID2DVMItem.RemoveKey(nID);
                delete pdvmi;
            }
        }
    }void CDialogViewManager::RemoveAll()
    {
        ASSERT_VALID(this);
        UINT nID;
        DVMITEM *pdvmi;
        POSITION pos=m_mapID2DVMItem.GetStartPosition();
        while(pos)
        {
            m_mapID2DVMItem.GetNextAssoc(pos,nID,pdvmi);
            ASSERT(pdvmi->pView);
            if(::IsWindow(pdvmi->pView->m_hWnd))
            {
                pdvmi->pView->ShowWindow(SW_HIDE);
                pdvmi->pView->SendMessage(WM_CLOSE,0,0);
            }
            m_mapID2DVMItem.RemoveKey(nID);
            delete pdvmi;
        }
    }#ifdef _DEBUG
    void CDialogViewManager::AssertValid() const
    {
        CCmdTarget::AssertValid();
    }void CDialogViewManager::Dump(CDumpContext &dc) const
    {
        CCmdTarget::Dump(dc);
    }
    #endif
    // DlgViewDlg.cpp : implementation file
    //#include "stdafx.h"
    #include "DlgView.h"
    #include "DlgViewDlg.h"#include <afxhtml.h>
    #include "DialogViewManager.h"#ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif/////////////////////////////////////////////////////////////////////////////
    // CAboutDlg dialog used for App Aboutclass CAboutDlg : public CDialog
    {
    public:
        CAboutDlg();// Dialog Data
        //{{AFX_DATA(CAboutDlg)
        enum { IDD = IDD_ABOUTBOX };
        //}}AFX_DATA    // ClassWizard generated virtual function overrides
        //{{AFX_VIRTUAL(CAboutDlg)
        protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
        //}}AFX_VIRTUAL// Implementation
    protected:
        //{{AFX_MSG(CAboutDlg)
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
    };CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
    {
        //{{AFX_DATA_INIT(CAboutDlg)
        //}}AFX_DATA_INIT
    }void CAboutDlg::DoDataExchange(CDataExchange* pDX)
    {
        CDialog::DoDataExchange(pDX);
        //{{AFX_DATA_MAP(CAboutDlg)
        //}}AFX_DATA_MAP
    }BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
        //{{AFX_MSG_MAP(CAboutDlg)
            // No message handlers
        //}}AFX_MSG_MAP
    END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
    // CDlgViewDlg dialogCDlgViewDlg::CDlgViewDlg(CWnd* pParent /*=NULL*/)
        : CDialog(CDlgViewDlg::IDD, pParent)
    {
        //{{AFX_DATA_INIT(CDlgViewDlg)
            // NOTE: the ClassWizard will add member initialization here
        //}}AFX_DATA_INIT
        // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
        m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }void CDlgViewDlg::DoDataExchange(CDataExchange* pDX)
    {
        CDialog::DoDataExchange(pDX);
        //{{AFX_DATA_MAP(CDlgViewDlg)
            // NOTE: the ClassWizard will add DDX and DDV calls here
        //}}AFX_DATA_MAP
    }BEGIN_MESSAGE_MAP(CDlgViewDlg, CDialog)
        //{{AFX_MSG_MAP(CDlgViewDlg)
        ON_WM_SYSCOMMAND()
        ON_WM_PAINT()
        ON_WM_QUERYDRAGICON()
        //}}AFX_MSG_MAP
    END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
    // CDlgViewDlg message handlers
      

  5.   

    BOOL CDlgViewDlg::OnInitDialog()
    {
        CDialog::OnInitDialog();    // Add "About..." menu item to system menu.    // IDM_ABOUTBOX must be in the system command range.
        ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
        ASSERT(IDM_ABOUTBOX < 0xF000);    CMenu* pSysMenu = GetSystemMenu(FALSE);
        if (pSysMenu != NULL)
        {
            CString strAboutMenu;
            strAboutMenu.LoadString(IDS_ABOUTBOX);
            if (!strAboutMenu.IsEmpty())
            {
                pSysMenu->AppendMenu(MF_SEPARATOR);
                pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
            }
        }    // Set the icon for this dialog.  The framework does this automatically
        //  when the application's main window is not a dialog
        SetIcon(m_hIcon, TRUE);            // Set big icon
        SetIcon(m_hIcon, FALSE);        // Set small icon
        
        // TODO: Add extra initialization here
        static CDialogViewManager manager;
        manager.Install2Dialog(this);
        VERIFY(manager.AddView(IDC_STATIC_AREA,RUNTIME_CLASS(CHtmlView)));
        CHtmlView *pHtmlView=DYNAMIC_DOWNCAST(CHtmlView,manager.GetView(IDC_STATIC_AREA));
        pHtmlView->Navigate2("D:\\YangTze\\VC\\DlgView\\Debug\\demo.htm",NULL,NULL);    return TRUE;  // return TRUE  unless you set the focus to a control
    }void CDlgViewDlg::OnSysCommand(UINT nID, LPARAM lParam)
    {
        if ((nID & 0xFFF0) == IDM_ABOUTBOX)
        {
            CAboutDlg dlgAbout;
            dlgAbout.DoModal();
        }
        else
        {
            CDialog::OnSysCommand(nID, lParam);
        }
    }// If you add a minimize button to your dialog, you will need the code below
    //  to draw the icon.  For MFC applications using the document/view model,
    //  this is automatically done for you by the framework.void CDlgViewDlg::OnPaint() 
    {
        if (IsIconic())
        {
            CPaintDC dc(this); // device context for painting        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);        // Center icon in client rectangle
            int cxIcon = GetSystemMetrics(SM_CXICON);
            int cyIcon = GetSystemMetrics(SM_CYICON);
            CRect rect;
            GetClientRect(&rect);
            int x = (rect.Width() - cxIcon + 1) / 2;
            int y = (rect.Height() - cyIcon + 1) / 2;        // Draw the icon
            dc.DrawIcon(x, y, m_hIcon);
        }
        else
        {
            CDialog::OnPaint();
        }
    }// The system calls this to obtain the cursor to display while the user drags
    //  the minimized window.
    HCURSOR CDlgViewDlg::OnQueryDragIcon()
    {
        return (HCURSOR) m_hIcon;
    }// DlgViewDlg.h : header file
    //#if !defined(AFX_DLGVIEWDLG_H__BC744FD5_492C_47EA_BAE6_C01295EB3432__INCLUDED_)
    #define AFX_DLGVIEWDLG_H__BC744FD5_492C_47EA_BAE6_C01295EB3432__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000/////////////////////////////////////////////////////////////////////////////
    // CDlgViewDlg dialogclass CDlgViewDlg : public CDialog
    {
    // Construction
    public:
        CDlgViewDlg(CWnd* pParent = NULL);    // standard constructor// Dialog Data
        //{{AFX_DATA(CDlgViewDlg)
        enum { IDD = IDD_DLGVIEW_DIALOG };
            // NOTE: the ClassWizard will add data members here
        //}}AFX_DATA    // ClassWizard generated virtual function overrides
        //{{AFX_VIRTUAL(CDlgViewDlg)
        protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
        //}}AFX_VIRTUAL// Implementation
    protected:
        HICON m_hIcon;    // Generated message map functions
        //{{AFX_MSG(CDlgViewDlg)
        virtual BOOL OnInitDialog();
        afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
        afx_msg void OnPaint();
        afx_msg HCURSOR OnQueryDragIcon();
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
    };//{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_DLGVIEWDLG_H__BC744FD5_492C_47EA_BAE6_C01295EB3432__INCLUDED_)其实用CWnd类取代不好吗?