Tutorial: Second MFC Program

Author: Ronald S. Holland

Total Application Works





To visit my site

HOME] Consulting Design Maintenance Project Testing Training Turnkey Java C++ SQL HTML JavaScript ]


To contact us

© 2002 - 2015 All Rights Reserved Total Application Works


  • Tell a friend about this site (copy and paste the following HTML page into a file (e.g., using Notepad).)

  • <html>
    <head>
    <title>Example of a link </title>
    </head>
    <body>
    <a href="http://sumtotalz.com/TotalAppsWorks/CPP/GettingStarted/GettingStarted_II.html">
    Getting Started II </a>
    </table>
    </body>
    </html>
    Download Source


Introduction

In this tutorial, we will explore dialog-based applications. You should be familiar with the concepts covered in Getting Started I. Additional links to dialog-based applications can be found at:

In this tutorial, we will create a Hello World application, using a GUI interface and a dialog-based application. With a GUI interface, the end-user is presented with graphics like:

  • Menus
  • Menu items
  • Push buttons
  • Radio buttons
  • Check boxes
  • Edit boxes
  • Etc.
When the end-user clicks on one of the above items, and event is created. If the program has identified code to respond to the event, that code is called. For example, if File is clicked on the menu bar and then Exit, then the code that causes the program to exit is called. The code that is called and responds to an event is called the event handler.

Are events and event handlers unusual? We see the handling of events mechanically and electro-mechanically everyday. Consider the following mechanical events.

     Event        
     Event Handler    
Switch Toggles light on or off
Press the gas peddle Car speeds up
Press the brake peddle Car slows down
Turn on the car ignition Car engine starts
Figure 1: Mechanical events

The pocket calculator and the TV remote control (TV-RC) are examples of electro-mechanical event-handlers that closely resemble our coding example.

     Event        
     Event Handler    
Calculator: 1 + 1 = 2 is computed

1 and 1 are input
+ is the command
= is the event
Calculator: 5 * 5 = 25 is computed

5 and 5 are input
* is the command
= is the event
TV-RC: Press the power button TV is turned on
TV-RC: Press the +channel button The next higher channel is selected
TV-RC: Press the -channel button The next lower channel is selected
Figure 2: Mechanical events


It should be noted that an event is created every time a calculator button is pressed. In the next section, we will define the requirements for the example covered in this tutorial.

A more advanced MFC example can be found at A basic Addressbook app II .

Requirements

  1. Modify the MFC application template. covered in the previous tutorial to handle a dialog-based application
  2. Use the updated MFC application template to create a Hello world application.

MFC Application Template

In the previous tutorial, the header looked like:
  
// define our window based on the MFC frame window 
class MyApp : public CFrameWnd 
{
public:
   MyApp();          // MyApp constructor
   virtual ~MyApp(); // free-up resources
 
private:

};
 

We will modify that header file for this example to look like:
  
class MyApp : public CDialog 
{
public:
   MyApp()
      : CDialog( "Name-of-dialog-to-be-invoked" )  {}

private:

   DECLARE_MESSAGE_MAP() 
};
  

In addition, the .cpp file template looked like:
  
// include application framework windows class definitions:
#include <afxwin.h>
#include "MyApp.h"

/****************************************
 * constructor initializes resources
 ***************************************/
MyApp::MyApp()
{
   
}

/****************************************
 * destructor frees resources
 ***************************************/
MyApp::~MyApp()   
{ 
  
}

class CHelloWorldApp : public CWinApp  
{
public:
   virtual BOOL InitInstance()   // override default CWinApp method
   {
     m_pMainWnd = new MyApp();             // instantiate MyApp
     m_pMainWnd->ShowWindow( m_nCmdShow ); // make frame visible
     m_pMainWnd->UpdateWindow();           // refresh frame window

     return true;                          // report success
   }

} helloWorldApp;     

 
Figure 3: MFC Application Template

We will modify the .cpp template to look like:
  

// include application framework windows class definitions:
#include 
#include "MyApp.h"


BEGIN_MESSAGE_MAP( MyApp, CDialog )
   
END_MESSAGE_MAP()
 

class MyHelloWorld : public CWinApp 
{
public:
   virtual BOOL InitInstance()   // override default method
   {
     MyApp  myapp;              // instantiate MyApp
     myapp.DoModal();           

     return true;               // report success
   }

} helloWorldApp;     

  
Figure 4: MFC Application Template - Modified

Where do we go from here? We need the means to describe the graphics we will use in this example. To do this, we will define the resource file.

Resource File

In this section we will describe the use of resource files (.rc). It is through the use of resource files that many applications define the graphical elements of their user interface: dialogs, menus, text strings (static/labels), bitmaps, toolbars, and other types of resources. In the previous tutorial, we used the following code to write a static text field to the screen.
  
 
    pHello = new CStatic();      // create a static control

    pHello->Create(              // create Windows control
       "This is a slight modification of the Hello World. "
	   "\n \n"
	   "Hello world from Ron Holland" 	   , // text
       WS_CHILD | WS_VISIBLE | WS_BORDER  // window styles
       | SS_CENTER,                 // static object styles
       CRect( 50, 50, 450, 150 ),   // window coordinates
       this );       
 
 
Figure 5: Resource File


To accomplish the same thing in this tutorial, we will code the following in the resource script file.

  
    LTEXT           "This is a slight modification of the Hello World.",
                         IDC_STATIC,10,10,200,8
    LTEXT           "From Ron Holland",IDC_STATIC,70,30,119,8

where the LTEXT parameters are:

    LTEXT text, id, x, y, width, height [[, style [[, extended-style]]]]
        x, y define the upper left hand corner of the static control window

    style: Specifies the control styles.

  
Figure 6: Resource Script File


Many programmers prefer the latter method for declaring their graphical elements because, to them, it is easier and more straightforward. We will also use this method to define some push buttons, which will cause our definition to look like:

  
    LTEXT           "This is a slight modification of the Hello World.",
                         IDC_STATIC,10,10,200,8
    LTEXT           "From Ron Holland",IDC_STATIC,70,30,119,8
    DEFPUSHBUTTON   "Hello",IDC_HELLO,6,104,30,15
    PUSHBUTTON      "GoodBye",IDC_GOODBYE,49,104,30,15,NOT WS_TABSTOP
    PUSHBUTTON      "Exit",IDC_EXIT,89,104,30,15,NOT WS_TABSTOP
  

where the PUSHBUTTON parameters are defined as
 
PUSHBUTTON text, id, x, y, width, height [[, style [[, extended-style]]]]
  - x,y      are the upper left-hand coordinates
  - id       Specifies the control identifier. This value must be a 
              16-bit unsigned integer in the range 0 through 65,535 
              or a simple arithmetic expression that evaluates to a 
              value in that range. 
  - width:   Specifies the width of the control.
  - height:  Specifies the height of the control. 
 
Finally, our defintion will look like:
  
Name of dialog
    |
    V
HELLOWORLD DIALOG DISCARDABLE  50, 50, 230, 130
STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | 
    WS_THICKFRAME
CAPTION "Hello World Dialog Box"
FONT 8, "Courier New"
BEGIN
    LTEXT           "This is a slight modification of the Hello World.",
                         IDC_STATIC, 10, 10, 200, 8
    LTEXT           "From Ron Holland", IDC_STATIC, 70, 30, 119, 8
    DEFPUSHBUTTON   "Hello", IDC_HELLO, 6, 104, 30, 15
    PUSHBUTTON      "GoodBye", IDC_GOODBYE, 49, 104, 30, 15, NOT WS_TABSTOP
    PUSHBUTTON      "Exit", IDC_EXIT, 89, 104, 30, 15, NOT WS_TABSTOP
END
  
Figure 7: Resource Script File II


Where do we go from here? We will expand our template to implement our hello world application.

Expand Our Template to Create an Hello World Application

In the section, we need to identify the code segments that should be called when a particular button is pressed. You will note that there is an id in the parameter list that defines a PUSHBUTTON. Consider the following:

 
PUSHBUTTON text, id, x, y, width, height [[, 
                    style [[, extended-style]]]]
 
which for the Hello push button, we defined as
 
DEFPUSHBUTTON   "Hello", IDC_HELLO, 6, 104, 30, 15
 

In this case, we defined the id as IDC_HELLO. Since the id must be an int, we define the ids for our push buttons in the following manner.
 
#define IDC_HELLO          2001
#define IDC_GOODBYE        2002
#define IDC_EXIT           2003
 

The next step is to associate the ids with the event handlers. This is done via the BEGIN_MESSAGE_MAP segment.
 
BEGIN_MESSAGE_MAP( MyApp, CDialog )
   ON_COMMAND( IDC_HELLO, OnHello )
   ON_COMMAND( IDC_GOODBYE, OnGoodBye )
   ON_COMMAND( IDC_EXIT, OnExit )
END_MESSAGE_MAP()
 

Figure 8: Resource Script File II


In this example,

  • IDC_HELLO is associated with the event handler OnHello ,
  • IDC_GOODBYE is associated with the event handler OnGoodBye ,
  • IDC_EXIT is associated with the event handler OnExit .
With the above in mind, the final mapping looks like:

PUSH
BUTTON
ID Value Event Handler Action
Hello IDC_HELLO 2001 OnHello Causes app to display a hello message
GoodBye IDC_GOODBYE 2002 OnGoodBye Causes app to display a goodbye message exit
and then exit
Exit IDC_EXIT 2003 OnExit Causes app to exit
Figure 9: PUSH BUTTON Mappings


When the Hello button is pressed, the system knows to call the OnHello code to do whatever processing that is contained within that code segment.

In the next section, we will put the lessons learned so far into writing a complete application.

Putting It Together: Build an Hello World Application

We have been describing the contents of four files. They are:
  
+-------------+
| MyApp.h     |  - defines MyApp class
+-------------+
| MyApp.cpp   |  - implements MyApp class
+-------------+
| MyApp.rc    |  - implements the graphical units in MyApp app.
+-------------+
| MyApp_ids.h |  - defines MyApp graphical units 
+-------------+

  
Figure 10: Hello World Application Source Files List


The above four files are used to build our application. Using the modified template and the code we have put together to create a dialog, we get the following header file:
  
/*******************************************************
 * File: MyApp.h
 *******************************************************/

// define our window based on the MFC frame window 
class MyApp : public CDialog
{
public:
   MyApp()
      : CDialog( "HELLOWORLD" )  {}

   afx_msg void OnHello();      // clicked the "Hello" button
   afx_msg void OnGoodBye();    // clicked the "GoodBye" button
   afx_msg void OnExit();       // clicked the "Clear" button

private:

   CStatic *pHello ;      // create a static control ;

   DECLARE_MESSAGE_MAP()
};
  
The MyApp_ids.h file looks like:
  
/**********************************************************
 * File: MyApp_ids.h
 ***********************************************************/

#define IDC_LABEL          2000
#define IDC_HELLO          2001
#define IDC_GOODBYE        2002
#define IDC_EXIT           2003
  
Figure 11: MyApp.h Header File


And the following .cpp file looks like.
  
/*************************************************************
 * File: MyApp.cpp
 *************************************************************/

// include application framework windows class definitions:
#include 
#include "MyApp.h"
#include "MyApp_ids.h"


/****************************************
 * MyApp constructor initializes frame
 * 1- Create a Cframe window
 * 2- Instantiate the pHello pointer based on a CStatic control
 * 3- Create a CStatic child window
 ****************************************/
afx_msg void MyApp::OnHello()
{
    MessageBox("Hello World",
		       "Hello World\n from\nRon Holland",
			   MB_ICONEXCLAMATION ); 

	          

  // pHello = new CStatic();   // create a static control
/*
   pHello->Create(           // create Windows control
      "Hello world\n from\n Ron Holland!", // text
      WS_CHILD | WS_VISIBLE | WS_BORDER  // window styles
      | SS_CENTER,                // static object styles
      CRect( 40, 50, 260, 150 ),  // window coordinates
      this );   
   */              
}

/****************************************
 *
 ***************************************/
afx_msg void MyApp::OnGoodBye()
{
    MessageBox("GoodBye World",
		       "GoodBye World from Ron Holland",
			   MB_ICONEXCLAMATION ); 

	OnExit() ;

}

/****************************************
 *
 ***************************************/
afx_msg void MyApp::OnExit()
{
   // Exit the dialog
	OnOK();
}


BEGIN_MESSAGE_MAP( MyApp, CDialog )
   ON_COMMAND( IDC_HELLO, OnHello )
   ON_COMMAND( IDC_GOODBYE, OnGoodBye )
   ON_COMMAND( IDC_EXIT, OnExit )
END_MESSAGE_MAP()
 
/*************************************************
 * Derive our application class CHelloApp based on 
 * CWinApp
 * 1- Overwrite InitInstance() method
 * 2- Make main frame window visiable
 * 3- Make the main frame window visiable
 *************************************************/
class MyHelloWorld : public CWinApp 
{
public:
   virtual BOOL InitInstance()   // override default method
   {
     MyApp  myapp;    // instantiate MyApp
     myapp.DoModal();           

     return true;                          // report success
   }

} helloWorldApp;     
  

  
Figure 12: MyApp.cpp File


Finally, the resource script file looks like:

  
#include "afxres.h"
#include "myapp_ids.h"


/**************************************************** 
 *
 * Dialog
 ****************************************************/

HELLOWORLD DIALOG DISCARDABLE  50, 50, 230, 130
STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | 
    WS_THICKFRAME
CAPTION "Hello World Dialog Box"
FONT 8, "Courier New"
BEGIN
    LTEXT           "This is a slight modification of the Hello World.",IDC_STATIC,10,10,200,8
    LTEXT           "From Ron Holland",IDC_STATIC,70,30,119,8
    DEFPUSHBUTTON   "Hello",IDC_HELLO,6,104,30,15
    PUSHBUTTON      "GoodBye",IDC_GOODBYE,49,104,30,15,NOT WS_TABSTOP
    PUSHBUTTON      "Exit",IDC_EXIT,89,104,30,15,NOT WS_TABSTOP
END
  
Figure 13: Resource Script File


Conclusions

From this tutorial, you should know

  1. How to build a basic hello world template.
  2. The definition of a resource file.
  3. How to define the graphical elements in the resource file.
  4. The definition of an event.
  5. The definition of an event handler.
  6. How associate the graphical elements with the event handlers.

Definitions

AFXWIN - This is a header for the Microsoft Foundation Classes C++ library. It must be included in all MFC applications.

BEGIN_MESSAGE_MAP - Use the BEGIN_MESSAGE_MAP macro to begin the definition of your message map. In the implementation (.CPP) file that defines the member functions for your class, start the message map with the BEGIN_MESSAGE_MAP macro, then add macro entries for each of your message-handler functions, and complete the message map with the END_MESSAGE_MAP macro.

CFrameWnd - The CFrameWnd class encapsulates the functionality of a Windows single document interface (SDI) frame window. A frame window is a window that frames an application.

CWinApp - The CWinApp class is the base class from which you derive a Windows application object. An application object provides member functions for initializing your application (and each instance of it) and for running the application.

CStatic - The CStatic class provides the functionality of a Windows static control. A static control is a control used to display text, to draw frames or lines separating other controls, or to display icons. A static control doesn't accept user input, but it can notify its parent of stylus taps if it's created with SS_NOTIFY style.

CDialog - The CDialog class encapsulates the functionality of a Windows dialog box.

dialog-based - applications that are derived from the CDialog class. The CDialog class encapsulates the functionality of a Windows dialog box.

DEFPUSHBUTTON - The DEFPUSHBUTTON resource-definition statement creates a default push-button control. The control is a small rectangle with a bold outline that represents the default response for the user. This means that if the user presses the enter button while this button has the focus, the program will executes this button's response. The given text is displayed inside the button. The control highlights the button in the usual way when the user clicks the mouse in it and sends a message to its parent window.

DIALOG - The DIALOG resource-definition statement specifies a window that an application can use to create dialog boxes. The statement defines the position and dimensions of the dialog box on the screen as well as the dialog box style.

DECLARE_MESSAGE_MAP() - in the .h file, this indcates that there will be event handlers. The event handlers are defined in the .cpp file.

event handler - an event occurs when a mouse is clicked, double clicked, a button is clicked, a key pressed, etc. Event handler is the code that is called to respond to the event, as a result of a graphical object being clicked.

GUI - graphical user interface is a program interface that uses a computer's graphics functionality to improve the program's ease to use for the end user.

inheritance - is the ability to create a class that derives properties from one or more base classes.

initinstance - Override InitInstance to initialize each new instance of your application running under Windows. Typically, you override InitInstance to construct your main window object and set the CWinThread::m_pMainWnd data member to point to that window.

message box - A message box is a special kind of modal dialog box that an application uses to display messages and prompt for simple input. A message box typically contains a text message and one or more predefined buttons.

m_pMainWnd - Holds a pointer to the application’s main window.

PUSHBUTTON - resource-definition statement creates a push-button control. The control is a round-cornered rectangle containing the given text. The text is centered in the control. The control sends a message to its parent whenever the user chooses the control.

resource files - contains graphical window layouts.

SS_CENTER - Designates a simple rectangle and displays the given text centered in the rectangle. The text is formatted before it is displayed. Words that would extend past the end of a line are automatically wrapped to the beginning of the next centered line.

Template - is a unique class or pattern that can be used to build other software code.

WS_BORDER - Creates a window that has a border.

WS_CAPTION - Creates a window that has a title bar (implies the WS_BORDER style). Cannot be used with the WS_DLGFRAME style.

WS_CHILD - Creates a child window. Cannot be used with the WS_POPUP style.

WS_MAXIMIZEBOX - Creates a window that has a Maximize button.

WS_MINIMIZEBOX - Creates a window that has a Minimize button.

WS_MINIMIZE - Creates a window that is initially minimized. For use with the WS_OVERLAPPED style only.

WS_POPUP - Creates a pop-up window. Cannot be used with the WS_CHILD style.

WS_SYSMENU - Creates a window that has a Control-menu box in its title bar. Used only for windows with title bars.

WS_THICKFRAME - Creates a window with a thick frame that can be used to size the window.

WS_VISIBLE - Creates a window that is initially visible.




[
HOME] Consulting Design Maintenance Project Testing Training Turnkey Java C++ SQL HTML JavaScript ]

© 2002 - 2015 All Rights Reserved Total Application Works