MFC AppWizard生成应用程序基本框架分析
摘要:在Visual C++中用MFCAppWizard帮助程序员快速生成应用程序框架,这在一定程度上实现了软件的自动生成和可视化编程。最基本的MFC应用程序框架由CXApp、CMainFrame、CXDoc和CXView类组成(X代表工程名称)。AppWizard是面向对象程序设计发展和工业化的产物。
MFC(Microsoft Foundation Class,微软基础类库)封装了大部分Windows API(Application Programming Interface)函数,大大简化了程序开发者的工作量,充分的重用代码,提高了程序开发效率。在Visual C++中还提供了ClassWizard,它利用Application Framework技术调用MFC库来建立程序需要新类、添加、修改各种消息和消息映射。
我最近刚接触MFC Application Framework,把我一点浅显的经验拿出来与大家交流。本文通过分析一个很简单的单文档程序来剖析MFC AppWizard生成应用程序基本框架。因为本文目的是MFC AppWizard生成应用程序基本框架的分析,所以就不再描述Application Framework及一些相关的技术。本示范程序用Visual C++6.0在Windows XP平台上编译制作。本示例程序的功能是在窗口中域输出“hello word!”字符串。为了便于描述,后文称这个示例程序为helloworld程序。
Visual C++6.0生成这个helloword程序基本框架的操作过程很简单。在Visual C++6.0的集成开发环境中,单击File弹出式菜单的New菜单项,系统会弹出一个New对话框,选中Projects标签,在对话框的左边会出现一个可供选择的项目列表,右边Project name编辑框里输入向新建项目名称helloworld,Localtion编辑框里输入保存项目的路径。从项目列表中选择MFCAppWizard(exe)项,单击OK按钮,进入MFC AppWizard-Step1对话框。应用程序类型选择Single document(单文档类型),选中Document/View architecture support(文档/视图结构支持)复选框,语种选择“中文[中国](APPWZCHS.DLL)”项,然后点击Finsh按钮,这样就生成了helloworld程序的基本框架了。框架仅仅是框架,还不具备我们所要求的功能——在程序的窗口中输出“hello world!”字符串。当然这正是我们剖析MFC AppWizard生成应用程序基本框架的目的所在,明白它的结构和接口再实现我恶魔想要的功能就很简单了,可谓水到渠成。
MFC AppWizard为我们生成了4个类CHelloworldApp、CHelloworldDoc、CHelloworldView、CMainFrame以及它们的实现代码,并巧妙地将这些代码结合在一起。下面我们开始真正的分析了。
1.应用类CHelloworldApp
CHelloworldApp类的作用是完成主窗口框架的构造和显示工作,并处理消息,他同意管理程序收到的所有消息,然后把相应的消息发给相应的对象。
Windows总要求每个应用程序都有一个主函数main或WinMan,但我们会发现CHelloworldApp类的代码中没有main或WinMain,这是因为它被隐藏到应用程序框架的内部了,Windows会自动调用它。在CHelloworldCApp中有一个虚函数InitInstance,它是作为用户看得见的应用程序的入口函数来完成应用程序的初始化工作,它的主要部分代码如下所示(在helloworld.cpp文件中):
BOOL CHelloworldApp::InitInstance()
{
//省略部分代码
//以下进行单文档模版的创建及初始化
CSingleDocTemplate* pDocTemplate; //定义一个单文档模板指针变量
pDocTemplate = new CSingleDocTemplate( //新建一个单文档模板对象
IDR_MAINFRAME, //菜单等资源标示号
RUNTIME_CLASS(CHelloworldDoc), //文档类
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CHelloworldView)); //视图类
AddDocTemplate(pDocTemplate); //向应用程序添加文档模板
//省略部分代码
//主窗口已经完成初始化,下面进行更新和显示
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
从函数InitInstance中我们可以看到,单文档模板类CSingleDocTemplate将用户程序项目中的资源、主窗口框架类、文档类和视图类建立了联系,生成并初始化相应应的对象。函数AddDocTemplate负责将这些对象和它们之间的联系潜入到应用程序中。主窗口创建后调用ShowWindow函数显示主窗口,并调用函数UpdataWindow更新它。
2.主窗口框架类CMainFrame
主窗口框架类CMainFrame是负责创建应用程序中的控制菜单、工具条和状态条等界面元素,具体创建工作在OnCreate的代码下所示(在MainFrm.cpp文件中):
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1) //创建主窗口框架
return -1;
//下面代码创建工具条
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar/n");
return -1; // 创建失败 }
//下面代码创建状态条
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar/n");
return -1; // 创建失败
}
// 下面代码可以使工具条“浮动”和“停泊”
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
return 0;
}
3.文档类CHelloworldDoc
文档类负责用户数据的读取和保存,程序的数据也保存在文档类中,由于视图类负责数据的现示,这样就可以实现一个文档对应多个视图,多个视图可以对文档类中的同一数据作不同的显示和处理。
当用户选择了File菜单中的Open和Save菜命令时,系统会执行文档类的成员函数OnOpenDeocument和OnSaveDocument,之后系统会调用虚函数Serialize,在文档类CHelloworldDoc中,虚函数Serialize的代码如下所示(在helloworldDoc.cpp文件中):
void CHelloworldDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring()) //当文档数据需要存盘时
{
// 这里添加存盘代码
}
else //当需要读取数据时
{
//这里添加读取数据代码 }
}
通过函数Serialize可以实现数据的串行化操作,CArchive是用于数据实现串行化的类,其成员函数IsStoring用于判断当前操作时读取数据还是保存数据。我们主要分析框架,所以不在此叙述这些函数的用法。
4.视图类CHelloworldView
视图类负责用户数据的显示工作,视图和文档是紧密相连的,它可以响应用户的各种输入,打印和打印预览工作也是在视图类中完成,还可以进行消息处理及文档数据的可视化处理。这种文档、视图的结合称为“文档/视图机制”,是MFC程序框架的核心。
在视图类中,OnDraw是一个非常重要的函数,它用于绘制视图窗口。当应用程序的窗口大小改变或试图上部分地区与需要更新时,这个函数就会被调用。用户可以绘图后有关输出字体的代码添加到这个函数中,就能完成相关的绘图或字体输出工作。OnDraw函数的代码如下所示(在helloworldVeiw.cpp文件中):
void CHelloworldView::OnDraw(CDC* pDC)
{
CHelloworldDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
//在此添加欲输出的绘图或文字数据
//helloworld程序实现显示字符串的关键
pDC->TextOut(30,30,pDoc->m_strOutput); //
}
在这个函数中,pDC是指向一个CDC类型的对象,代表视图窗口,用它可以完成绘图操作。函数GetDocument用于获取与视图相关联的文档,从而可以利用文档类的文档类绘制图形。
现在我们把MFC AppWizard生成的应用程序基本框架分析完了,这个框架没有实现任何具体的功能,但它提供了我们需要的框架,就像建一座楼房,建好框架了,剩下的文体就是在需要的地方添砖加土了。下面就是要添加一些代码,来实现程序输出“Hello World!”的功能。
1. 定义变量
在文档类CHelloworldDoc添加变量m_strOutput,类型为CString。如下所示(在helloworldDoc.h文件中):
class CHelloworldDoc : public CDocument
{
//省略其他代码
// Attributes
public:
CString m_strOutput; //自定义变量
//CString类它可以进行各种字符串操作
//省略其他代码
};
2. 初始化变量
在CHelloworldDoc类的构造函数CHelloworldDoc中初始化m_strOutput变量,如下所示(在helloworldDoc.cpp文件中):
CHelloworldDoc::CHelloworldDoc()
{
// TODO: add one-time construction code here
m_strOutput = "Hello World! "; //为变量赋之
}
3. 输出字符串
在文档类定义好数据后,就可以在视图类的OnDraw函数中输出,代码如下所示(在helloworldView.cpp中):
void CHelloworldView::OnDraw(CDC* pDC)
{
CHelloworldDoc* pDoc = GetDocument(); //获取文档对象指针
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
pDC->TextOut(30,30,pDoc->m_strOutput); //输出字符串
}
在OnDraw函数中,首先得到文档对象的指针,通过该指针可以得到文档数据m_strOutput
,利用CDC类的TextOut函数输出字符。
这些工作都完成后,就可以编译程序了,编译出来的程序可以在窗口上显示字符串“Hello World!”。
以上我们简单的分析了MFC AppWizard生成应用程序的基本框架和在此框架基础上添加少量的代码生成一个能够输出“Hello World!”win32窗口程序,这大大地搞了程序的开发效率。而在传统的SDK开发方式下是非常麻烦的,例如也做一个能显示“Hello World!”的窗口程序,可就要写很多代码。例如一下代码所示,这只有一个最基本的窗口,就要写如此多的代码,如果加上工具栏和状态栏以及其他资源那简直是艰巨的体力劳动。
#i nclude
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("HelloWin") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
/*省略一部分代码
}
hwnd = CreateWindow (szAppName,
TEXT ("The Hello Program"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
/*省略部分代码
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
/*省略部分代码
switch (message)
{
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
GetClientRect (hwnd, &rect) ;
DrawText (hdc, TEXT ("Hello World!"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
/*省略部分代码
}
MFC AppWizard生成的程序框架大大提高了开发软件的工作效率,让程序员能够集中精力去做他们想做的事情,而不是过分计较一些次要的问题。MFC AppWizard是软件开发工业化的产物。
MFC AppWizard生成应用程序基本框架分析
最新推荐文章于 2025-07-09 12:33:15 发布