C ++ MFC MDI视图渲染

时间:2012-10-31 16:46:08

标签: c++ mfc render document mdi

在我的应用程序中,我目前有2种文档类型。我将关注的那个,将是第二个。我的应用程序是一个3d引擎编辑器,它是在MFC MDI中构建的。第一个文档是渲染窗口,它工作得很完美,因为它很容易提取它的hwnd,然后将它发送到我的图形类。但我的第二个窗口,即脚本编写,(现在)只是为了进行丰富的编辑。但由于某种原因,它不会呈现(实际上它只是,但只有一次:/)。

CEditorScriptView.h

#pragma once

#include "CEditorDoc.h"
class CCEditorCntrItem;

class CCEditorScriptView : public CView
{
public: // create from serialization only
    CCEditorScriptView();
    DECLARE_DYNCREATE(CCEditorScriptView)

// Attributes
public:
    CCEditorDoc* GetDocument() const;
    static CCEditorScriptView * GetView();
    // m_pSelection holds the selection to the current CCEditorCntrItem.
    // For many applications, such a member variable isn't adequate to
    //  represent a selection, such as a multiple selection or a selection
    //  of objects that are not CCEditorCntrItem objects.  This selection
    //  mechanism is provided just to help you get started

    // TODO: replace this selection mechanism with one appropriate to your app
    CCEditorCntrItem* m_pSelection;
    CRichEditCtrl* m_rEdit;

    int  TYPE;

// Operations
public:

// Overrides
public:
    virtual void OnDraw(CDC* pDC);  // overridden to draw this view
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
    virtual void OnInitialUpdate(); // called first time after construct
    virtual BOOL IsSelected(const CObject* pDocItem) const;// Container support

// Implementation
public:
    virtual ~CCEditorScriptView();
#ifdef _DEBUG
    virtual void AssertValid() const;
    virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// Generated message map functions
protected:
    afx_msg void OnDestroy();
    afx_msg void OnSetFocus(CWnd* pOldWnd);
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg void OnInsertObject();
    afx_msg void OnCancelEditCntr();
    afx_msg void OnFilePrint();
    afx_msg void OnFilePrintPreview();
    afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
    afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
    DECLARE_MESSAGE_MAP()
};

#ifndef _DEBUG  // debug version in CEditorView.cpp
inline CCEditorDoc* CCEditorScriptView::GetDocument() const
   { return reinterpret_cast<CCEditorDoc*>(m_pDocument); }
#endif

CEditorScriptView.cpp:

#include "stdafx.h"
// SHARED_HANDLERS can be defined in an ATL project implementing preview, thumbnail
// and search filter handlers and allows sharing of document code with that project.
#ifndef SHARED_HANDLERS
#include "CEditor.h"
#endif

#include "CEditorDoc.h"
#include "CntrItem.h"
#include "resource.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CCEditorView

#pragma region CCEditorScriptView

IMPLEMENT_DYNCREATE(CCEditorScriptView, CView)

BEGIN_MESSAGE_MAP(CCEditorScriptView, CView)
    ON_WM_DESTROY()
    ON_WM_SETFOCUS()
    ON_WM_SIZE()
    ON_COMMAND(ID_OLE_INSERT_NEW, &CCEditorScriptView::OnInsertObject)
    ON_COMMAND(ID_CANCEL_EDIT_CNTR, &CCEditorScriptView::OnCancelEditCntr)
    ON_COMMAND(ID_FILE_PRINT, &CCEditorScriptView::OnFilePrint)
    ON_WM_CONTEXTMENU()
    ON_WM_RBUTTONUP()
END_MESSAGE_MAP()

// CCEditorView construction/destruction

CCEditorScriptView::CCEditorScriptView()
{
    EnableActiveAccessibility();
    m_pSelection = NULL;
    // TODO: add construction code here

    m_rEdit->Create(WS_CHILD|WS_VISIBLE|WS_BORDER|ES_MULTILINE,
                    CRect(10,10,500,500), this, 1);

    //m_rEdit->SetFocus();

    TYPE = ID_CEDITOR_VIEW_SCRIPT;
}

CCEditorScriptView::~CCEditorScriptView()
{
}

BOOL CCEditorScriptView::PreCreateWindow(CREATESTRUCT& cs)
{
    // TODO: Modify the Window class or styles here by modifying
    //  the CREATESTRUCT cs

    return CView::PreCreateWindow(cs);
}

// CCEditorView drawing

void CCEditorScriptView::OnDraw(CDC* pDC)
{
    if (!pDC)
        return;

    CCEditorDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    // TODO: add draw code for native data here
    // TODO: also draw all OLE items in the document

    // Draw the selection at an arbitrary position.  This code should be
    //  removed once your real drawing code is implemented.  This position
    //  corresponds exactly to the rectangle returned by CCEditorCntrItem,
    //  to give the effect of in-place editing.

    // TODO: remove this code when final draw code is complete.

    m_rEdit->UpdateWindow();

    if (m_pSelection != NULL)
    {
        CSize size;
        CRect rect(10, 10, 210, 210);

        if (m_pSelection->GetExtent(&size, m_pSelection->m_nDrawAspect))
        {
            pDC->HIMETRICtoLP(&size);
            rect.right = size.cx + 10;
            rect.bottom = size.cy + 10;
        }
        m_pSelection->Draw(pDC, rect);
    }
}

// MDI view implementation file
CCEditorScriptView * CCEditorScriptView::GetView()
{
    CMDIChildWnd * pChild =
        ((CMDIFrameWnd*)(AfxGetApp()->m_pMainWnd))->MDIGetActive();

    if ( !pChild )
        return NULL;

    CView * pView = pChild->GetActiveView();

    if ( !pView )
        return NULL;

    // Fail if view is of wrong kind
    /*if ( ! pView->IsKindOf( RUNTIME_CLASS(CCEditorRenderView) ) )
        return NULL;*/

    return (CCEditorScriptView *) pView;
}

void CCEditorScriptView::OnInitialUpdate()
{
    CView::OnInitialUpdate();

    // TODO: remove this code when final selection model code is written
    m_pSelection = NULL;    // initialize selection
}

void CCEditorScriptView::OnDestroy()
{
    // Deactivate the item on destruction; this is important
    // when a splitter view is being used
   COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
   if (pActiveItem != NULL && pActiveItem->GetActiveView() == this)
   {
      pActiveItem->Deactivate();
      ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
   }
   CView::OnDestroy();
}

// OLE Client support and commands

BOOL CCEditorScriptView::IsSelected(const CObject* pDocItem) const
{
    // The implementation below is adequate if your selection consists of
    //  only CCEditorCntrItem objects.  To handle different selection
    //  mechanisms, the implementation here should be replaced

    // TODO: implement this function that tests for a selected OLE client item

    return pDocItem == m_pSelection;
}

void CCEditorScriptView::OnInsertObject()
{
    // Invoke the standard Insert Object dialog box to obtain information
    //  for new CCEditorCntrItem object
    COleInsertDialog dlg;
    if (dlg.DoModal() != IDOK)
        return;

    BeginWaitCursor();

    CCEditorCntrItem* pItem = NULL;
    TRY
    {
        // Create new item connected to this document
        CCEditorDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);
        pItem = new CCEditorCntrItem(pDoc);
        ASSERT_VALID(pItem);

        // Initialize the item from the dialog data
        if (!dlg.CreateItem(pItem))
            AfxThrowMemoryException();  // any exception will do
        ASSERT_VALID(pItem);

        if (dlg.GetSelectionType() == COleInsertDialog::createNewItem)
            pItem->DoVerb(OLEIVERB_SHOW, this);

        ASSERT_VALID(pItem);
        // As an arbitrary user interface design, this sets the selection
        //  to the last item inserted

        // TODO: reimplement selection as appropriate for your application
        m_pSelection = pItem;   // set selection to last inserted item
        pDoc->UpdateAllViews(NULL);
    }
    CATCH(CException, e)
    {
        if (pItem != NULL)
        {
            ASSERT_VALID(pItem);
            pItem->Delete();
        }
        AfxMessageBox(IDP_FAILED_TO_CREATE);
    }
    END_CATCH

    EndWaitCursor();
}

// The following command handler provides the standard keyboard
//  user interface to cancel an in-place editing session.  Here,
//  the container (not the server) causes the deactivation
void CCEditorScriptView::OnCancelEditCntr()
{
    // Close any in-place active item on this view.
    COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
    if (pActiveItem != NULL)
    {
        pActiveItem->Close();
    }
    ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
}

// Special handling of OnSetFocus and OnSize are required for a container
//  when an object is being edited in-place
void CCEditorScriptView::OnSetFocus(CWnd* pOldWnd)
{
    COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
    if (pActiveItem != NULL &&
        pActiveItem->GetItemState() == COleClientItem::activeUIState)
    {
        // need to set focus to this item if it is in the same view
        CWnd* pWnd = pActiveItem->GetInPlaceWindow();
        if (pWnd != NULL)
        {
            pWnd->SetFocus();   // don't call the base class
            return;
        }
    }

    CView::OnSetFocus(pOldWnd);
}

void CCEditorScriptView::OnSize(UINT nType, int cx, int cy)
{
    CView::OnSize(nType, cx, cy);
    COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
    if (pActiveItem != NULL)
        pActiveItem->SetItemRects();
}

void CCEditorScriptView::OnFilePrint()
{
    //By default, we ask the Active document to print itself
    //using IOleCommandTarget. If you don't want this behavior
    //remove the call to COleDocObjectItem::DoDefaultPrinting.
    //If the call fails for some reason, we will try printing
    //the docobject using the IPrint interface.
    CPrintInfo printInfo;
    ASSERT(printInfo.m_pPD != NULL); 
    if (S_OK == COleDocObjectItem::DoDefaultPrinting(this, &printInfo))
        return;

    CView::OnFilePrint();

}


void CCEditorScriptView::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
    ClientToScreen(&point);
    OnContextMenu(this, point);
}

void CCEditorScriptView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
    theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}

// CCEditorView diagnostics

#ifdef _DEBUG
void CCEditorScriptView::AssertValid() const
{
    CView::AssertValid();
}

void CCEditorScriptView::Dump(CDumpContext& dc) const
{
    CView::Dump(dc);
}

CCEditorDoc* CCEditorScriptView::GetDocument() const // non-debug version is inline
{
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CCEditorDoc)));
    return (CCEditorDoc*)m_pDocument;
}
#pragma endregion
#endif //_DEBUG


// CCEditorView message handlers

目前这是它的输出:

enter image description here

现在似乎没问题,但它只渲染一次,这意味着如果我点击它(richEdit)什么都不会发生,或者如果我试图输入richEdit,也不会发生任何事情。所以我想知道,为什么?为什么不继续渲染或更新视图?

谢谢

PS。如果你不想发布任何内容,比如代码,请发表评论。

1 个答案:

答案 0 :(得分:3)

所以,似乎我已经解决了我的问题,这是解决方案:

我看着控制台,注意到窗口无法创建。我找到了m_rEdit是错误的解决方案(通过测试)。所以我发现我必须在构造函数中初始化指针,并在OnInitialUpdate()中使用m_rEdit-&gt; Create。并修复了它。

无论如何,感谢任何试图解开这个谜团的人。