Mfc Application Tutorial

Mfc Application Tutorial 8,8/10 5991 reviews

This is a continuation from the previous module. Program examples compiled using Visual C++ 6.0 (MFC 6.0) compiler on Windows XP Pro machine with Service Pack 2. Topics and sub topics for this Tutorial are listed below:

Nov 04, 2016  Choose MFC Application from the center pane. Modify the configuration values as needed, then press Finish. For more information, see Creating a Forms-Based MFC Application. To create an MFC console application. An MFC console application is a command-line program that uses MFC libraries but runs in the console window. The MFC code library used by Visual C is stored in a.DLL. An MFC extension.DLL dynamically links to the MFC code library.DLL. The client application must also dynamically link to the MFC code library.DLL. As the years have gone by the MFC library has grown. As a result, there are a few different versions of the MFC code library.DLL out. Visual C/MFC Tutorial - Lesson 4: MFC Basics. You don't want me to teach you a stupid 'hello world' application, do you? If you want to make the most of Visual C you have to use Microsoft Foundation Classes (MFC). These classes are great because they wrap all of those handles we talked about in the first lesson with easy to use classes. Step by Step Guide for Graphics Programming using Microsoft Foundation Classes (MFC) MFC Step-by-Step Guide. MAIN MENU » TUTORIAL 1 TUTORIAL 2 Tutorial 1 Simple Dialog Based MFC Application GOAL: To gain understanding of the GUI API and basic MFC Dialog Window PREREQUISITES: none.

The Gallery

The Visual C++ Components and Controls Gallery lets you share software components among different projects. The Gallery manages three types of modules:

  • ActiveX controls: When you install an ActiveX control (OCX - formerly OLE control), an entry is made in the Windows Registry. All registered ActiveX controls appear in the Gallery's window, so you can select them in any project.

  • C++ source modules: When you write a new class, you can add the code to the Gallery. The code can then be selected and copied into other projects. You can also add resources to the Gallery.

  • Visual C++ components: The Gallery can contain tools that let you add features to your project. Such a tool could insert new classes, functions, data members, and resources into an existing project. Some component modules are supplied by Microsoft (Idle time processing, Palette support, and Splash screen, for example) as part of Visual C++. Others will be supplied by third-party software firms.

Figure 18: Visual C++ Components and Controls Gallery.

If you decide to use one of the prepackaged Visual C++ components, try it out first in a dummy project to see if it's what you really want. Otherwise, it might be difficult to remove the generated code from your regular project. All user-generated Gallery items can be imported from and exported to OGX files. These files are the distribution and sharing medium for Visual C++ components.

ATL is a tool, separate from MFC, for building ActiveX controls. You can build ActiveX controls with either MFC or ATL, but ATL controls are much smaller and quicker to load on the Internet.

The Microsoft Foundation Class Library

The Microsoft Foundation Class Library (the MFC library, for short) defines the application framework that you'll be learning in this Tutorial. MFC provides a variety of classes designed to serve a wide range of needs. You'll find a handy diagram of the MFC 7.0 class hierarchyhere. The majority of MFC classes are derived, either directly or indirectly, from CObject.CObject provides other useful benefits to its derived classes as well. For example, it overloads the new and delete operators to provide protection against memory leaks. If you create an object from a CObject-derived class and fail to delete it before the application terminates, MFC will warn you by writing a message to the debug output window. The overarching importance of this most basic of MFC classes will become increasingly clear as you grow more familiar with MFC.

One definition of application framework is 'an integrated collection of object-oriented software components that offers all that's needed for a generic application.' That isn't a very useful definition, is it? If you really want to know what an application framework is, you'll have to read the rest of this book. The application framework example that you'll familiarize yourself with later in this chapter is a good starting point.

An Application Framework vs. a Class Library

One reason that C++ is a popular language is that it can be 'extended' with class libraries. Some class libraries are delivered with C++ compilers, others are sold by third-party software firms, and still others are developed in-house. A class library is a set of related C++ classes that can be used in an application. A mathematics class library, for example, might perform common mathematics operations, and a communications class library might support the transfer of data over a serial link. Sometimes you construct objects of the supplied classes; sometimes you derive your own classes, it all depends on the design of the particular class library.

An application framework is a superset of a class library. An ordinary library is an isolated set of classes designed to be incorporated into any program, but an application framework defines the structure of the program itself. Microsoft didn't invent the application framework concept. It appeared first in the academic world, and the first commercial version was MacApp for the Apple Macintosh. Since MFC 2.0 was introduced, other companies, including Borland, have released similar products.

An Application Framework Example

It's time to look at some code, not pseudocode but real code that actually compiles and runs with the MFC library. It's the good old 'Hello, world!' application, with a few additions. It's about the minimum amount of code for a working MFC library application for Windows. You don't have to understand every line now. This is Single Document Interface (SDI) without Document /View architecture support application and the full steps to build this program are given in Example 1. By convention, MFC library class names begin with the letter C. Following is the source code for the header and implementation files for our MYAPP application (all the Visual C++ comments have been deleted). The classes CMyApp and CMyFrame are each derived from MFC library base classes. The first is the MyApp.h header file for the MYAPP application:

// MyApp.h

// application class

class CMyApp : public CWinApp

{

public:

virtual BOOL InitInstance();

};

// frame window class

class CMyFrame : public CFrameWnd

{

public:

CMyFrame();

protected:

// 'afx_msg' indicates that the next two functions are part

// of the MFC library message dispatch system

afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

afx_msg void OnPaint();

DECLARE_MESSAGE_MAP()

};

And here is the MyApp.cpp implementation file for the MYAPP application:

#include <afxwin.h> // MFC library header file declares base classes

#include 'myapp.h'

CMyApp theApp;// the one and only CMyApp object

BOOL CMyApp::InitInstance()

{

m_pMainWnd = new CMyFrame();

m_pMainWnd->ShowWindow(m_nCmdShow);

m_pMainWnd->UpdateWindow();

return TRUE;

}

BEGIN_MESSAGE_MAP(CMyFrame, CFrameWnd)

ON_WM_LBUTTONDOWN()

ON_WM_PAINT()

END_MESSAGE_MAP()

CMyFrame::CMyFrame()

{

Create(NULL, 'MYAPP Application');

}

void CMyFrame::OnLButtonDown(UINT nFlags, CPoint point)

{

TRACE('Entering CMyFrame::OnLButtonDown - %lx, %d, %dn', (long) nFlags, point.x, point.y);

}

void CMyFrame::OnPaint()

{

CPaintDC dc(this);

dc.TextOut(0, 0, 'Hello, world!');

}

Here are some of the program elements:

The WinMain() function: Remember that Windows requires your application to have a WinMain() function. You don't see WinMain() here because it's hidden inside the application framework.

The CMyApp class: An object of class CMyApp represents an application. The program defines a single global CMyApp object, theApp. The CWinApp base class determines most of theApp's behavior.

Application startup: When the user starts the application, Windows calls the application framework's built-in WinMain() function, and WinMain() looks for your globally constructed application object of a class derived fromCWinApp. Don't forget that in a C++ program global objects are constructed before the main program is executed.

The CMyApp::InitInstance member function: When theWinMain() function finds the application object, it calls the virtual InitInstance() member function, which makes the calls needed to construct and display the application's main frame window. You must overrideInitInstance() in your derived application class because the CWinApp base class doesn't know what kind of main frame window you want.

The CWinApp::Run member function: TheRun() function is hidden in the base class, but it dispatches the application's messages to its windows, thus keeping the application running. WinMain() calls Run() after it calls InitInstance().

The CMyFrame class: An object of classCMyFrame represents the application's main frame window. When the constructor calls theCreate() member function of the base class CFrameWnd, Windows creates the actual window structure and the application framework links it to the C++ object. The ShowWindow() and UpdateWindow() functions, also member functions of the base class, must be called in order to display the window.

The CMyFrame::OnLButtonDown function: This function is a sneak preview of the MFC library's message-handling capability. We've elected to 'map' the left mouse button down event to a CMyFrame member function. You'll learn the details of the MFC library's message mapping inModule 3. For the time being, accept that this function gets called when the user presses the left mouse button. The function invokes the MFC libraryTRACE macro to display a message in the debugging window.

The CMyFrame::OnPaint function: The application framework calls this important mapped member function of class CMyFrame every time it's necessary to repaint the window: at the start of the program, when the user resizes the window, and when all or part of the window is newly exposed. The CPaintDC statement relates to the Graphics Device Interface (GDI) and is explained in later chapters. The TextOut() function displays 'Hello, world!'.

Application shutdown: The user shuts down the application by closing the main frame window. This action initiates a sequence of events, which ends with the destruction of theCMyFrame object, the exit from Run(), the exit from WinMain(), and the destruction of the CMyApp object.

Look at the code example again. This time try to get the big picture. Most of the application's functionality is in the MFC library base classes CWinApp and CFrameWnd. In writing MYAPP, we've followed a few simple structure rules and we've written key functions in our derived classes. C++ lets us 'borrow' a lot of code without copying it. Think of it as a partnership between us and the application framework. The application framework provided the structure, and we provided the code that made the application unique. Now you're beginning to see why the application framework is more than just a class library. Not only does the application framework define the application structure but it also encompasses more than C++ base classes. You've already seen the hidden WinMain() function at work. Other elements support message processing, diagnostics, DLLs, and so forth.

Convention

The notation used in MFC is mix of theHungarian andCamelCase. If you already got familiar with the MFC/Windows programming, you will recognize the codes such as variables, classes, objects etc. based on the notations used. For example, MFC library class names begin with the letter C such as CScrollView and variables prefixed with m_.

Object ID Naming Conventions

There are several categories or types of IDs found in Windows applications. The MFC ID-naming convention defines different prefixes for different resource types. MFC uses the prefix 'IDR_' to refer to a resource ID that applies to multiple resource types. For example, for a given frame window, the same 'IDR_' value is used to refer to a menu, accelerator, string and icon resource all at once.

Object ID

Description

IDR_

Multiple resource types (Used for Menus, Accelerators primarily).

IDD_

For dialog template resources (for example, IDD_DIALOG1).

IDC_

For Cursor resources.

IDI_

For Icon resources.

IDB_

For Bitmap resources.

IDS_

For String resources.

Table 1.

Note that the IDS_ value for a string resource is the ID passed to LoadString. The actual implementation of string table resources groups together 16 strings into one segment. For example, within a DIALOG resource, we follow the convention of:

Object ID

Note: The following tables cover the Class 1,2,3 machines only. If you have a Burroughs Portable Adding Machine, follow the link to Dates for Portables. From The American Digest of Business Machines (1924) Serial Numbers (approx. 1915 to 1927): The serial number is stamped on the front of the base of every machine. Burroughs adding machine values.

Description

IDOK , IDCANCEL

For standard push button IDs.

IDC_

For other dialog controls.

Table 2.

The 'IDC_' prefix is also used for cursors. This naming conflict is not usually a problem since a typical application will have few cursors and a large number of dialog controls. Within a Menu resource, we follow the convention of:

Object ID

Description

IDM_

For menu items not using the MFC command architecture.

ID_

For menu item commands using the MFC command architecture.

Table 3.

Commands that follow the MFC command architecture must have an ON_COMMAND command handler and may have an ON_UPDATE_COMMAND_UI handler. If these command handlers follow the MFC command architecture, they will function correctly whether they are bound to a menu item, a toolbar button or a dialog bar button. The same ID_ is also used for a menu prompt string displayed on the program's message bar. Most of the menu items in your application should follow the MFC command convention. All of the standard command IDs (for example, ID_FILE_NEW) follow this convention. MFC also uses 'IDP_' as a specialized form of strings (that is, instead of 'IDS_'). Strings with the 'IDP_' prefix are 'prompts,' that is, strings used in message boxes. 'IDP_' strings may contain '%1' and '%2' as place holders of strings determined by the program. 'IDP_' strings usually have help topics, while 'IDS_' strings do not. 'IDP_' strings are always localized, while 'IDS_' strings may or may not be localized. The MFC library also uses the 'IDW_' prefix as a specialized form of control IDs (that is, instead of 'IDC_'). These IDs are assigned to child windows such as views and splitters by the framework classes. MFC implementation IDs are prefixed with 'AFX_'.

Object ID-Numbering Convention

The following lists the valid ranges for the IDs of the specific types. Some of the limits are technical implementation limits while others are just conventions to prevent your IDs from colliding with Windows predefined IDs or MFC default implementations. We strongly recommend you do not defined IDs outside the recommended ranges. Even though the lower limit of many of these ranges is 1 (0 is not used), common convention starts practical use of IDs at 100 or 101.

Prefix

Resource type

Valid range

IDR_

multiple

1 → 0x6FFF

IDD_

dialog templates

1 → 0x6FFF

IDC_,IDI_,IDB_

cursors, icons, bitmaps

1 → 0x6FFF

IDS_,IDP_

general strings

1 → 0x7FFF

ID_

commands

0x8000 → 0xDFFF

IDC_

controls

8 → 0xDFFF

Table 4.

Reasons for these range limits:

  • By convention, the ID value of 0 is not used.

  • Windows implementation limitations restrict true resource IDs to be less than or equal to 0x7FFF.

  • MFC's internal framework implementations reserve several ranges: 0xE000 → 0xEFFF and 0x7000 → 0x7FFF.

  • Several Windows system commands use the range of 0xF000 → 0xFFFF.

  • Control IDs of 1→7 are reserved by IDOK, IDCANCEL, and so on.

  • The range of 0x8000→0xFFFF for strings is reserved for menu prompts for commands.

Program Examples 1

Let go straight to the program example using MFC. This is a Single Document Interface (SDI) 'Hello, world!' classic example. The application has only one window, an object of a class derived from CFrameWnd. All drawing occurs inside the frame window and all messages are handled there. This just a warm up session and we are using AppWizard that can automate most of our task in building Windows application. Follow the steps one-by-one.

Launch your Visual C++, click the File menu and click the New… sub menu. Click the Projects tab for the AppWizard as shown below. Select the MFC AppWizard (exe), type your project name and set the project location as needed. Leave other setting as default and click the OK button.

---------------------------------------------------------------------------------------------------------------------------------------------

Figure 19: AppWizard dialog.

The wizard has 6 steps and you can exit at any step. Select the Single document radio button and uncheck the Document/View architecture support then click Next button.

Figure 20: Visual C++ AppWizard step 1 of 6.

Select the None radio button for database support. Click the Next button. We are going to create the simplest project.

Figure 21: Visual C++ AppWizard step 2 of 6.

Uncheck the ActiveX Controls. Just to make our code simpler.

Figure 22: Visual C++ AppWizard step 3 of 6.

Accept the defaults and click the Next button.

Accept the defaults and click Next button.

Figure 24: Visual C++ AppWizard step 5 of 6.

The following are the classes that will be generated (also the related files created) for our project. Click the Next button.

Figure 25: Visual C++ AppWizard step 6 of 6.

Finally the summary of the project settings. Click the OK button.

Figure 26: Visual C++ AppWizard project summary.

Expand all folders in the FileView and double click the ChildView.cpp. FileView displays all the project files that can be edited, logically. Physically, there are more projects’ files.

Figure 27: Visual C++ FileView.

Add code to paint in the dialog. Add the following code to the CChildView::OnPaint function in the ChildView.cpp source code file:

void CChildView::OnPaint()

{

CPaintDC dc(this); // device context for painting

dc.TextOut(0, 0, 'Hello, world!');

// Do not call CWnd::OnPaint() for painting messages

}

Listing 1.

Compile and run. You now have a complete SDI application that has no dependencies on the document-view architecture.

Figure 28: Visual C++ 'Hello world' output.

Program Examples 2

The following is another classic example using MFC AppWizard, and Visual C++ to create, build, and run a simple MFC-based single document interface (SDI) Scribble application. We just dealing with the View part of the Document/View architecture. We will learn more detail about the Document/View architecture later.

Use MFC AppWizard to create a new project

  1. In Visual C++/Visual Studio, on the File menu, click New.

  2. In the New dialog box, click the Projects tab, and then do the following:

  • For the project type, select MFC AppWizard (exe).

  • For the project name, type myscribble.

  • Set the location for your project as needed.

  • Accept the default platform Win32.

  • Click OK to create the new project workspace. MFC AppWizard starts.

  1. In MFC AppWizard Step 1, click Single document and English, leave the Document/View architecture support checkbox selected, and then click Next to go to Step 2.

  2. Because this project does not need database support, accept the default None for database support and click Next to go to Step 3.

  3. In Step 3, accept None for the document support, because we are not going to create a compound document that using Object Linking and Embedding (OLE), clear the ActiveX Controls check box, and then click Next to go to Step 4.

  4. In Step 4, clear the Printing and print preview check box, accept the defaults (Docking toolbar, Initial status bar, 3D controls, and 4 files for the recent file list) and then click Next to go to Step 5.

  5. In Step 5, leave the project style as MFC Standard, click Yes, please for generating source file comments and select As a shared DLL for MFC support. Click Next to go to Step 6.

  6. In Step 6, click Finish to display the New Project Information dialog box summarizing your choices.

  7. To create the application files with MFC AppWizard, click OK.

When MFC AppWizard is finished, you will be returned to Visual C++/Visual Studio. To see the classes that MFC AppWizard created, click the ClassView tab in theProject Workspace window.

Add message handlers that will handle several mouse clicking and dragging events. This just the skeleton, we will add the real codes later – myscribbleView.cpp file.

  1. On the View menu, click ClassWizard. The MFC ClassWizard property page appears.

  2. In the Message Maps tab, in the combo boxes provided on the property page, select the myscribble project, theCMyscribbleView class, and the CMyscribbleView Object ID.

  3. We are going to add member functions in the CMyscribbleView class. In the Messages list box, select the WM_LBUTTONDOWN message and click Add Function.

  4. Repeat Step 3 for the WM_MOUSEMOVE and WM_LBUTTONUP messages.

  5. Click OK to close ClassWizard.

Implement OnLButtonDown,OnMouseMove, and OnLButtonUp handlers. This is the real codes that will implement the mouse clicking and dragging events.

  1. Declaring variables in the declaration part. Open MyscribbleView.h (or use the ClassView).

  2. In the public attributes section of theCMyscribbleView class declaration, define startpt and endpt variables as follows:

CPoint startpt, endpt;

Or by using the ClassView, select the CMyscribbleView and right click, select the Add Member Variable:

Figure 29: Adding a member variable through the ClassView.

Figure 30: Add member variable dialog.

  1. Save MyscribbleView.h.

  2. Then, the implementation codes in the implementation part. Open MyscribbleView.cpp.

  3. In the constructor, initialize startpt and endpt coordinates to –1 as follows:

startpt = -1;

endpt = -1;

Figure 31: Scribble code segment.

  1. Scroll to the OnLButtonDown handler.

  2. In the OnLButtonDown handler, save the point where the mouse button is pressed as the start point:

startpt.x = point.x;

startpt.y = point.y;

  1. Scroll to the OnMouseMove handler.

  2. In the OnMouseMove handler, add the following code to draw a line from the previous detected point in the mouse drag to the current point:

CClientDC dc(this);

endpt.x = point.x;

endpt.y = point.y;

if (startpt.x != -1)

{

dc.MoveTo(startpt.x, startpt.y);

dc.LineTo(endpt.x, endpt.y);

startpt.x = endpt.x;

startpt.y = endpt.y;

}

  1. In the OnLButtonUp handler, add code to reinitialize the variable startpt as follows:

startpt = -1;

Listing 3: Scribbles’ C++ code segment.

Microsoft Mfc Tutorial

Build and run the project

  1. On the Build menu, click Build Myscribble.exe. Visual Studio displays the status of the build process as it builds your project.

  2. After the build is complete, on the Build menu, click Execute Myscribble.exe. The Scribble application starts. Try writing something using your mouse.

Figure 32: Visual C++’s Scribble program output.

Since its introduction in 2002, people’s attention has focused on the many new features that have formed part of Microsoft .NET, such as the major changes to Microsoft Visual Basic (Visual Basic .Net), the introduction of C#, the new ASP.NET and ADO.NET models, and the increased use of XML. So, from application framework we are introduced the next level, .Net framework (currently version 2.0). C++ developers need not feel left out, however, because a lot of the new features in Microsoft Visual C++ .NET make C++ a first-class member of the .NET family of programming languages. This new functionality is called the Managed Extensions for C++, and as well as providing C++ programmers with access to all the functionality in the .NET class libraries, it also lets you interoperate with existing C++ code, COM objects, and the Win32 API.

Managed vs. Unmanaged Code

Code and data that live in the .NET world are calledmanaged because locations and lifetimes are managed by the common language runtime (CLR). Code and data that exist outside of .NET are called unmanaged, because there is no central mechanism for managing their lifetimes.

Figure 33: Enabling/disabling the /clr for managed/unmanaged code in Visual C++ .Net through the project properties.

Figure 34: Enabling/disabling the /clr in Visual C++ .Net.

Sometimes you have to mix the two, calling existing unmanaged code from within .NET. The .NET Framework is the new library of classes that you use to build Windows applications. It is large, quite complex, and far-reaching in its scope. For MFC programming we do not use the /clr (can be enabled in the Visual C++ .Net: Project menu your_project_name PropertiesGeneralUse Managed ExtensionsYes/No, as shown in the above Figures), that is unmanaged. The managed code will be used in the .Net programming and don’t confused that .Net framework is not compiler, it is framework. All program examples used in this Tutorial series are unmanaged and we are using Visual C++ 6.0. The managed code used in Visual C++ .Net provided that the /clr is used.

Further reading and digging:

  1. MSDN MFC 7.0 class library online documentation.

  2. MSDN What's New (MFC Feature Pack) - feature pack.

  3. Porting & Migrating your older programs.

  4. DCOM at MSDN.

  5. COM+ at MSDN.

  6. COM at MSDN.

  7. Windows data type.

  8. Win32 programming Tutorial.

  9. The best of C/C++, MFC, Windows and other related books.

  10. Unicode and Multi-byte character set: Story and program examples.

Desktop-as-a-Service Designed for Any Cloud ? Nutanix Frame


Environment: Visual C++

At one point in time, before COM, before ATL, programmers used ordinary .DLLs instead. You could do a lot with a .DLL. If you had several programs that used the same functions or other resources, you could save space by putting those resources in a .DLL. Putting code used by multiple programs in a single .DLL often saved maintenance time because the code was all in one place. Fixes and other modifications would only have to be done one time. If you had a program which needed to run different routines at different times, you could put those routines into .DLLs and have the application load the appropriate .DLL when it was needed. There were lots of good reasons to use .DLLs.

There are still a lot of good reasons to use .DLLs. They haven't gone away. Sure, whatever you can do with a .DLL, you can probably do with a COM object. Granted, there are a number of shortcomings to .DLLs, some of them serious, which is why we ended up with COM in the first place. Still, .DLLs remain a very useful tool. Compared to COM and ATL, they are much easier to make. Learning COM or ATL requires a serious investment of time and effort. Making a .DLL is relatively easy. Modifying one is easy too. If you know some C++ and MFC, you could be making .DLLs today.

Mfc Dialog Application Tutorial

This article will review the types of .DLLs you can make with MFC, including when to use each type and how to make them. In the next article there will be a discussion of the limitations of .DLLs (which led to the rise of COM and ATL), and how these can be partially avoided. In the third article, there will be more coding details and examples.

Different types of .DLLs

There are two kinds of .DLLs you can make using MFC: an MFC extension .DLL or a regular .DLL. Regular .DLLs in turn come in two varieties: dynamically linked or statically linked. Visual C++ also allows you to make a generic Win32 .DLL, but in this article I'm only going to discuss the MFC-based .DLL types.

C++ Mfc Tutorial

MFC extension .DLLs

Every .DLL has some kind of interface. The interface is the set of the variables, pointers, functions or classes provided by the .DLL which you can access from the client program. They are the things that allow the client program to use the .DLL. An MFC extension .DLL can have a C++ style interface. That is, it can provide ('export') C++ functions and entire C++ classes to be used by the client application. The functions it exports can use C++ or MFC data types as parameters or as return values. When it exports a class, the client will be able to create objects of that class or derive new classes from it. Inside the .DLL, you can also use MFC and C++.

The MFC code library used by Visual C++ is stored in a .DLL. An MFC extension .DLL dynamically links to the MFC code library .DLL. The client application must also dynamically link to the MFC code library .DLL. As the years have gone by the MFC library has grown. As a result, there are a few different versions of the MFC code library .DLL out there. Both the client program and the extension .DLL must be built using the same version of MFC. Therefore, for an MFC extension .DLL to work, both the extension .DLL and the client program must dynamically link to the same MFC code library .DLL, and this .DLL must be available on the computer where the application is running.

Note: If you have an application which is statically linked to MFC, and you wish to modify it so that it can access functions from an extension .DLL, you can change the application to dynamically link to MFC. In Visual C++, select 'Project Settings' from the menu. On the 'General' settings tab you can change your application to dynamically link to MFC.

MFC extension .DLLs are very small. You can build an extension .DLL which exports a few functions or small classes and has a size of 10-15 KB. Obviously, the size of your .DLL depends on how much code you store in it, but in general MFC extension .DLLs are relatively small and quick to load.

Regular .DLLs

The MFC extension .DLL only works with MFC client applications. If you need a .DLL that can be loaded and run by a wider range of Win32 programs, you should use a regular .DLL. The downside is that your.DLL and your client application cannot send each other pointers or references to MFC-derived classes and objects. If you export a function, it cannot use MFC data types in its parameters or return values. If you export a C++ class, it cannot be derived from MFC. You can still use MFC inside your .DLL, but not in your interface.

Your regular .DLL still needs to have access to the code in the MFC code library .DLL. You can dynamically link to this code or statically link. If you dynamically link, that means the MFC code your .DLL needs in order to function is not built into your .DLL. Your .DLL will get the code it needs from the MFC code library .DLL found on the client application's computer. If the right version of the MFC code library .DLL is not there, your .DLL won't run. Like the MFC extension .DLL, you get a small .DLL (because the .DLL doesn't include the MFC code), but you can only run if the client computer has the MFC code library .DLL.

If you statically link to the MFC code library, your .DLL will incorporate within itself all the MFC code it needs. Thus, it will be a larger .DLL, but it won't be dependent on the client computer having the proper MFC code library .DLL. If you can't rely on the host computer having the right version of MFC available, this is the way to go. If your application users are all within your own company, and you have control over what versions of the MFC .DLLs are lurking on their computers, or if your installation program also loads the right MFC .DLL, this might not be an issue.

Building a .DLL

You can make an MFC-based .DLL with the App Wizard. Select 'File New' from the menu. On the 'Projects' tab, select 'MFC AppWizard (.DLL).' Pick a name for your new project and click 'OK.' On the next screen, you will have the choice to create an MFC extension .DLL, a regular .DLL 'using shared MFC .DLL' (i.e., a regular .DLL dynamically linked to MFC), or a regular .DLL statically linked to MFC. Pick the one you want and click 'Finish.'

App Wizard builds a .DLL which doesn't do anything. The new .DLL will compile, but since it doesn't export any classes or functions yet, it is still essentially useless. You now have two jobs: (1) add functionality to make your .DLL useful; and (2) modify your client application to use your .DLL.

Export a class

Once you're done with the App Wizard, you can add classes to your .DLLby adding the .cpp and .h files from another project, or you can create them from scratch within your current project. To export a class, you add '__declspec(dllexport)' to the class declaration so it looks like this:

If you are making an MFC extension .DLL, you can instead use the AFX_EXT_CLASS macro:

There are other ways to export a class, but this is the easiest. If your exported class requires a resource which is located in the .DLL,for example a class derived from CDialog, the process is moreinvolved. I'll cover this subject in tutorial #3.Below I'll discuss what to do to the client application so that it can use your exported class.

Export variables, constants and objects

Instead of exporting a whole class, you can have your .DLL export a variable, constant or object. To export a variable or constant, you simply declare it like this:

When you want to export a constant, you must use the 'extern' specifier.Otherwise you will get a link error.

You can declare and export a class object in the exact same manner:

Note that you can only export a class object if the client application recognizes the class and has its header file. If you make a new class inside your .DLL, the client application won't recognize it without the header file.

When you export a variable or object, each client application which loads the .DLL will get its own copy. Thus, if two different applications are using the same .DLL, changes made by one application will not affect the other application.

It's important to remember that you can only export objects and variables which are of global scope within your .DLL. Local objects and variables cease to exist when they go out of scope. Thus, if your .DLL included the following, it wouldn't work.

As soon as the object and variable go out of scope, they will cease to exist.

Export a function

Exporting functions is similar to exporting objects or variables. You simply tack '_declspec(dllexport)' onto the beginning of your function prototype:

If you are making an MFC regular .DLL which will be used by a clientapplication written in C, your function declaration should look like this:

and your function definition should look like this:

If you are building a regular .DLL which is dynamically linked to theMFC code library .DLL, you must insert the AFX_MANAGE_STATE macro as the first line of any exported function. Thus, your function definition would look like this:

It doesn't hurt to do this in every regular .DLL. If you you switch your.DLL to static linking, the macro will simply have no effect.

That's all there is to exporting functions. Remember, only an MFC extension .DLL can export functions with MFC data types in the parameters or return value.

Export a pointer

Exporting an uninitialized pointer is simple. You do it the same wayyou export a variable or object:

You can also export an initialized object this way:

Of course, if you declare and initialize your pointer you need to find a place to delete it.

In an extension .DLL, you will find a function called DllMain( ). This function gets called when the client program attaches your .DLL and again when it detaches. So here's one possible way to handle your pointers in an extension .DLL:

A regular .DLL looks more like an ordinary MFC executable. It has an objectderived from CWinApp to handle opening and closing your .DLL. You can use theclass wizard to add an InitInstance( ) function and an ExitInstance( ) function.

Using the .DLL in a client application

A .DLL can't run on its own. It requires a client application to load it and use its interface. Making a client application that can do so is not difficult.

When you compile your .DLL, the compiler creates two important files: the .DLL file and the .lib file. Your client application needs both of these. You must copy them into the project folder of your client application. Note that the .DLL and .lib files that are created when you build in Debug are different that those built when you build in Release. When you are building your client application in Debug, you need the Debug versions of the .DLL and .lib files, and when you are building in Release you need the Release .DLL and .lib. The easiest way to handle this is to put the Debug .DLL and .lib files in your client application's Debug folder and the Release .DLL and .lib in the Release folder.

The next step is to go into your client project settings and tell thelinker to look for your .lib file. You must tell the linker the name of your .lib file and where it can be found. To do this, open the project settings, go to the 'Link' tab and enter your file name and path in the 'Object/library modules' box. It should look something like this:

In addition to the .DLL and .lib files, your client application needs a header file for the imported classes, functions, objects and variables. When we were exporting, we added '__declspec(dllexport)' to our declarations. Now when we are importing, we will add '__declspec(dllimport).' So if we wanted to import the variable, object and function used in our previous examples, our header file would contain the following:

Remember, if you used the extern 'C' specifier in the .DLL, you mustalso use it in the client application:

To make things more readable, we might write it like this instead:

Now that you have declared your object, variable and function in a header file inside your client application, they are available for use.

Mfc Application Tutorial Pdf

Tutorial

To import an entire class, you must copy the entire .h header file intothe client application. The .DLL and the client application will thus have identical header files for the exported class, except one will say 'class __declspec(dllexport) CMyClass' and one will say 'class __declspec(dllimport) CMyClass'. If you are makingan MFC extension .DLL, you could instead say 'class AFX_EXT_CLASS CMyClass'in both places.

Once you are done building your client application and you're ready to turn it over to the actual users, you should give them your Release executable and the Release .DLL. You do not need to give the users the .lib file. The .DLL can go in the same directory as the executable, or it can go in the Windows System directory. As discussed above, you may also have to provide your users with the correct MFC code library .DLL. This .DLL was loaded onto your computer when you installed Visual C++. Your users, however, may not have it. It does not come standard with Windows.

A Word of Caution

Mfc Sdi Application Tutorial

This article should provide you with enough information to start building your own .DLLs. A word of caution is needed, however. As mentioned at the beginning of this article, there are several serious shortcomings to .DLLs. These shortcomings are the reason that we now have COM and ATL. There are two main problems. First, a .DLL built with one brand of compiler may not be compatible with a client application built with a different compiler. Second, when you modify the .DLL, you may have to recompile the client application, even though you aren't changing any code in the client application. You may still have to copy in a new .DLL and .lib file and recompile.

Mfc Application C++ Example

There are ways to avoid this problem under some circumstances. I'll discuss the problem in more detail in the next article.