一个最简单的MFC程序框架剖析
首先在VC中(我使用的是VC2008)建立一个Win32应用程序,并且选择空项目。建立完成后,选择项目属性->配置属性->常规->MFC的使用
选择在共享DLL中使用MFC。现在这个空项目中没有任何的文件。
先新建一个.h文件:MyApp.h,并且加入以下代码:
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()
};
然后建立一个MyApp.cpp文件,加入以下代码:
#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, _T("MYAPP Application"));
}
void CMyFrame::OnLButtonDown(UINT nFlags, CPoint point)
{
AfxMessageBox(_T("Left Button Clicked!"));
/*
TRACE("Entering CMyFrame::OnLButtonDown - %lx, %d, %d\n",
(long) nFlags, point.x, point.y);
*/
}
void CMyFrame::OnPaint()
{
CPaintDC dc(this);
dc.TextOut(0, 0, "Hello, world!");
}
Ctrl+F5运行程序,就是一个最简单的窗口,并且画了一个字符串:“Hello World!”,同时点击鼠标左键会弹出一个MessageBox。这就是不通过应用程序向导我们自己构建的一个MFC应用程序,但是我们继承了MFC的基类,也就是在MFC的应用程序框架下的程序。
1,WinMain函数:每一个Windows应用程序要有一个入口函数,即WinMain函数。但是这里它已经隐藏在了MFC应用程序框架中了。
2,CMyApp类:这个类的对象代表了这个应用程序,定义了全局对象theApp。基类CWinApp决定了theApp的主要行为。
3,应用程序启动: 启动应用程序的时候,先要构造全局对象theApp,进入WinMain函数,并且WinMain寻找一个由CWinApp派生出的全局应用程序对象。
4,成员函数CMyApp::InitInstance:是一个虚函数。也就是基类CWinApp中也有这个函数。当WinMain函数找到应用程序对象theApp时,就调用它的虚拟成员函数InitInstance。这个函数就调用所需要的构造和显示应用程序的主窗口。派生的应用程序类(CMyApp)中必须覆盖InitInstance函数,应为基类(CWinApp)中的函数不知道我们要什么样的主窗口。
5,成员函数CWinApp::Run:这个函数是CWinApp类的成员,它就是发送应用程序的消息到它的窗口,这样就保证了应用程序一直运行。在WinMain调用InitInstance后就调用Run函数。
6,CMyFrame类:这个类的一个对象就代表了应用程序的主框架窗口。构造函数调用基类CFrameWnd的成员函数Create的时候,Windows创建实际窗口结构。 ShowWindow和UpdateWindow函数也是基类的成员函数,调用来显示窗口。
7,CMyFrame::OnLButtonDown函数:当触发了左键点击消息ON_WM_LBUTTONDOWN 时候的响应函数,它是CMyFrame的成员函数(注意的是它并不是基类的成员函数,也即不是虚函数,它使用了宏来把特定的消息映射到了派生类的成员函数。之所以MFC对Windows消息不使用虚函数,因为单单CWnd就要超过100个消息,每个消息都定义一个虚响应函数,那么每个其派生类都要顶一个虚函数调度表,即使大多消息不使用,这样太复杂了)。
8,CMyFrame::OnPaint函数:每次需要重绘窗口的时候,应用程序框架就调用CMyFrame的成员函数OnPaint。CPaintDC是与GDI有关的一个类。最后显示Hello World!。
9,关闭程序:关闭主窗口就关闭了程序。相关事件:CMyFrame的析构,Run函数退出,WinMain函数退出,CMyApp对象析构。