Webocreation

Tuesday, November 17, 2009

Analyzing a Document/View Application

Analyzing a Document/View Application

Because theory and background information can only take you so far, it's time to look at the implementation of a working document/view application. Analyzing the code for an actual document/view application should help bring into focus the abstract concepts presented earlier.

In this section, you will take a close look at the source code related to document/view architecture. This will help you better understand what is going on behind the scenes in a typical MFC application. (The CAboutDialog class is not discussed since it is not related to document/view and its only purpose in this application is to provide information in the Help About dialog box.)

The following illustration shows the base classes present in most document/view applications and the derived classes for a sample application called Reader, created using AppWizard.



The five main classes for the Reader application appear at the bottom of the preceding illustration and are derived as follows:

® The application class, CReaderApp, is derived from CWinApp.

® The frame window class, CMainFrame, is derived from CFrameWnd.

® The document class, CReaderDoc, is derived from CDocument.

® The view class, CReaderView, is derived from CView.

® The dialog class, CAboutDialog, is derived from CDialog.

For purposes of illustration, some changes have been made to the code automatically generated by AppWizard for this application. You can find the complete code for the Reader application in \Samples\Ch04\Reader.

This section includes the following topics:

The CWinApp Derived Class

The class CReaderApp, which is derived from CWinApp, is the application class for the Reader application. CReaderApp includes the member function InitInstance. The InitInstance function stores the application settings in the registry, creates a document template, registers the document template, and initializes the command line.

Setting the Registry

The InitInstance function causes application settings to be stored in the registry instead of in private .ini files by executing the following statement:

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

If this function has been called, the list of most recently used (MRU) files is also stored in the registry. The registry key is usually the name of a company.

Loading the Application Profile

InitInstance executes the following statement to load the list of most recently used (MRU) files and the last preview state:

LoadStdProfileSettings();

Creating a Document Template

Finally, the InitInstance function creates a document template from the CSingleDocTemplate class by executing the following statements:

CSingleDocTemplate* pDocTemplate;

pDocTemplate = new CSingleDocTemplate(IDR_MAINFRAME,

RUNTIME_CLASS(CReaderDoc),

RUNTIME_CLASS(CMainFrame),RUNTIME_CLASS(CReaderView));


The CSingleDocTemplate class defines a document template that implements the single document interface (SDI). An SDI application uses the main frame window to display a document. Only one document can be open at a time. A document template defines the relationship between the three main document/view classes:

® The document class, which is used to represent the application's document

® The view class, which displays data from the document class

® The frame window class, which contains the views of the document

The document template also specifies the ID of the resources used with the document type. Resources can include menus, icons, an accelerator table, and strings.

The following statement adds a document template to the list of available document templates that the application maintains:

AddDocTemplate(pDocTemplate);

Initializing the Command Line

The following statements are executed to initialize a CCommandLineInfo object with the values entered on the command line:

CCommandLineInfo cmdInfo;

ParseCommandLine(cmdInfo);

if (!ProcessShellCommand(cmdInfo))

return FALSE;


The ProcessShellCommand processes the command-line parameter and returns a nonzero value if the shell command is processed successfully. Otherwise, it returns FALSE from InitInstance.

To see the source code for the implementation file associated with the CReaderApp class, click this icon. For easy reference, the segments of code discussed in this section are highlighted in bold.



// Reader.cpp : Defines the class behaviors for the application.

//


#include "stdafx.h"

#include "Reader.h"


#include "MainFrm.h"

#include "ReaderDoc.h"

#include "ReaderView.h"


#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif


/////////////////////////////////////////////////////////////////////////////

// CReaderApp


BEGIN_MESSAGE_MAP(CReaderApp, CWinApp)

//{{AFX_MSG_MAP(CReaderApp)

ON_COMMAND(ID_APP_ABOUT, OnAppAbout)

// NOTE - the ClassWizard will add and remove mapping macros here.

// DO NOT EDIT what you see in these blocks of generated code!

//}}AFX_MSG_MAP

// Standard file based document commands

ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)

ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)

// Standard print setup command

ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)

END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////

// CReaderApp construction


CReaderApp::CReaderApp()

{

// TODO: add construction code here,

// Place all significant initialization in InitInstance

}


/////////////////////////////////////////////////////////////////////////////

// The one and only CReaderApp object


CReaderApp theApp;


/////////////////////////////////////////////////////////////////////////////

// CReaderApp initialization


BOOL CReaderApp::InitInstance()

{

// Standard initialization

// If you are not using these features and wish to reduce the size

// of your final executable, you should remove from the following

// the specific initialization routines you do not need.


#ifdef _AFXDLL

Enable3dControls(); // Call this when using MFC in a shared DLL

#else

Enable3dControlsStatic(); // Call this when linking to MFC statically

#endif


// Change the registry key under which our settings are stored.

// You should modify this string to be something appropriate

// such as the name of your company or organization.

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


LoadStdProfileSettings(); // Load standard INI file options (including MRU)


// Register the application's document templates. Document templates

// serve as the connection between documents, frame windows and views.


CSingleDocTemplate* pDocTemplate;

pDocTemplate = new CSingleDocTemplate(

IDR_MAINFRAME,

RUNTIME_CLASS(CReaderDoc),

RUNTIME_CLASS(CMainFrame), // main SDI frame window

RUNTIME_CLASS(CReaderView));

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;

}


/////////////////////////////////////////////////////////////////////////////

// CAboutDlg dialog used for App About


class CAboutDlg : public CDialog

{

public:

CAboutDlg();


// Dialog Data

//{{AFX_DATA(CAboutDlg)

enum { IDD = IDD_ABOUTBOX };

//}}AFX_DATA


// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CAboutDlg)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

//}}AFX_VIRTUAL


// Implementation

protected:

//{{AFX_MSG(CAboutDlg)

// No message handlers

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};


CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

{

//{{AFX_DATA_INIT(CAboutDlg)

//}}AFX_DATA_INIT

}


void CAboutDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CAboutDlg)

//}}AFX_DATA_MAP

}


BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

//{{AFX_MSG_MAP(CAboutDlg)

// No message handlers

//}}AFX_MSG_MAP

END_MESSAGE_MAP()


// App command to run the dialog

void CReaderApp::OnAppAbout()

{

CAboutDlg aboutDlg;

aboutDlg.DoModal();

}


/////////////////////////////////////////////////////////////////////////////

// CReaderApp commands

No comments:

Post a Comment