Hello World in C, C++, and Win32

Let us examine the classic program, "Hello World", and take it through the evolution of C to C++ to Win32 to MFC.  This tutorial will hopefully bridge some gaps between the different technologies.  First things first, lets make a C program!

 

main.c - Hello World written in "C"
#include "stdio.h"  // Include the standard C library
                    // which gives us functions like printf
void SayHello() // tell the world hello
{
    printf("Hello World!\n");
}
void SayGoodbye() // tell the world goodbye
{
    printf("Goodbye World!\n");
}
int main()
{
    SayHello();
    SayGoodbye();
    return 0;
}

Notice we define two functions SayHello() and SayGoodbye(), then call these functions from main(), which is our entry point into our program.


Hello World in "C++"

That was simple enough, how would we write this in C++?

main.cpp - Hello World written in "C++"
#include <iostream.h> // Include the standard C++ library
                      // which gives us functions like cout

// Application object which says hello and goodbye
class Application
{
public:
    Application() // say hello when object is constructed
    {
        Say("Hello World!");
    };
    ~Application() // say goodbye when object is destroyed
    {
        Say("Goodbye World!");
    };
    void Say(char* Message)
    {
        cout << Message << endl;
    };
};

// Create out global application object
Application theApp;

// Main function is not really important anymore,
// as all the program logic is contained within
// our the globally constructed application object.
int main()
{   
    return 0;
}

Notice we define an Application class which gets instanciated with the global define of theApp.  Our main function isn't really used, as all our programming logic is contained with the Application class.  When the application class is constructed, it produces the output "Hello World!" and when it is destructed (termination of program) it produces "Goodbye World!"  So, we just implemented the same program using a C++ class.  We also are using the cout object (iostream.h) instead of the C based function printf (stdio.h).


Hello World using "Win32 API"

Now lets take a look at Windows programming.  In order to write a windowed program for Windows 95/98/NT/2000, we use an API called "Win32".  For simplicity lets take the previous example, and instead of sending the output to a console window, we will send the output in the form of message boxes.

main.cpp - Hello World written in "C++" using Win32
#include <windows.h>    // include the Windows API

// Application object which says hello and goodbye
class Application
{
public:
    Application() // say hello when object is constructed
    {
        Say("Hello World!");
    };
    ~Application() // say goodbye when object is destroyed
    {
        Say("Goodbye World!");
    };
    void Say(char* Message)
    {
        // Use the Win32 function MessageBox to
        // display the message with
        // an OK button and an information icon
        MessageBox(NULL,Message,"Application Message", MB_OK |
                   MB_ICONINFORMATION);
    };
};

// Create out global application object
Application theApp;

// WinMain function is the entry point for Win32 programs
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpCmdLine,
                     int nCmdShow)
{
    return 0;
}

We just had to include "Windows.h" and used the Win32 function MessageBox.  Also notice that we are no longer using main, but instead WinMain, which is our entry point to all Windows programs.

 


Hello World using "MFC Library"

Now lets create a window based program that can be minimized, maximized, and resized.  We could demonstrate how to do this using Win32 and C, but let us instead move forward in programming evolution and use a C++ library to help us out.  Microsoft gives us the MFC library (Microsoft Foundation Classes) which can greatly help speed up the development of GUI applications.   The AppWizard in Visual C++ makes it very easy to get started with MFC, which generates skeleton application code which we can build on top of.  But, lets not go the easy way, lets start from scratch and  examine how we can create a MFC program without AppWizard.   Hopefully showing the main concepts behind MFC and its classes will help get you on your way.  We will be using some core MFC architecture classes like CWinApp, CMainFrame, and CWnd.

 
main.cpp - Hello World written in "C++" using MFC
#include <afxwin.h> // include MFC library

//
// CHelloView is paints into the center of its window, "Hello World!"
//
class CHelloView : public CWnd
{
public:
    CHelloView() {};
    virtual ~CHelloView() {};
   
    void OnPaint()    // on paint lets us draw into the view
    {                
        // Output hello world in middle of the window
        CPaintDC dc(this); // device context for painting
        CRect rect;
        GetClientRect(&rect);
        dc.TextOut(rect.right/2 - 40,rect.bottom/2 - 10,"Hello World!");
    }       
    DECLARE_MESSAGE_MAP() // need message map to handle PAINT message
};

//
// CMainFrame is our main frame window which holds our hello view
//
class CMainFrame : public CFrameWnd
{
public:
    CMainFrame() {};
    virtual ~CMainFrame() {};

protected:   
    CHelloView m_wndView;
   
    int OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
        // create our frame window first
        if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;
       
        // create a view to occupy the client area of the frame       
        if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
            CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL)) return -1;
       
        return 0;
    }

    virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
    {
        // let the view have first crack at the command
        if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
            return TRUE;
   
        // otherwise, do default handling
        return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
    }       
    DECLARE_MESSAGE_MAP() // need message map to handle CREATE message
};

//
// Application is our entry point into our MFC program
//
class Application : public CWinApp
{
public:
    Application() {};
   
    virtual BOOL InitInstance() // our entry point into MFC application
    {       
        // To create the main window, this code creates a new frame window
        // object and then sets it as the application's main window object.
        CMainFrame* pFrame = new CMainFrame;
        m_pMainWnd = pFrame;

        // create and load the frame with its resources
        pFrame->Create(NULL,"Hello World Application");
        pFrame->ShowWindow(SW_SHOW);
        return TRUE;
    };
};

BEGIN_MESSAGE_MAP(CHelloView,CWnd )   
    ON_WM_PAINT()    // paint message
END_MESSAGE_MAP()

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    ON_WM_CREATE()    // create message
END_MESSAGE_MAP()

// Create out global application object
Application theApp;

// Notice we have no WinMain, because the MFC library
// implements one for us
Application theApp;
We first include "afxwin.h" which is our main include file for using MFC.  I first create a class called CHelloView which inherits from CWnd.  This class is going to be responsible for painting "Hello World" inside our window.  It is our view which is contained by the frame.  The frame of a window is implemented by CMainFrame and inherits from CFrameWnd.  Its purpose is to create the CHelloView and route our windows messages to it (like WM_PAINT).  In MFC we have the CWinApp, which we inherit from to create our "Application" object.  This is our entry point into an MFC program.  Notice that we don't have to write a WinMain function, the MFC library implements it.  This program will now display Hello World into the center of the window.