Conditional Compilation

Chapter 22 - The Microsoft Foundation Class Library: Fundamentals

Visual C++ 6: The Complete Reference
Chris H. Pappas and William H. Murray, III
  Copyright 1998 The McGraw-Hill Companies

A Simplified MFC Application
Before writing more complicated application code, let’s see what is required to just establish a window on the screen. In the last chapter, you learned to do this in C with a program that spanned two pages in length. When you use the power of the MFC library, the initial program code can be reduced to one-third this size!
This section examines the simplest possible Windows application, SIMPLE.CPP. The simple application will establish a window on the screen and place a title in its title bar area.
Establishing a Window with SIMPLE.CPP
In order to compile this MFC application, you need to enter the source code that follows. The source code file, while initially strange in appearance, is certainly shorter than its procedure-oriented counterparts.
//
//  simple.cpp
//  The code needed to establish a window with
//  the Microsoft Foundation Class library
//  Copyright William H. Murray and Chris H. Pappas, 1998
//

#include <afxwin.h>

class CTheApp : public CWinApp
{
public:
 virtual BOOL InitInstance( );
};
class CMainWnd : public CFrameWnd
{
public:
 CMainWnd( )
 {
   Create(NULL,"Hello MFC World",
          WS_OVERLAPPEDWINDOW,rectDefault,NULL,NULL);
 }
};

BOOL CTheApp::InitInstance( )
{
 m_pMainWnd=new CMainWnd( );
 m_pMainWnd->ShowWindow(m_nCmdShow);
 m_pMainWnd->UpdateWindow( );

 return TRUE;
}

CTheApp TheApp;
Once this C++ file is entered, you can compile this application from the integrated environment by creating a project file that includes the use of the MFC library.
  Note Make sure you set the option in the Project menu to include the static MFC library.
The following sections examine how each piece of code works in establishing the window on the screen.
Using the AFXWIN.H Header File
The AFXWIN.H header file is the gateway to Windows programming with the MFC library. This header file calls all subsequent header files, including WINDOWS.H, as they are needed. Using one header file also aids in creating precompiled header files. Precompiled header files save time when repeated compilation is being done during application development.
It might be a good idea to print a copy of AFXWIN.H for your reference as you develop your own applications using the MFC library. However, be warned, this header file has grown and approaches 100 pages in the current version because of support for OLE features and so on.
Deriving a Class from CWinApp
This application starts by deriving a class, CTheApp, from the MFC parent class, CWinApp. The programmer defines this new object.
class CTheApp : public CWinApp
{
public:
 virtual BOOL InitInstance( );
};
The class CTheApp overrides the member function InitInstance( ) of CWinApp. You will find that overriding member functions occurs frequently. By overriding InitInstance( ), you can customize the initialization and execution of the application. In CWinApp, it is also possible to override InitApplication( ), ExitInstance( ), and OnIdle( ), but for most applications, this will not be necessary.
Here is an edited portion of the CWinApp class description as found in the AFXWIN.H header file:
/////////////////////////////////////////////////////////////
// CWinApp - the root of all Windows applications

class CWinApp : public CWinThread
{
 DECLARE_DYNAMIC(CWinApp)
public:

// Constructor
 CWinApp(LPCTSTR lpszAppName = NULL);  //app defaults
                                       //to EXE name
// Attributes
 // Startup args (do not change)
 HINSTANCE m_hInstance;
 HINSTANCE m_hPrevInstance;
 LPTSTR m_lpCmdLine;
 int m_nCmdShow;

 // Running args (can be changed in InitInstance)
 LPCTSTR m_pszAppName;
 LPCTSTR m_pszRegistryKey;   // used for registry entries
 CDocManager* m_pDocManager;
public:  // set in constructor to override default
 LPCTSTR m_pszExeName;       // executable name (no spaces)
 LPCTSTR m_pszHelpFilePath;  // default based on module path
 LPCTSTR m_pszProfileName;   // default based on app name

// Initialization Operations - should be done in InitInstance
protected:
 void LoadStdProfileSettings(UINT nMaxMRU = _AFX_MRU_COUNT);
 void EnableShellOpen( );

 void SetDialogBkColor(COLORREF clrCtlBk = RGB(192,192,192),
       COLORREF clrCtlText = RGB(0, 0, 0));
   // set dialog box and message box background color
 void SetRegistryKey(LPCTSTR lpszRegistryKey);
 void SetRegistryKey(UINT nIDRegistryKey);
   // enables app settings in registry instead of INI files
   //  (registry key is usually a “company name”)

#ifdef _MAC
 friend void CFrameWnd::OnSysColorChange( );
 friend void CDialog::OnSysColorChange( );
#endif

 BOOL Enable3dControls( ); //use CTL3D32.DLL for 3D controls
#ifndef _AFXDLL
 BOOL Enable3dControlsStatic( );  //link CTL3D.LIB instead
#endif
 void RegisterShellFileTypes(BOOL bCompat=FALSE);
   // call after all doc templates are registered
 void RegisterShellFileTypesCompat( );
   // for backwards compatibility
 void UnregisterShellFileTypes( );

// Helper Operations - usually done in InitInstance
public:
 // Cursors
 HCURSOR LoadCursor(LPCTSTR lpszResourceName) const;
 HCURSOR LoadCursor(UINT nIDResource) const;
 HCURSOR LoadStandardCursor(LPCTSTR lpszCursorName) const;
 HCURSOR LoadOEMCursor(UINT nIDCursor) const;             
 // Icons
 HICON LoadIcon(LPCTSTR lpszResourceName) const;
 HICON LoadIcon(UINT nIDResource) const;
 HICON LoadStandardIcon(LPCTSTR lpszIconName) const;      
 HICON LoadOEMIcon(UINT nIDIcon) const;                   
    .
    .
    .
 // overrides for implementation
 virtual BOOL InitInstance( );
 virtual int ExitInstance( ); // return app exit code
 virtual int Run( );
 virtual BOOL OnIdle(LONG lCount);
 virtual LRESULT ProcessWndProcException(CException* e,
                                         const MSG* pMsg);
public:
 virtual ~CWinApp( );
    .
    .
    .
protected:
 //{{AFX_MSG(CWinApp)
 afx_msg void OnAppExit( );
 afx_msg void OnUpdateRecentFileMenu(CCmdUI* pCmdUI);
 afx_msg BOOL OnOpenRecentFile(UINT nID);
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP( )
};
The CWinApp class is responsible for establishing and implementing the Windows message loop. The Windows message loop was discussed in Chapter 21. This action alone eliminates many lines of repetitive code.
CFrameWnd
The application’s window, established by the CMainWnd class, is defined from the base class, CFrameWnd, as shown in the following segment of code:
class CMainWnd : public CFrameWnd
{
public:
 CMainWnd( )
 {
   Create(NULL,"Hello MFC World",
          WS_OVERLAPPEDWINDOW,rectDefault,NULL,NULL);
 }
};
The constructor for the class, CMainWnd( ), calls the Create( ) member function to establish initial window parameters. In this application, the window’s style and caption are provided as parameters. You’ll see in Chapter 23 that it is also possible to specify a menu name and an accelerator table when this member function is used.
Here is an edited portion of CFrameWnd, also found in the AFXWIN.H header file:
/////////////////////////////////////////////////////////////
// CFrameWnd - base class for SDI and other frame windows

class CFrameWnd : public CWnd
{
 DECLARE_DYNCREATE(CFrameWnd)

// Constructors
public:
 static AFX_DATA const CRect rectDefault;
 CFrameWnd( );

 BOOL LoadAccelTable(LPCTSTR lpszResourceName);
 BOOL Create(LPCTSTR lpszClassName,
       LPCTSTR lpszWindowName,
       DWORD dwStyle = WS_OVERLAPPEDWINDOW,
       const RECT& rect = rectDefault,
       CWnd* pParentWnd = NULL,        // != NULL for popups
       LPCTSTR lpszMenuName = NULL,
       DWORD dwExStyle = 0,
       CCreateContext* pContext = NULL);
 // dynamic creation - load frame and associated resources
 virtual BOOL LoadFrame(UINT nIDResource,
       DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW |
                              FWS_ADDTOTITLE,
       CWnd* pParentWnd = NULL,
       CCreateContext* pContext = NULL);

 // special helper for view creation
 CWnd* CreateView(CCreateContext* pContext,
                  UINT nID = AFX_IDW_PANE_FIRST);
  .
  .
  .
 // control bar docking
 void EnableDocking(DWORD dwDockStyle);
 void DockControlBar(CControlBar* pBar, UINT nDockBarID = 0,
   LPCRECT lpRect = NULL);
 void FloatControlBar(CControlBar* pBar, CPoint point,
   DWORD dwStyle = CBRS_ALIGN_TOP);
 CControlBar* GetControlBar(UINT nID);
  .
  .
  .
// Implementation
public:
 virtual ~CFrameWnd( );
 int m_nWindow;
 HMENU m_hMenuDefault;       // default menu resource
 HACCEL m_hAccelTable;       // accelerator table
 DWORD m_dwPromptContext;    // current help prompt
 BOOL m_bHelpMode;           // if TRUE, help mode is active
 CFrameWnd* m_pNextFrameWnd; // CFrameWnd in app global list
 CRect m_rectBorder;         // OLE border space negotiation
 COleFrameHook* m_pNotifyHook;
 CPtrList m_listControlBars; // array of control bars that
                             // have this window as dock site
 int m_nShowDelay;           // SW_ command for delay show/hide

    .
    .
    .
 // Windows messages
 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
 afx_msg void OnDestroy( );
 afx_msg void OnClose( );
 afx_msg void OnInitMenuPopup(CMenu*, UINT, BOOL);
 afx_msg void OnMenuSelect(UINT nItemID, UINT nFlags,
                           HMENU hSysMenu);
 afx_msg LRESULT OnPopMessageString(WPARAM wParam,
                                    LPARAM lParam);
 afx_msg LRESULT OnSetMessageString(WPARAM wParam,
                                    LPARAM lParam);
  .
  .
  .
protected:
#ifndef _MAC
 afx_msg LRESULT OnDDEInitiate(WPARAM wParam,
                               LPARAM lParam);
 afx_msg LRESULT OnDDEExecute(WPARAM wParam,
                              LPARAM lParam);
 afx_msg LRESULT OnDDETerminate(WPARAM wParam,
                                LPARAM lParam);
 afx_msg LRESULT OnRegisteredMouseWheel(WPARAM wParam,
                                        LPARAM lParam);
#endif
#ifdef _MAC
 afx_msg void OnActivateApp(BOOL bActive, HTASK hTask);
 afx_msg void OnPaint( );
#endif
 DECLARE_MESSAGE_MAP( )

 friend class CWinApp;
};
The first parameter in the Create( ) member function allows a class name to be specified in compliance with the traditional Windows API RegisterClass( ) function. Normally, this will be set to NULL in the applications you develop (a parent window) and a class name will not be required.
Implementing the InitInstance( ) Member Function
Recall that the derived CTheApp class object overrode the InitInstance( ) member function. Here is how this application implements InitInstance( ):
BOOL CTheApp::InitInstance( )
{
 m_pMainWnd=new CMainWnd( );
 m_pMainWnd->ShowWindow(m_nCmdShow);
 m_pMainWnd->UpdateWindow( );

 return TRUE;
}
The new operator invokes the constructor CMainWnd( ), discussed in the previous section. The m_pMainWnd member variable (m_ indicates a member variable) holds the location for the application’s main window. The ShowWindow( ) member function is required to display the window on the screen. The parameter, m_nCmdShow, is initialized by the application’s constructor. UpdateWindow( ) displays and paints the window being sent to the screen.
The Constructor
The last piece of code invokes the application’s constructor at startup:
CTheApp TheApp;
The application code for this example is very simple and straightforward. The application merely establishes a window; it does not permit you to draw anything in the window.
In the next chapter, you will create a more generalized template, as you did in Chapter 21. This template will allow you to use basically the same MFC code from one application to another. In addition, this template code will allow you to draw in the client area of the window.
Running the SIMPLE.CPP Application
Figure 22-1 shows a window similar to the one that will appear on your screen. While the application didn’t draw anything in the client area of the window, it did give the application a new title!
Figure 22-1: Establishing a window with the use of the MFC library
This code forms the foundation for all Windows MFC library applications developed in this book. You might want to review the important details one more time before going on to the applications created in Chapter 23.
Application Maintenance Is Easy with the MFC
Reusable classes are one of the main drawing cards in C++ for simplified design and application maintenance. The MFC library for Windows allows C++ to be extended in a natural way, making these classes appear to be part of the language itself. In the next chapter you’ll explore many additional features of the MFC library as you develop applications that range from a simple program template to a robust charting program using menus and dialog boxes.

Books24x7.com, Inc 2000 –  


Visual C++ 6(c) The Complete Reference
Visual Studio 6: The Complete Reference
ISBN: B00007FYGA
EAN: N/A
Year: 1998
Pages: 207

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net