Dans mon application, j'ai actuellement 2 types de documents. Celui sur lequel je vais me concentrer sera le second. Mon application est un éditeur de moteur 3D, qui est construit dans MFC MDI. Le premier document est la fenêtre de rendu, qui fonctionne parfaitement, car il est simple d'en extraire le hwnd, puis de l'envoyer à ma classe graphique. Mais ma deuxième fenêtre, qui est script, est supposée (pour l'instant) juste pour avoir un montage riche. Mais pour une raison quelconque, il ne rend pas (en fait c'est le cas, mais seulement une fois: /).C++ MFC MDI Voir le rendu
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
C'est actuellement ce qu'il génère:
semble maintenant est ok, mais il ne le rend une fois, ce qui signifie que je cliquerais dessus (richEdit) n Rien ne se passerait, ou si j'essayais de taper dans le RichEdit, rien ne se passerait aussi bien. Alors je me demande, pourquoi? Pourquoi ne continue-t-il pas à rendre ou à mettre à jour la vue?
Merci Vous
PS. Si vous ne voulez pas poster quoi que ce soit, comme le code, s'il vous plaît commenter.