Removing the Body of Your Old WinMain Function

Move any special initialization or idle-processing code from your C project's WinMain function (leave behind window class registration, window creation and display, and the message loop). Put the moved code into appropriate overridden CWinApp member functions in the MFC project, such as InitInstance, InitApplication, Run, or ExitApplication. You can put idle processing code into an override of the OnIdle member function. Guidelines:

Note PROJNAME is whatever name you specified for your project in AppWizard.

Once you've removed the code you need to save, delete your entire old WinMain function. You'll rely on MFC's version instead.

Tip C++ allows you to "override" member functions of class A in your derived class B. To override function A::Fun1, derive class B from class A and declare function B::Fun1. For an override, A::Fun1 (or the Fun1 version in one of A's base classes) must be a virtual function; otherwise, you simply hide A's version with B's version. For more details, see To override a class member function

For SHOWDIB, move the following lines of code from the old WinMain function in SHOWDIB.CPP into the InitInstance function in class CShowDibApp, derived from CWinApp (in SHOWD.CPP):


hInst = hInstance ; /* Initialize clip rectangle */ SetRectEmpty(&rcClip); if (!GetProfileString("extensions", "bmp", "", ach, sizeof(ach))) WriteProfileString("extensions", "bmp", "showdib.exe ^.bmp"); if (!GetProfileString("extensions", "dib", "", ach, sizeof(ach))) WriteProfileString("extensions", "dib", "showdib.exe ^.dib"); /* Save the pointer to the command line */ lstrcpy(achFileName, lpCmdLine);

If you're migrating 16-bit SHOWDIB, also move over the following lines:


/* default to MEMORY DIB's if XWindows */ dwWinFlags = GetWinFlags(); bMemoryDIB = (BOOL)(dwWinFlags & WF_PMODE);

You don't have to override InitInstance yourself, because AppWizard does it for you. You'll need to make some changes to support this code in its new location, as described below.

Þ To make the code changes work in SHOWDIB

1. Rename the lpCmdLine variable in the lstrcpy statement to m_lpCmdLine.

For 16-bit SHOWDIB, rename lpszCmdLine to m_lpCmdLine.

This uses a member variable of the MFC application class, CShowDibApp, instead of the old variable. The old variable in SHOWDIB.CPP will be deleted when you delete the old WinMain.

2. Similarly, rename the hInstance variable just before the code that initializes the clip region to m_hInstance, another MFC application class member variable.

3. "Disambiguate" both sets of calls to GetProfileString and WriteProfileString by prefixing a double colon (::) to them:


if (!::GetProfileString("extensions", "bmp", "", ach, sizeof(ach)))
::WriteProfileString("extensions", "bmp", "showdib.exe ^.bmp");

The double colon is the C++ scope resolution operator, which here indicates that the functions are at file scope rather than class scope. In other words, MFC encapsulates or "wraps" these Windows API functions, but the calls here are to the Windows functions, not the wrapped MFC versions. This prevents an error in the number of parameters passed. For more information about disambiguating non-MFC function calls, see Disambiguating Calls to Windows API Functions.

4. Add the following #include to the SHOWD.CPP file:


#include "showdib.h"

5. Move the declaration of the ach local variable from SHOWDIB.CPP to SHOWD.H. In class CShowDibApp (SHOWD.H), add the ach variable to a new "// Attributes" section of the class declaration, as shown below:


class CShowDibApp : public CWinApp { public: CShowDibApp(); // Attributes CHAR ach[40]; // for 16-bit SHOWDIB, it's char // Overrides // ... };

This isn't strictly necessary, but it illustrates a common practice in MFC. Variables that you might ordinarily define as globals are often turned into class member variables. This makes them "global" (at class scope) from the point of view of class member functions but keeps down the clutter of true globals.

6. Delete your old WinMain function completely.

Tip You might want to use MFC naming conventions for consistency. Class names begin with "C". Member variable names begin with "m_" ¾ so the ach variable above should really be m_ach (everywhere). MFC programmers typically also use Hungarian notation. Charles Petzold discusses Hungarian notation in Programming Windows 3.1 (Microsoft Press).