Doc-view modules

MFC doc-view application can be created by MFC wizard. We have seen how to create a single document interface SDI application using wizard in our previous module. MFC wizard creates each class and adds functions and events to support the minimal functionalities. However doc-view application can be created manually and now we want to understand the work function of each class. This module will help developer to write a minimal doc-view application from scratch.

A doc-view application should conain -

  • An application class instance derived from CWinApp class
  • A frame window derived from CFrameWnd class
  • A document class to hold the state and content of the document
  • A view class to represent the view of the document

CWinApp Application class

CWinApp should override and implement this functon.

CWinApp::InitInstance - Main application classs should override InitInstance() and implement the basic requirement. It should process command line arguments and create a SDI or MDI frame window.

CWinApp should handle these event codes and

  • OnFileNew() - New file with event code ID_FILE_NEW
  • OnFileOpen() - Open an existing file from disk using code ID_FILE_OPEN
  • OnAppAbout() - To show an about dialog with event code ID_APP_ABOUT
BEGIN_MESSAGE_MAP(CMySDIApp, CWinApp)
	ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
	ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
	ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
END_MESSAGE_MAP()

CMySDIApp::CMySDIApp()
{
}

CMySDIApp theApp;

BOOL CMySDIApp::InitInstance()
{
	AfxEnableControlContainer();

#ifdef _AFXDLL
	Enable3dControls();
#else
	Enable3dControlsStatic();
#endif


	SetRegistryKey(_T("Local AppWizard-Generated Applications"));

	LoadStdProfileSettings();

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

	// Parse command line for standard shell commands, DDE, file open
	CCommandLineInfo cmdInfo;
	ParseCommandLine(cmdInfo);

	// Dispatch commands specified on the command line
	if (!ProcessShellCommand(cmdInfo))
		return FALSE;

	// The one and only window has been initialized, so show and update it.
	m_pMainWnd->ShowWindow(SW_SHOW);
	m_pMainWnd->UpdateWindow();

	return TRUE;
}

CFrameWnd Window class

Programmer should implement and override OnCreate() event.

  • OnCreate - It is called when window is created.

Programmer should implement MFC OnCreate() event map.

  • ON_WM_CREATE - MFC Event map for OnCeate.
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	ON_WM_CREATE()
END_MESSAGE_MAP()

static UINT indicators[] =
{
	ID_SEPARATOR,           // status line indicator
	ID_INDICATOR_CAPS,
	ID_INDICATOR_NUM,
	ID_INDICATOR_SCRL,
};

/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction

CMainFrame::CMainFrame()
{
}

CMainFrame::~CMainFrame()
{
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
		| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
		!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
	{
		TRACE0("Failed to create toolbar\n");
		return -1;      // fail to create
	}

	if (!m_wndStatusBar.Create(this) ||
		!m_wndStatusBar.SetIndicators(indicators,
		  sizeof(indicators)/sizeof(UINT)))
	{
		TRACE0("Failed to create status bar\n");
		return -1;      // fail to create
	}

	// TODO: Delete these three lines if you don't want the toolbar to
	//  be dockable
	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
	EnableDocking(CBRS_ALIGN_ANY);
	DockControlBar(&m_wndToolBar);

	return 0;
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	if( !CFrameWnd::PreCreateWindow(cs) )
		return FALSE;
	return TRUE;
}

CDocument class

CDocument implements these member functions

  • CDocument - Construcor and destructor
  • OnNewDocument - Event for new document creation. Called during a new applicaton start or selecting new document menu
  • Serialize- Event saving or retrieving document from file. Called by framework in OnFileOpen() and OnFileSave().
///////////////////////////////////////////
// CMySDIDoc

IMPLEMENT_DYNCREATE(CMySDIDoc, CDocument)

BEGIN_MESSAGE_MAP(CMySDIDoc, CDocument)

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMySDIDoc construction/destruction

CMySDIDoc::CMySDIDoc()
{
}

CMySDIDoc::~CMySDIDoc()
{
}

BOOL CMySDIDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

    m_strFile = "Untitled";
	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CMySDIDoc serialization

void CMySDIDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		m_strFile = ar.GetFile()->GetFilePath();
		AfxMessageBox("Save:"+m_strFile);
	}
	else
	{
		m_strFile = ar.GetFile()->GetFilePath();
		AfxMessageBox("Load:"+m_strFile);
	}
}

CView class

CView implements these member functions

  • PreCreateWindow - Override Window attributes or pass the call to base class function.
  • OnDraw - Actual drawing work for window and printer DC.
  • OnPreparePrinting - Prining attributes override and print dialog by calling DoPreparePrinting
  • OnBeginPrinting - Prining or previewing startup call
  • OnEndPrinting - Prining or previewing cleanup call

CView implements these application event handlers functions

  • ID_FILE_PRINT - Printinging from menu/toolbar call event base CView::OnFilePrint.
  • ID_FILE_PRINT_DIRECT - Dirent printing using command line call base event CView::OnFilePrint.
  • ID_FILE_PRINT_PREVIEW - Print preview from menu/toolbar call CView::OnFilePrintPreview.
/////////////////////////////////////////////////////////////////////////////
// CMySDIView

IMPLEMENT_DYNCREATE(CMySDIView, CView)

BEGIN_MESSAGE_MAP(CMySDIView, CView)
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

CMySDIView::CMySDIView()
{
}

CMySDIView::~CMySDIView()
{
}

BOOL CMySDIView::PreCreateWindow(CREATESTRUCT& cs)
{
  return CView::PreCreateWindow(cs);
}

void CMySDIView::OnDraw(CDC* pDC)
{
	RECT rect;
	CMySDIDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	pDC->GetWindow()->GetClientRect(&rect);
	pDC->DrawText(pDoc->m_strFile, &rect, 0);
}

BOOL CMySDIView::OnPreparePrinting(CPrintInfo* pInfo)
{
  return DoPreparePrinting(pInfo);
}

void CMySDIView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
}

void CMySDIView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)
{
}

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 ...

#