MFC: Getting Started with Visual C++ V

Author: Ronald S. Holland
at
Total Application Works






To visit my site

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


To contact us

© 2002 - 2017 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/GettingStarted_V.html">
    MFC: Getting Started with Visual C++ </a>
    </table>
    </body>
    </html>
    Download Source and see a screen shot


Introduction

In this tutorial, we will add a toolbar to the GUI in our Hello World dialog-based application, and we will expand on the lessons we learned about dialog-based applications. This tutorial relies heavily on the lessons presented in

  1. Getting Started I
  2. Getting Started II
  3. Getting Started III
  4. Getting Started IV
You should be familiar with the concepts covered in the above tutorials. Additional links to dialog-based applications can be found at: If you look in the MSDN Library Visual Studio under CToolBar, you will find an example describing how to add a toolbar under the name of MFC Sample DLGCBR32. I have used the code from that example that describes how to reposition and load a toolbar in this example.

To aid in user interaction, a GUI interface is used. With this type of 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.

If you would be interested in a book on Visual C++ containing over 150 example, feel free to indicate so at: Visual C++ book survey . If you enjoyed this tutorial, feel free to notify a friend.

Requirements

  1. Modify the MFC application template. to create a dialog-based application.
  2. Create a class MyHelloWorld, which is derived from class CWinApp.
    • In class MyHelloWorld, instantiate class MyApp.
  3. Use the updated MFC application template to create a Hello world application.
  4. Create a class MyApp, which is derived from class CDialog.
  5. In class MyApp, create the following methods:
    1. MyApp() - constructor
    2. OnHello() - is the event handler code that is called when the "Hello" push button, the "Hello" toolbar button, or the Hello-Say Hello menuitem is clicked
    3. OnGoodBye() - is the event handler code that is called when the "GoodBye" push button, the "GoodBye" toolbar button, or the GoodBye-Say GoodBye menuitem is clicked
      • The event handler code should display a message box and then exit.
    4. OnExit() - is the event handler code that is called when the "Exit" push button, the "Exit" toolbar button, or the File-Exit menuitem is clicked
      • The event handler code should cause the application to exit.
  6. In the resource file, define the following graphics:
    • A toolbar that contains
      EXIT HELLO GOOD
      BYE
    • Hello push button
    • Goodbye push button
    • Exit push button
    • File popup menu
    • Hello popup menu
      • Contains a "Say Hello" menuitem
    • Goodbye popup menu
      • Contains a "Say Goodbye" menuitem

MFC Application Template

In the Getting Started II tutorial, the header looked like:

  
// define our windows application based on the MFC dialog window 
  
class MyApp : public CDialog 
{
public:
   MyApp()
      : CDialog( "Name-of-dialog-to-be-invoked" )  {}

private:

   DECLARE_MESSAGE_MAP() 
};
 
Figure 1: MFC Application Template


Our header file template for this example will remain essentially the same. The only changes will be the addition of the event handler methods.

In addition, the .cpp file template looked 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 2: cpp file Templatee


With the exception of the event handler code, this file remains the same.

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 Script 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 Getting started IV tutorial, we used the following code to write a static text field, push buttons, and a menu to the screen.

  
  
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      
 


/////////////////////////////////////////////////////////////////////////////
//
// Menu
//

MYAPP_V_M MENU DISCARDABLE 
BEGIN
    POPUP "File"
    BEGIN
        MENUITEM "Exit",                        IDC_EXIT
    END
    POPUP "Hello"
    BEGIN
        MENUITEM "Say Hello",                   IDC_HELLO
    END
    POPUP "Goodbye"
    BEGIN
        MENUITEM "Say Goodbye",                 IDC_GOODBYE
    END
END
 
Figure 3: Resource Script File


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

Adding a Toolbar to our Hello World Application

To add a toolbar to our application, we will

  1. Add a Toolbar definition to the resource file.
  2. Add a Toolbar bitmap definition to the resource file.
  3. Create a CToolBar object named m_toolBar in the MyApp_V.h header file.
  4. Declare a virtual BOOL OnInitDialog() method in the MyApp_V.h header file.
  5. Implement the virtual BOOL OnInitDialog() method.

Add a Toolbar definition to the resource file.

A toolbar definition in our resource file will be similar to how we added the menu definition. It looks like:

  
/////////////////////////////////////////////////////////////////////////////
//
// Toolbar
//

IDR_TOOLBAR1 TOOLBAR DISCARDABLE  89, 41
BEGIN
    BUTTON      IDT_EXIT
    BUTTON      IDT_HELLO
    SEPARATOR
    BUTTON      IDT_GOODBYE
    BUTTON      IDT_EXTRA
END
  

Add a Toolbar bitmap definition to the resource file.

A toolbar definition in our resource file will be simialr to how we added the toolbar definition. It looks like:

  
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//

IDR_TOOLBAR1            BITMAP  DISCARDABLE     "res\\toolbar1.bmp"

  
Figure 4: Resource Script File


Create a CToolBar object named m_toolBar in the MyApp_V.h header file.

To create a CToolBar object, we implement the following code.

  
CToolBar	m_toolBar;
  

Declare a virtual BOOL OnInitDialog() method in the MyApp_V.h header file.

To declare a virtual BOOL OnInitDialog() method, we write the following code.

  
virtual BOOL OnInitDialog();
  
Figure 5: virtual BOOL OnInitDialog() method


Implement the virtual BOOL OnInitDialog() method.

To implement a virtual BOOL OnInitDialog() method, we write the following code.

  
/*****************************************************
 * 1- Overwrite OnInitDialog() method
 *    - This member function is called in response to 
 *      the WM_INITDIALOG message. This message is sent 
 *      to the dialog box during the Create, CreateIndirect, 
 *      or DoModal calls, which occur immediately before the 
 *      dialog box is displayed.
 * 2- Create toolbar at the top of the dialog window
 * 3- m_toolBar is the CToolbar object
 * 4- IDR_TOOLBAR1 is the resource ID 
 *    - IDR_TOOLBAR1 is the name of the toolbar
 *    - IDR_TOOLBAR1 is also the name of the toolbar bitmap
 * 5- This method can be used asis as long as the toolbar and the 
 *    toolbar and the bitmap ae named IDR_TOOLBAR1. If you use 
 *    another name for them, change every IDR_TOOLBAR1 reference
 *    to the name you have chosen.
 * 
 *****************************************************/


BOOL MyApp_V::OnInitDialog() {

   CDialog::OnInitDialog();

    // Create toolbar at the top of the dialog window
	if(!m_toolBar.Create(this) || 
		!m_toolBar.LoadToolBar(IDR_TOOLBAR1)) {
       TRACE0("Failed to Create Dialog Toolbar\n");
	   EndDialog(IDCANCEL);
	}

	m_toolBar.SetBarStyle(m_toolBar.GetBarStyle() |
		CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);

	// We need to resize the dialog to make room for control bars.
	// First, figure out how big the control bars are.
	CRect rcClientStart;          // current client area
	CRect rcClientNow;            // New client area

	GetClientRect(rcClientStart);  // get client area

        // Called to reposition and resize control bars in the 
        // client area of a window. 
	RepositionBars(AFX_IDW_CONTROLBAR_FIRST, 
		           AFX_IDW_CONTROLBAR_LAST,
				   0, 
				   reposQuery, 
				   rcClientNow);

	// Now move all the controls so they are in the same relative
	// position within the remaining client area as they would be
	// with no control bars.
	CPoint ptOffset(rcClientNow.left - rcClientStart.left,
					rcClientNow.top - rcClientStart.top);

	CRect  rcChild;

        // The GetWindow function retrieves a handle to a window 
        // that has the specified relationship (Z order or owner) to the specified window. 
        // The retrieved handle identifies the child window at 
        // the top of the Z order
	CWnd* pwndChild = GetWindow(GW_CHILD);
	while (pwndChild)
	{
		pwndChild->GetWindowRect(rcChild);
                // Convert the screen coordinates of a given point 
                // or rectangle on the display to client coordinates.
		ScreenToClient(rcChild);
                // Moves CRect by the specified offsets.
		rcChild.OffsetRect(ptOffset);
		pwndChild->MoveWindow(rcChild, FALSE);
		pwndChild = pwndChild->GetNextWindow();
	}

	// Adjust the dialog window dimensions
	CRect rcWindow;
	GetWindowRect(rcWindow);
	rcWindow.right += rcClientStart.Width() 
		                - rcClientNow.Width();
	rcWindow.bottom += rcClientStart.Height()
		                 - rcClientNow.Height();

        // Change the window’s size and position.
	MoveWindow(rcWindow, FALSE);

	// And position the control bars
	RepositionBars(AFX_IDW_CONTROLBAR_FIRST, 
		           AFX_IDW_CONTROLBAR_LAST, 
				   0);

	// Finally, center the dialog on the screen
	CenterWindow();

    return TRUE;  // return TRUE  unless you set the focus to a control
}

  
Figure 6: Toolbar added to the Resource Script File


You can use this code algorithm without modification.

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_V.h defines MyApp class
MyApp_V.cpp implements MyApp class
MyApp_V.rc implements the graphical units in MyApp app.
MyApp_ids_V.h defines MyApp graphical units
Figure 7: Getting Started V Source Files


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_V.h
 *******************************************************/

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

   
   virtual BOOL OnInitDialog();
   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:

   CToolBar	m_toolBar;


   DECLARE_MESSAGE_MAP()
};
  
Figure 8: MyApp_V.h Header File


The MyApp_ids.h file looks like:

  

/**********************************************************
 * File: MyApp_IV_ids.h
 ***********************************************************/

#define IDC_LABEL          2000
#define IDC_HELLO          2001
#define IDC_GOODBYE        2002
#define IDC_EXIT           2003

#define IDT_HELLO          2010
#define IDT_GOODBYE        2011
#define IDT_EXIT           2012
#define IDM_EXTRA          2013
#define IDR_TOOLBAR1       2014
  
Figure 9: MyApp_ids_V.h Header File


And the following .cpp file looks like.

  
/*************************************************************
 * File: MyApp_V.cpp
 *************************************************************/

// include application framework windows class definitions:
#include <afxwin.h>
#include "stdafx.h"
#include "MyApp_V.h"
#include "MyApp_V_ids.h"


/*****************************************************
 * 1- Overwrite OnInitDialog() method
 * 2- Create toolbar at the top of the dialog window
 * 3- m_toolBar is the CToolbar object
 * 4- IDR_TOOLBAR1 is the resource ID 
 * 
 *****************************************************/


BOOL MyApp_V::OnInitDialog() {

   CDialog::OnInitDialog();

        // Create toolbar at the top of the dialog window
      if(!m_toolBar.Create(this) || 
		!m_toolBar.LoadToolBar(IDR_TOOLBAR1)) {
         TRACE0("Failed to Create Dialog Toolbar\n");
         EndDialog(IDCANCEL);
      }

      m_toolBar.SetBarStyle(m_toolBar.GetBarStyle() |
		CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);

	// We need to resize the dialog to make room for control bars.
	// First, figure out how big the control bars are.
      CRect rcClientStart;          // current client area
      CRect rcClientNow;            // New client area

      GetClientRect(rcClientStart);  // get client area

        // Called to reposition and resize control bars in the 
        // client area of a window. 
      RepositionBars(AFX_IDW_CONTROLBAR_FIRST, 
		           AFX_IDW_CONTROLBAR_LAST,
		           0, 
		           reposQuery, 
		           rcClientNow);

         // Now move all the controls so they are in the same relative
         // position within the remaining client area as they would be
         // with no control bars.
      CPoint ptOffset(rcClientNow.left - rcClientStart.left,
					rcClientNow.top - rcClientStart.top);

      CRect  rcChild;

         // The GetWindow function retrieves a handle to a window 
         // that has the specified relationship (Z order or owner) to the specified window. 
         // The retrieved handle identifies the child window at 
         // the top of the Z order
      CWnd* pwndChild = GetWindow(GW_CHILD);
      while (pwndChild) {
         pwndChild->GetWindowRect(rcChild);
         ScreenToClient(rcChild);
         rcChild.OffsetRect(ptOffset);
         pwndChild->MoveWindow(rcChild, FALSE);
         pwndChild = pwndChild->GetNextWindow();
      }

         // Adjust the dialog window dimensions
      CRect rcWindow;
      GetWindowRect(rcWindow);
      rcWindow.right += rcClientStart.Width() 
		                - rcClientNow.Width();
      rcWindow.bottom += rcClientStart.Height()
		                 - rcClientNow.Height();
      MoveWindow(rcWindow, FALSE);

         // And position the control bars
      RepositionBars(AFX_IDW_CONTROLBAR_FIRST, 
                     AFX_IDW_CONTROLBAR_LAST, 
                     0);

         // Finally, center the dialog on the screen
      CenterWindow();

      return TRUE;  // return TRUE  unless you set the focus to a control
}


//****************************************
 * When the Hello menu item is selected
 * or the Hello button is pressed, the
 * OnHello() event handler is called.
 ****************************************/
   afx_msg void MyApp_V::OnHello() {
      MessageBox("Hello World",
               "Hello World\n from\nRon Holland",
               MB_ICONEXCLAMATION ); 
}

/****************************************
 * When the GoodBye menu item is selected
 * or the GoodBye button is pressed, the
 * OnGoodBye() event handler is called.

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

   OnExit() ;

}

/****************************************
 * When the GoodBye menu item is selected
 * or the GoodBye button is pressed, the
 * OnGoodBye() event handler is called.
 ***************************************/
afx_msg void MyApp_V::OnExit() {
           // Exit the dialog
   OnOK();
}

/****************************************
 * BEGIN_MESSAGE_MAP defines the event 
 * handlers. It indirectly associates
 * events with event handler  through IDs.
 ***************************************/

BEGIN_MESSAGE_MAP( MyApp_V, CDialog )
   ON_COMMAND( IDC_HELLO, OnHello )
   ON_COMMAND( IDC_GOODBYE, OnGoodBye )
   ON_COMMAND( IDC_EXIT, OnExit )
   ON_COMMAND( IDT_HELLO, OnHello )
   ON_COMMAND( IDT_GOODBYE, OnGoodBye )
   ON_COMMAND( IDT_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_V  myapp;    // instantiate MyApp
     myapp.DoModal();           

     return true;                          // report success
   }

} helloWorldApp;     

  
Figure 10: MyApp_V.cpp File


Conclusion

From this tutorial, you should know the following:

  1. How to build a basic dialog-based hello world template.
  2. How to build 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.

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.

DoModal - Call this member function to invoke the modal dialog box and return the dialog-box result when done. This member function handles all interaction with the user while the dialog box is active. This is what makes the dialog box modal; that is, the user cannot interact with other windows until the dialog box is closed.

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.

MENUITEM - The MENUITEM resource-definition statement creates a menu item.

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.

POPUP - The POPUP resource-definition statement creates a menu item that can contain menu items and submenus.

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.

toolbar - A set of buttons that you click to carry out common tasks. Objects of the class CToolBar are control bars that have a row of bitmapped buttons and optional separators. The buttons can act like pushbuttons, check-box buttons, or radio buttons.

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 C#

© 2002 - 2017 All Rights Reserved Total Application Works

##################################################### #####################################################