Windows Forms for MFC Developers
George Shepherd
NET is many things to many developers. To the line
developer, .NET is an overhaul of the old Component Object Model, representing
a better way to integrate components. For the Web developer, .NET includes an
excellent library for handling HTTP requests (ASP.NET). For the
security-conscious developer, .NET builds a preventive security layer called
Code Access Security. For the network developer, .NET enables two different
types of remoting—Web Services (using SOAP) and .NET remoting (using the
reflection capabilities inherent in the .NET Common Language Runtime. Finally,
for the rich client or desktop client developer, .NET unifies the Windows
programming model through Windows Forms.
Depending upon your development background, Windows Forms
may seem very familiar, or Windows Forms may seem radically different from what
you’re used to using. If you’ve spent time with Visual Basic, Windows Forms
will seem almost second nature. If you’re used to SDK-style development (a
vanishing breed these days), Windows Forms probably seems like a very distant
abstraction from what’s really going on in a Windows program. Finally, if
you’re an MFC developer, Windows Forms sits right in between the two
aforementioned extremes. Windows Forms represents a form-based event-driven UI
environment with excellent designer support and a straightforward development
approach.
MFC Developer, Meet Windows Forms
Approaching Windows Forms from an MFC development background
means adopting a slightly new development style. Much of MFC development is
done through calling functions in a program’s code. For example, resizing a
window involves actually calling CWnd::MoveWindow() at some point.
On the other hand, Windows Forms represents a
forms-based environment. Much of the up-front work involved in a Windows Forms
application can be done through a forms designer. When it comes time to manage
the look and feel of a window, you just change some of the Windows properties
around a bit.
MFC is a C++ library that wraps the low-level code necessary
to make Windows work. MFC includes classes that encapsulate the message loop,
drawing and graphics, managing dialogs, and even some high-level classes for
managing documents and their rendering components (the document/view
architecture). Windows Forms also includes many of the same types of class.
(However, Windows Forms objects run under the CLR rather than in raw \memory—as
C++ objects do.
Table 1 compares a few classes found within MFC to the
counterparts found within the Windows Forms library.
|
MFC |
Windows Forms |
Comment |
|
CObject |
System.Object |
Root of most classes in MFC, root of all types in the
CLR. |
|
CWinApp |
System.Windows.Forms.Application |
Singleton, spins message loop. |
|
CWnd |
System.Windows.Forms.Form |
Main window class. Hosts child windows, controls,
responds to Windows messages. |
|
CDC |
System.Drawing.Graphics |
Represents a drawing surface. |
|
CPen |
System.Drawing.Pen |
Represents color and style for lines and shapes. |
|
CBrush |
System.Drawing.Brush |
Represents color and style for background fills. |
|
CFont |
System.Drawing.Font |
Represents font for drawing text. |
|
CButton |
System.Windows.Forms.Button |
Represent a push button UI element. |
|
ClistBox |
System.Windows.Forms.ListBox |
Represents a list box UI element. |
Table 1: Class comparison between MFC and Windows Forms
HelloWorld in MFC
To get a good feel for how MFC and Windows Forms compare,
let’s take a look at how you might write “HelloWorld” in each environment.
Listing 1 shows “HelloMFC”—both the header and the source files.
// HelloMFC.H
#include
class CSimpleApp :public CWinApp
{
public:
virtual BOOL InitInstance()
{
m_pMainWnd = new CSimpleFrame;
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
};
class CSimpleFrame:public CFrameWnd
{
public:
CSimpleFrame()
{
Create(NULL, “Hello MFC!”);
}
protected:
DECLARE_MESSAGE_MAP();
afx_msg void OnPaint();
};
--------------------------------------------
// HelloMFC.CPP
CSimpleApp helloApp;
BEGIN_MESSAGE_MAP(CSimpleFrame, CFrameWnd)
ON_WM_PAINT()
END_MESSAGE_MAP()
void CSimpleFrame::OnPaint()
{
CPaintDC dc(this);
dc.TextOut(200,200, "Hello World from MFC!!!");
}
Listing 1: “HelloMFC” using MFC
Notice the application class named CSimpleApp (derived from
CWinApp). Every MFC application requires one and only one class derived from
CWinApp to be declared in the program. MFC looks for this class and calls
important methods prior to starting up (the most important of which is probably
InitInstance()). Most application classes create an instance of a main window
and store the reference to the window in a member called m_pMainWnd. In the
case of the application above, the main window is managed by class named
CSimpleFrame (which derives from CFrameWnd). CSimpleFrame is responsible for
providing the look and feel of the application. This is a simple application,
and the job of the main window is to write a string saying “Hello World from
MFC!!!”.
HelloWorld in Windows Forms
By contrast, the simplest Windows Forms application is quite
a bit simpler. Listing 2: “Hello World” using Windows Forms
using System;
using System.Windows.Forms;
public class SimpleForm : Form {
private Label label1;
public SimpleForm() {
this.label1 = new Label();
label1.Text = “HelloWorld”;
Controls.Add(label1);
}
[STAThread()]
static void Main() {
Application.Run(new SimpleForm());
}
}
Listing 2: “HelloWorld” using Windows Forms
In the Windows forms
application listed above, the Application object also exists as a rendezvous
point for initialization. However, in this case the initialization is performed
by creating during the application's Main() function. Main() is a required entry point for every application that runs
under the CLR. Main() creates an instance of a SimpleForm class and asks the
Application object to run the form. SimpleForm displays its greeting by showing
a label with greeting text in it. In later installments, we’ll look at
performing drawing operations on the form.
Conclusion
At the very highest level, the difference between an MFC
application and a Windows Forms application is like the difference between a
classic VB 6.0 application and a Windows Forms application. If you know how to
program in VB 6.0, you’ll be right at home with Windows Forms. However, if
you’re coming from an MFC point of view, many aspects of Windows programming
are different. In this article, we saw the most basic differences between an
MFC application and a Windows Forms application. In coming installments, we’ll
compare MFC to Windows Forms to see what it takes to move from MFC to Windows
Forms.