MFC简要介绍

一、概念

MFC(MicrosoftFoundationClasses)是微软基础类库的简称,是微软公司实现的一个c++类库,主要封装了大部分的windows API函数,vc++是 微软公司开发的c/c++的集成开发环境,所谓集成开发环境,就是说利用它可以编辑,编译,调试,而不是使用多种工具轮换操作,灵活性较大。vc也指它的内部编译器,集成开发环境必须有一个编译器内核,例如DevC++其中一个编译器内核就是gcc。 MFC除了是一个类库以外,还是一个框架,在vc++里新建一个MFC的工程,开发环境会自动帮你产生许多文件,同时它使用了mfcxx.dll。xx是版本,它封装了mfc内核,所以你在你的代码看不到原本的SDK编程中的消息循环等等东西,因为MFC框架帮你封装好了,这样你就可以专心的考虑你程序的逻辑,而不是这些每次编程都要重复的东西,但是由于是通用框架,没有最好的针对性,当然也就丧失了一些灵活性和效率。但是MFC的封装很浅,所以效率上损失不大。

二、在MFC下创建一个窗口对象
MFC下创建一个窗口对象分两步,首先创建MFC窗口对象,然后创建对应的Windows窗口。在内存使用上,MFC窗口对象可以在栈或者堆(使用new创建)中创建。具体表述如下:
创建MFC窗口对象。通过定义一个CWnd或其派生类的实例变量或者动态创建一个MFC窗口的实例,前者在栈空间创建一个MFC窗口对象,后者在堆空间创建一个MFC窗口对象。
调用相应的窗口创建函数,创建Windows窗口对象。
例如:在前面提到的AppWizard产生的源码中,有CMainFrame(派生于CMDIFrame(SDI)或者CMDIFrameWnd(MDI))类。它有两个成员变量定义如下:
CToolBar m_wndToolBar;
CStatusBar m_wndStatusBar;
当创建CMainFrame类对象时,上面两个MFC Object也被构造。
CMainFrame还有一个成员函数
OnCreate(LPCREATESTRUCT lpCreateStruct),
它的实现包含如下一段代码,调用CToolBar和CStatusBar的成员函数Create来创建上述两个MFC对象对应的工具栏HWND窗口和状态栏HWND窗口:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (!m_wndToolBar.Create(this) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
}
关于工具栏、状态栏将在后续有关章节作详细讨论。
在MFC中,还提供了一种动态创建技术。动态创建的过程实际上也如上所述分两步,只不过MFC使用这个技术是由框架自动地完成整个过程的。通常框架窗口、文档框架窗口、视使用了动态创建。介于MFC的结构,CFrameWnd和CView及其派生类的实例即使不使用动态创建,也要用new在堆中分配。理由见窗口的销毁(2.2.5节)。
至于动态创建技术,将在下一章具体讨论。
在Windows窗口的创建过程中,将发送一些消息,如:
在创建了窗口的非客户区(Nonclient area)之后,发送消息WM_NCCREATE;
在创建了窗口的客户区(client area)之后,发送消息WM_CREATE;
窗口的窗口过程在窗口显示之前收到这两个消息。
如果是子窗口,在发送了上述两个消息之后,还给父窗口发送WM_PARENATNOTIFY消息。其他类或风格的窗口可能发送更多的消息,具体参见SDK开发文档。

三、MFC编程的缺点

1.大量使用稀奇古怪的宏,会使代码可读性很差。要掌握MFC需要编程人员耐心的去分析它们。

2.消息映射的现实机制十分笨拙,没有采用继承机制,也没有采用委托技术,而是采用表驱动。

3.对于底层SDK的封装太薄,面向对象的感觉不足。

4.自己编写了RTTI,SHE,CObjXXX(Container)等,实现起来不太理想。

5.很多场合本来是标准库可以一展身手的地方,MFC完全没用上。

6.为了迎合MFC,编译器的很多地方都违反标准。

7.Doc/View体系的局限性,想图破很难。

四、一个MFC编程的例子

1. 由于mfc只是对win32API进行了大量的封装,因此可以通过修改win32项目来创建mfc工程

MFC简要介绍_第1张图片

2. 工程名起名为FirstMFC,然后下一步选择windows应用程序,然后点击完成

MFC简要介绍_第2张图片

3. 创建完成后发现主cpp文件已经为我们自动生成了win32创建窗口的代码,因为要用mfc实现,所以只需保留头文件,删掉其余的代码

FirstMFC.cpp内只剩下如下代码

// FirstMFC.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "FirstMFC.h"

4.由于我们要使用MFC库,因此需要在stdafx头文件里包含afxwin.h  而afxwin.h内已经包含windows.h,因此可以直接将stdafx.h内的#include 替换成

5. 右键点击工程名,选择属性,在弹出对话框中MFC使用这一项选择在静态库中使用MFC,然后选择应用确定。

6. 因为mfc程序需要至少包含一个应用程序类和窗口框架类,因此我们需要在FirstMFC.cpp定义一个CFrameWnd和CWinApp的子类,并为CWinApp的子类创建一个全局的实 

    例化对象,并在CwinApp的子类中重载InitInstance函数创建窗口,代码如下:

[cpp]  view plain  copy
  1. class CMyFrameWnd : public CFrameWnd  
  2. {  
  3.   
  4. };  
  5.   
  6. class CMyWinApp : public CWinApp  
  7. {  
  8.     virtual BOOL InitInstance();  
  9. };  
  10.   
  11. CMyWinApp myApp;  
[cpp]  view plain  copy
  1. InitInstance函数中创建窗口代码如下"code" class="cpp">BOOL CMyWinApp::InitInstance()  
  2. {  
  3.     CMyFrameWnd * pFrame = new CMyFrameWnd();  
  4.     pFrame->Create(NULL,"FirstMFC");  
  5.     m_pMainWnd = pFrame;  
  6.     pFrame->ShowWindow(SW_SHOW);  
  7.     pFrame->UpdateWindow();  
  8.     return TRUE;  
  9. }  
从代码可以看出,InitInstance主要完成的工作就是窗口的创建过程,查阅csdn可以发现

CFrameWnd::Create

BOOL Create( LPCTSTR lpszClassName,

LPCTSTR lpszWindowName

DWORD dwStyle = WS_OVERLAPPEDWINDOW, 

const RECT& rect = rectDefault, 

CWnd* pParentWnd = NULL, 

LPCTSTR lpszMenuName = NULL, 

DWORD dwExStyle = 0,

CCreateContext* pContext = NULL );

create函数的第一个参数为类名,可以置空,在创建的过程中mfc会自己重新为它赋值,第二个参数为要创建的窗口的名称,后面的参数固定参数,无须赋值



MFC简要介绍_第3张图片

你可能感兴趣的:(MFC简要介绍)