Vous êtes sur la page 1sur 20

Microsoft Foundation Classes

O modelo de Model/View/Controller nas MFC´s

CCISEL 2001 Advanced MFC 1 de 20


Application Framework

Document template

Model: Os dados - providenciam uma interface para consultas e alterações

View: Uma forma de visualizar os dados

Controller: Interface com o utilizador sobre uma View

Frame

O modelo SDI (Single Document Interface) Document

View

CCISEL 2001 Advanced MFC 2 de 20


Uma aplicação MDI simples (scribble)

CCISEL 2001 Advanced MFC 3 de 20


A aplicação Scribble

#include "resource.h" CScribbleApp theApp;


class CScribbleApp : public CWinApp { BOOL CScribbleApp::InitInstance() {
public:
virtual BOOL InitInstance(); // Register the application's document templates.
afx_msg void OnAppAbout(); CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(
DECLARE_MESSAGE_MAP() IDR_SCRIBBTYPE,
}; RUNTIME_CLASS(CScribbleDoc),
// custom MDI child frame
RUNTIME_CLASS(CChildFrame),
// custom MDI view
#include "stdafx.h" RUNTIME_CLASS(CScribbleView));
#include "Scribble.h" AddDocTemplate(pDocTemplate);
#include "MainFrm.h"
#include "ChildFrm.h" // create main MDI Frame window
#include "ScribDoc.h" CMainFrame* pMainFrame = new CMainFrame;
#include "ScribVw.h" if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
return FALSE;
BEGIN_MESSAGE_MAP(CScribbleApp, CWinApp) m_pMainWnd = pMainFrame;
ON_COMMAND(ID_APP_ABOUT, OnAppAbout) OnFileNew(); // Abrir uma frame filha inicial
pMainFrame->ShowWindow(m_nCmdShow);
// Standard file based document commands pMainFrame->UpdateWindow();
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) return TRUE;
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) }
END_MESSAGE_MAP()

CCISEL 2001 Advanced MFC 4 de 20


Especialização de vector da biblioteca STL com serialização MFC

template <class T>


class MFCVector : public std::vector<T> {
public:
void Serialize(CArchive &ar) {
int vSize;
if (ar.IsStoring()) {

vSize = size();
ar << vSize;
for (iterator it = begin(); it != end(); ++it)
ar << *it;
}
else {
clear();
ar >> vSize;
reserve(vSize*2);
for (int i= 0; i < vSize; ++i) {
T val;
ar >> val;
push_back(val);
}
}
}
};

CCISEL 2001 Advanced MFC 5 de 20


A classe documento (CScribbleDoc)

class CScribbleDoc : public CDocument {


// construção virtual
DECLARE_DYNCREATE(CScribbleDoc)
private:
UINT m_nPenWidth; // current user-selected pen width
CPen m_penCur; // pen created according
class CStroke : public CObject {
// user-selected pen style (width)
protected:
MFCVector <CStroke *> m_strokeList;
CStroke();
DECLARE_SERIAL(CStroke)
public:
CStroke* NewStroke();
protected:
typedef MFCVector<CStroke*>::iterator StrokeIterator;
UINT m_nPenWidth;
// one pen width applies to entire
// stroke
StrokeIterator beginIterator() { return m_strokeList.begin(); }
MFCVector <CPointt> m_pointArray; // series of points
StrokeIterator endIterator() { return m_strokeList.end(); }
CPen* GetCurrentPen() { return &m_penCur; }
public:
virtual BOOL OnNewDocument();
CStroke(UINT nPenWidth);
virtual void Serialize(CArchive& ar);
BOOL DrawStroke(CDC* pDC);
virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
void add(CPoint &point) { m_pointArray.push_back(point); }
virtual void DeleteContents();
virtual void Serialize(CArchive& ar);
protected:
};
void InitDocument();

};

CCISEL 2001 Advanced MFC 6 de 20


A classe CStroke (implementação)

IMPLEMENT_SERIAL(CStroke, CObject, 1)

CStroke::CStroke(UINT nPenWidth) { m_nPenWidth = nPenWidth; }

void CStroke::Serialize(CArchive& ar) {


if (ar.IsStoring()) {
ar << (WORD) m_nPenWidth;
m_pointArray.Serialize(ar);
}
else {
WORD w;
ar >> w;
m_nPenWidth = w;
m_pointArray.Serialize(ar);
}
}

BOOL CStroke::DrawStroke(CDC* pDC) {


CPen penStroke;
if (!penStroke.CreatePen(PS_SOLID, m_nPenWidth, RGB(0,0,0))) return FALSE;
CPen* pOldPen = pDC->SelectObject(&penStroke);
pDC->MoveTo(m_pointArray[0]);
for (int i=1; i < m_pointArray.GetSize(); i++) { pDC->LineTo(m_pointArray[i]); }
pDC->SelectObject(pOldPen);
return TRUE;
}

CCISEL 2001 Advanced MFC 7 de 20


A classe CScribbleDoc (implementação)
#include "stdafx.h"
#include "Scribble.h"
#include "ScribDoc.h"
IMPLEMENT_DYNCREATE(CScribbleDoc, CDocument)

BOOL CScribbleDoc::OnNewDocument() {
if (!CDocument::OnNewDocument()) return FALSE;
InitDocument();
return TRUE; void CScribbleDoc::InitDocument() {
} m_nPenWidth = 6; // default 2 pixel pen width, solid, black pen
m_penCur.CreatePen(PS_SOLID, m_nPenWidth, RGB(0,0,0));
void CScribbleDoc::Serialize(CArchive& ar) { m_strokeList.Serialize(ar);
} }

BOOL CScribbleDoc::OnOpenDocument(LPCTSTR lpszPathName) {


if (!CDocument::OnOpenDocument(lpszPathName)) return FALSE;
InitDocument();
return TRUE; CStroke* CScribbleDoc::NewStroke() {
} CStroke* pStrokeItem = new CStroke(m_nPenWidth);
m_strokeList.push_back(pStrokeItem);
void CScribbleDoc::DeleteContents() { SetModifiedFlag();
while (!m_strokeList.empty()) { // Mark the document as having been modified, for
CStroke *stroke = m_strokeList.front(); // purposes of confirming File Close.
m_strokeList.pop_front(); return pStrokeItem;
delete stroke;
} }
CDocument::DeleteContents();
}

CCISEL 2001 Advanced MFC 8 de 20


A classe que representa as frames filhas (CChildFrame)

class CChildFrame : public CMDIChildWnd {


DECLARE_DYNCREATE(CChildFrame)

};

#include "stdafx.h"
#include "Scribble.h"

#include "ChildFrm.h"

IMPLEMENT_DYNCREATE(CChildFrame,
CMDIChildWnd)

CCISEL 2001 Advanced MFC 9 de 20


A classe view ( CSCribbleView)

class CScribbleView : public CView {

DECLARE_DYNCREATE(CScribbleView)
private:
CStroke* m_pStrokeCur; // the stroke in progress
CPoint m_ptPrev; // the last mouse pt in the stroke in progress
public:
CScribbleDoc* GetDocument();

virtual void OnDraw(CDC* pDC); // overridden to draw this view

protected:

afx_msg void OnLButtonDown(UINT nFlags, CPoint point);


afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);

DECLARE_MESSAGE_MAP()
};

CCISEL 2001 Advanced MFC 10 de 20


A classe CScribbleView (implementação 1)

#include "stdafx.h"
#include "Scribble.h"
#include "ScribDoc.h"
#include "ScribVw.h"

IMPLEMENT_DYNCREATE(CScribbleView, CView)

BEGIN_MESSAGE_MAP(CScribbleView, CView)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()

void CScribbleView::OnDraw(CDC* pDC) {


CScribbleDoc* pDoc = GetDocument();
// The view delegates the drawing of individual strokes to CStroke::DrawStroke().
for ( CScribbleDoc::StrokeIterator it = pDoc->beginIterator(); it != pDoc->endIterator(); ++it) {
CStroke* pStroke = *it;
pStroke->DrawStroke(pDC, false);
}
}

CScribbleDoc* CScribbleView::GetDocument() {
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CScribbleDoc)));
return (CScribbleDoc*)m_pDocument;
}

CCISEL 2001 Advanced MFC 11 de 20


A classe CScribbleView (implementação 2)

void CScribbleView::OnLButtonDown(UINT, CPoint point)


m_pStrokeCur = GetDocument()->NewStroke();
m_pStrokeCur->add(point); SetCapture(); m_ptPrev = point; return;
}

void CScribbleView::OnLButtonUp(UINT, CPoint point) {


if (GetCapture() != this) return;
CScribbleDoc* pDoc = GetDocument();
CClientDC dc(this);
CPen* pOldPen = dc.SelectObject(pDoc->GetCurrentPen());

dc.MoveTo(m_ptPrev); dc.LineTo(point);
dc.SelectObject(pOldPen); m_pStrokeCur->add(point);
ReleaseCapture();
return;
}

void CScribbleView::OnMouseMove(UINT, CPoint point) {


if (GetCapture() != this) return;
CClientDC dc(this);
m_pStrokeCur->add(point);
CPen* pOldPen = dc.SelectObject(GetDocument()->GetCurrentPen());

dc.MoveTo(m_ptPrev); dc.LineTo(point); dc.SelectObject(pOldPen); m_ptPrev = point;


return;
}

CCISEL 2001 Advanced MFC 12 de 20


Métodos da classe CDocument

dView Attaches a view to the document.


tDocTemplate Returns a pointer to the document template that describes the type of the document.
tFirstViewPosition Returns the position of the first in the list of views; used to begin iteration.
tNextView Iterates through the list of views associated with the document.
tPathName Returns the path of the document’s data file.
tTitle Returns the document’s title.
Modified Indicates whether the document has been modified since it was last saved.
moveView Detaches a view from the document.
tModifiedFlag Sets a flag indicating that you have modified the document since it was last saved.
tPathName Sets the path of the data file used by the document.
tTitle Sets the document’s title.
dateAllViews Notifies all views that document has been modified.
verridables.
leteContents Called to perform cleanup of the document.
nChangedViewList Called after a view is added to or removed from the document.
nCloseDocument Called to close the document.
nNewDocument Called to create a new document.
nOpenDocument Called to open an existing document.
nSaveDocument Called to save the document to disk.

CCISEL 2001 Advanced MFC 13 de 20


CDocTemplate Class Members

SetContainerInfo Determines the resources for OLE containers when editing an in-place OLE item.
SetServerInfo Determines the resources and classes when the server document is embedded or edited in-place.

GetFirstDocPosition Retrieves the position of the first document associated with this template.
GetNextDoc Retrieves a document and the position of the next one.
LoadTemplate Loads the resources for a given CDocTemplate or derived class.
AddDocument Adds a document to a template.
RemoveDocument Removes a document from a template.
GetDocString Retrieves a string associated with the document type.
Overridables
MatchDocType Determines the degree of confidence in the match between a document type and this template.

CreateNewDocument Creates a new document.


CreateNewFrame Creates a new frame window containing a document and view.
InitialUpdateFrame Initializes the frame window, and optionally makes it visible.
SaveAllModified Saves all documents associated with this template which have been modified.
CloseAllDocuments Closes all documents associated with this template.
OpenDocumentFile Opens a file specified by a pathname.
SetDefaultTitle Displays the default title in the document window’s title bar.

CCISEL 2001 Advanced MFC 14 de 20


CView Class Members

GetDocument Returns the document associated with the view.

OnInitialUpdate Called after a view is first attached to a document.

Overridables

OnActivateView Called when a view is activated.

OnActivateFrame Called when the frame window containing the view is activated or deactivated.

OnBeginPrinting Called when a print job begins; override to allocate graphics device interface (GDI) resources.

OnDraw Called to render an image of the document for screen display, printing, or print preview.

Implementation required.

OnUpdate Called to notify a view that its document has been modified.

CCISEL 2001 Advanced MFC 15 de 20


A classe CObject
A classe CObject dá suporte à construção virtual, RTTI e serialização de
objectos.
As classes MFC que pretenderem estas caracteristicas terão de providenciar
uma instância de CRuntimeClass que contem toda a informação de runtime
necessária. Para simplificar o trabalho do programador, foram definidas um
conjunto de macros que dão independentemente cada um dos níveis de suporte
(por ordem de abrangência, RTTI, construção virtual e Serialização). Ver Slides
seguintes
Diagnostics

AssertValid Validates this object’s integrity.

Dump Produces a diagnostic dump of this object.

Serialization

IsSerializable Tests to see whether this object can be serialized.

Serialize Loads or stores an object from/to an archive.

Miscellaneous

GetRuntimeClass Returns the CRuntimeClass structure corresponding to this object’s class.

IsKindOf Tests this object’s relationship to a given class.

CCISEL 2001 Advanced MFC 16 de 20


A classe CRuntimeClass

struct CRuntimeClass {
// Attributes
LPCSTR m_lpszClassName;
int m_nObjectSize;
UINT m_wSchema; // schema number of the loaded class
CObject* (PASCAL* m_pfnCreateObject)(); // NULL => abstract class

CRuntimeClass* m_pBaseClass;

// Operations
CObject* CreateObject();
BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const;

// Implementation
void Store(CArchive& ar) const;
static CRuntimeClass* PASCAL Load(CArchive& ar, UINT* pwSchemaNum);

// CRuntimeClass objects linked together in simple list


CRuntimeClass* m_pNextClass;

};

CCISEL 2001 Advanced MFC 17 de 20


Macros para MFC rtti, construção virtual e serialização

DECLARE_DYNAMIC( class_name )
IMPLEMENT_DYNAMIC( class_name, base_class_name )

DECLARE_DYNCREATE( class_name )
IMPLEMENT_DYNCREATE( class_name, base_class_name )

DECLARE_SERIAL( class_name )
IMPLEMENT_SERIAL( class_name, base_class_name, wSchema )

CCISEL 2001 Advanced MFC 18 de 20


A classe CArchive

Close Flushes unwritten data and disconnects from the CFile.


Basic Input/Output
Flush Flushes unwritten data from the archive buffer.
operator >> Loads objects and primitive types from the archive.
operator << Stores objects and primitive types to the archive.
Read Reads raw bytes.
Write Writes raw bytes.
WriteString Writes a single line of text.
ReadString Reads a single line of text.
Status
GetFile Gets the CFile object pointer for this archive.
GetObjectSchema Called from the Serialize function to determine the version of the object that is being deserialized.
SetObjectSchema Sets the object schema stored in the archive object.
IsLoading Determines whether the archive is loading.
IsStoring Determines whether the archive is storing. .
Object Input/Output
ReadObject Calls an object’s Serialize function for loading.
WriteObject Calls an object’s Serialize function for storing.

CCISEL 2001 Advanced MFC 19 de 20


Macros para MFC rtti, construção virtual e serialização (definição)

#define _DECLARE_DYNAMIC(class_name) \
public: \
static AFX_DATA CRuntimeClass class##class_name; \
virtual CRuntimeClass* GetRuntimeClass() const;

#define DECLARE_DYNCREATE(class_name) \
DECLARE_DYNAMIC(class_name) \
static CObject* CreateObject();

#define DECLARE_SERIAL(class_name) \
DECLARE_DYNCREATE(class_name) \
AFX_API friend CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb);

#define IMPLEMENT_SERIAL(class_name, base_class_name, wSchema) \


CObject* PASCAL class_name::CreateObject() \
{ return new class_name; } \
_IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, \
class_name::CreateObject) \
AFX_CLASSINIT _init_##class_name(RUNTIME_CLASS(class_name)); \
CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb) \
{ pOb = (class_name*) ar.ReadObject(RUNTIME_CLASS(class_name)); \
return ar; }

CCISEL 2001 Advanced MFC 20 de 20

Vous aimerez peut-être aussi