Frame window

MFC frame base aplication or dialog base application creates a frame window by directly with new operator. Main window is assigned to a base i.e. class CWnd pointer and framework takes care rest of the things.

virtual BOOL InitInstance()
{
  m_pMainWnd = new CMyWnd();
  m_pMainWnd->ShowWindow(SW_SHOW);
  m_pMainWnd->UpdateWindow();
  return TRUE;
}

DOC/VIEW objects

Doc view application never creates a DOC, VIEW and FRAME object directly with new operator. Here framework takes runtime pointer RUNTIME_CLASS.

	CSingleDocTemplate* pDocTemplate;
	pDocTemplate = new CSingleDocTemplate(
		IDR_MAINFRAME,
		RUNTIME_CLASS(CMySDIDoc),
		RUNTIME_CLASS(CMainFrame),
		RUNTIME_CLASS(CMySDIView));
	AddDocTemplate(pDocTemplate);

CSingleDocTemplate constructor

Runtime class pointers are validated in runtime and saved in member variables in CDocTemplate.

	CDocTemplate::CDocTemplate(UINT nIDResource, CRuntimeClass* pDocClass,
	CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass)
{
	ASSERT_VALID_IDR(nIDResource);
	ASSERT(pDocClass == NULL ||
		pDocClass->IsDerivedFrom(RUNTIME_CLASS(CDocument)));
	ASSERT(pFrameClass == NULL ||
		pFrameClass->IsDerivedFrom(RUNTIME_CLASS(CFrameWnd)));
	ASSERT(pViewClass == NULL ||
		pViewClass->IsDerivedFrom(RUNTIME_CLASS(CView)));
	m_pDocClass = pDocClass;
	m_pFrameClass = pFrameClass;
	m_pViewClass = pViewClass;

}

CreateNewDocument call stack

Framework calls CreateNewDocument at New document event.

CMySDIDoc::CMySDIDoc()
CMySDIDoc::CreateObject()
CRuntimeClass::CreateObject()
CDocTemplate::CreateNewDocument()
CSingleDocTemplate::OpenDocumentFile()
CDocManager::OnFileNew()

CDocTemplate::CreateNewDocument

RUNTIME class is casted to base pointer i.e. CDocument and CreateObject() is called. CreateObject() function calls m_pfnCreateObject function pointer.


CDocument* CDocTemplate::CreateNewDocument()
{
	// default implementation constructs one from CRuntimeClass
	if (m_pDocClass == NULL)
	{
		TRACE0("Error: you must override CDocTemplate::CreateNewDocument.\n");
		ASSERT(FALSE);
		return NULL;
	}
	CDocument* pDocument = (CDocument*)m_pDocClass->CreateObject();
	
}

CRuntimeClass::CreateObject

CRuntimeClass uses base abstruct class CObject and calls function pointer which eventually calls the derived class CreateObject.

CObject* CRuntimeClass::CreateObject()
{
	if (m_pfnCreateObject == NULL)
	{
		TRACE(_T("Error: Trying to create object which is not ")
			  _T("DECLARE_DYNCREATE \nor DECLARE_SERIAL: %hs.\n"),
			m_lpszClassName);
		return NULL;
	}

	CObject* pObject = NULL;
	TRY
	{
		pObject = (*m_pfnCreateObject)();
	}
	END_TRY

	return pObject;
}

CreateObject and new call

Derived class implements this CreateObject() and calls new operator. CMySDIDoc defines our CreateObject() with IMPLEMENT_DYNCREATE() macro and thus new operator calls the constructor CMySDIDoc().

#define IMPLEMENT_DYNCREATE(class_name, base_class_name) \
	CObject* PASCAL class_name::CreateObject() \
		{ return new class_name; } 

Thus creation of DOC, View and Frame are all at runtime with dynamic function pointer. This RUNTIME class and DECLARE_DYNCREATE & IMPLEMENT_DYNCREATE makes all things.

About our authors: Team EQA

Further readings

Where is WinMain() function in MFC application ?

MFC hides WinMain in its framework and includes source file on WinMain(). This explains how framework calls global CWinApp::Initinstance() from entry WinMain.

What is the utility of CWinApp class?

This is constructed during global C++ objects are constructed and is already available when Windows calls the WinMain function, which is supplied by the ...

Basic steps in Win32 GUI Application with source code.

Define a custom Window class structure, Register the class name, CreateWindow, Show windows and write message get and dispatch loop statements. Define the Window CallBack procedure and write the handlers.

What is a Window CallBack procedure and what is its utility?

DispatchMessage() is a API which indirectly triggers the Window CallBack procedure. Message structure members from this function are passed to the CallBack procedure. CallBack procedure should implement event handlers depending on the need of the application.

What are LPARAM and WPARAM in window proc function?

LPARAM and WPARAM are the two parameters in Window CallBack procedure. They signifies parameters of various events. They are used in handing individual events.

What are the basic steps of a typical MFC based application?

We need to write WinMain and need to follow all these in a Win32 application. However we need not to write much if we are writing an application with MFC ...

#