Writing Applications in Non-Document/View
This section describes the basics of non-document/view architecture and analyzes the code from a simple MFC application.
Before the days of document/view architecture, MFC applications had two principal components: an application object representing the application itself and a window object representing the application's window. The application object's primary duty was to create a window, and the window in turn processed messages. In these early versions, MFC simply encapsulated the Windows API and grafted an object-oriented interface onto standard Windows objects, such as menus and dialog boxes.
Most MFC applications are developed in document/view, but it is not required. Document/view applications include an extensive set of starter files and are inherently bigger and more complex than non-document/view applications. In some cases, such as a simple dialog-based application, document/view may not be architecturally appropriate.
When you are first learning about MFC, you may find it useful to look at the non-document/view architecture, because it has fewer layers of code and uses a simpler messaging model. Developers who rely on code-generation tools such as AppWizard are sometimes unfamiliar with some important aspects of MFC architecture and functionality.
This section includes the following topics:
- Getting Started in Non-Document/View
The simplest way to create a non-document/view application is by creating a dialog-based application using AppWizard. The resulting application consists of an empty dialog template that must be edited to fit the needs of the application. In the InitInstance function, the dialog box is invoked and, when dismissed, the application will terminate.
The bold section in the following sample code illustrates a key segment of the AppWizard-generated code that instantiates and displays a dialog box object and allows for specific handling based on its return code. To see the sample code, click this icon.
BOOL CNonDocViewApp::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
CNonDocViewDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
After you remove the dialog template and the dialog code in InitInstance, you can create the non-document/view application of your choice.
In Lab 4.1, you will learn how to manually code a Windows-based MFC application without using AppWizard.
- Analyzing a Non-Document/View Application
You can see how CWinApp and CFrameWnd classes are implemented by looking at the code for a simple application. As you look at this code, notice how the classes derived from CWinApp and CFrameWnd can be used for writing MFC applications.
The following code generates an application with a window that can be moved, resized, minimized, maximized, and closed.
#include <afxwin.h>
class CMyApp : public CWinApp
{
public:
virtual BOOL InitInstance ();
};
class CMainFrame : public CFrameWnd
{
};
CMyApp myApp;
BOOL CMyApp::InitInstance ()
{
m_pMainWnd = new CMainFrame;
((CMainFrame*)m_pMainWnd)->Create(NULL,"The MFC Application");
m_pMainWnd->ShowWindow (m_nCmdShow);
return TRUE;
}
Let's look at some key statements, shown in bold in the preceding code, to see how MFC uses the application and frame window classes to perform various functions.
Declaring the Application Object Globally
In a framework application, you don't write WinMain. It is supplied by the class library and is called when the application starts up. An application built on the framework must have one (and only one) object of a class derived from CWinApp. The application object is declared globally at the beginning of the application because it must exist before the framework calls the WinMain function. The following statement globally declares the application object, myApp, for this application:
CMyApp myApp;
Creating the Window
To initialize the application, WinMain calls the application object's InitInstance member function. In this application, InitInstance creates the window by instantiating an object from the CMainFrame class.
The following statement dynamically creates a CMainFrame object and assigns its address to the data member, m_pMainWnd, for the application class.
m_pMainWnd = new CMainFrame;
The next statement creates the window by using CFrameWnd::Create. It uses the default window class and gives the window the caption “The MFC Application.”
((CMainFrame*)m_pMainWnd)->Create(NULL,"The MFC Application");
Displaying the Window
The following statement displays the window using the ShowWindow member function.
m_pMainWnd->ShowWindow (m_nCmdShow);
If the InitInstance function returns 0, WinMain is terminated and the application is shut down. If InitInstance returns a nonzero value, the WinMain function runs the application's message loop by calling the Run member function. The message loop executes until a WM_QUIT message is retrieved from the message queue. Upon termination, WinMain calls the application object's ExitInstance member function.
For more information about the WinMain functions, see the source code file, WinMain.cpp. This file is included with the set of starter files that you get when you use AppWizard to create your application.
Lab 4.1: Hand-Coding a Minimal MFC Application
In this lab, you will create, build, and run a minimal MFC application in the Developer Studio development environment.
To see a demonstration that shows what you will accomplish during the lab, click this icon.
Estimated time to complete this lab: 20 minutes
To complete the exercises in this lab, you must have the required software. For detailed information about the labs and setup for the labs, see Labs in this course.
Objectives
After completing this lab, you will be able to:
® Create a simple MFC Windows-based application without using wizards.
® Use Microsoft Developer Studio and Microsoft Visual C++ to build and run the application.
Prerequisites
There are no prerequisites for this lab.
Exercise
The following exercise provides practice with the concepts and techniques covered in this chapter.
® Exercise 1: Creating a Minimal MFC Application
In this exercise, you will use Microsoft Developer Studio and Microsoft Visual C++ to create, build, and run a simple MFC application. This lab gives you first-hand experience in creating a Windows-based application from scratch without using the MFC wizards.
® Exercise 1: Creating a Minimal MFC Application
In this exercise, you will hand-code a minimal MFC application without using wizards.
u Create a new project
1. In Developer Studio, on the File menu, click New.
2. In the New dialog box, click the Projects tab, and then do the following:
a. For the project type, click Win32 Application.
b. For the project name, type MinimalApplication.
c. Set the location for your project.
d. Accept the default platform Win32.
3. To create the new project workspace, click OK.
u Add a header file to the project
1. In Developer Studio, on the Project menu, point to Add To Project, and then click New.
2. In the New dialog box, click the Files tab, and then do the following:
a. For the file type, click C/C++ Header File.
b. Select the Add To Project check box.
c. For the file name, type MinApp.
3. To create the new file, click OK.
u Derive classes from the base classes CWinApp and CFrameWnd
1. Include the Afxwin.h file as follows:
#include <afxwin.h>
2. Publicly derive a CMyApp class from CWinApp. Override the InitInstance member function in the public section of the class as follows:
class CMyApp : public CWinApp
{
public:
virtual BOOL InitInstance ();
};
3. Publicly derive a CMainFrame class from CFrameWnd.
class CMainFrame: public CFrameWnd
{
};
4. Save and close the file.
u Add an implementation file to the project
1. In Developer Studio, on the Project menu, point to Add To Project, and then click New.
2. In the New box, click the Files tab, and then do the following:
a. For the file type, click C/C++ Source File.
b. Select the Add To Project check box.
c. For the file name, type MinApp.
3. To create the new file, click OK.
u Write code for the member function
1. Include the MinApp.h file as follows:
#include "MinApp.h"
2. Declare the following variable in your MinApp.cpp file:
CMyApp myApp;
3. Implement the InitInstance function for the CMyApp class as follows:
BOOL CMyApp::InitInstance ()
{
m_pMainWnd = new CMainFrame;
((CMainFrame*)m_pMainWnd)->Create(NULL,"The MFC Application");
m_pMainWnd->ShowWindow (m_nCmdShow);
return TRUE;
}
u Edit the project settings
1. In Developer Studio, on the Project menu, click Settings, and then do the following:
a. In the Settings for list box, click Win32 Debug.
b. Click the General property sheet tab.
c. In the Microsoft Foundation Classes combo box, click Use MFC in a Static Library.
This will bind the binary information from the MFC library directly to your program.
2. To return to Developer Studio, click OK.
u Build and run the current project
1. In Developer Studio, on the Build menu, click Build MinimalApplication.exe.
2. On the Build menu, click Execute MinimalApplication.exe.
You can find the completed code for this exercise in \Labs\Ch04\Lab01\Ex01.
No comments:
Post a Comment