回 帖 发 新 帖 刷新版面

主题:MFC学习进阶02

大家好,上一次我们主要是学习了WIN32 API编程的主要特点,今天我们用一个具体的MFC运用程序来理解

MFC是建立在WIN32 API上的。
这是一个称作Skeleton的框架性运用程序。它使用了创建一个MFC运用程序所需的最少代码。Skeleton除了

创建,管理一个主窗口外,不做任何事情。Skeleton可以完成的工作有:
。响应一个窗口的尺寸变化
。显示一个自定义图标
。最小化和最大化
。与其他运用程序一起共享系统资源
Skeleton主要包含以下的文件:
。StdAfx.h StdAfx.cpp .Skeleton.h Skeleton.cpp .MainFrame.h

MainFrame.cpp .Resource.h Skeleton.rc

下面分别就每个文件进行简单的讲述:
1。StdAfx.h:
这个文件是用来帮助生成预编译头文件的。其源代码为:

//the file of StdAfx.h
#ifndef _STDAFX_H_
#define _STDAFX_H_

#include<AfxWin.h>
#include<AfxExt.h>

#endif

可以看得出,这个文件里面只是包含了两个头文件。(有人肯定会想,就包含几个头文件还要一个

专门的文件,有费马达又费电?但是这里有一个实际情况要考虑,那就是几乎每一个MFC程序都要这些相同

的代码,那么每写一个程序就要重新输入,编译。而这个文件就避免了这个问题。看来该留)


2。StdAfx.cpp
这个文件用来存放StdAfx.h的源代码。其清单为:

//the file of StdAfx.cpp
#include"StdAfx.h"

因为这是一个最简单的程序,所以没有其他代码,只是把文件包含进来。

3。Skeleton.h
这个文件创建了一个运用程序核心的对象:运用程序对象。这个对象管理者运用程序的总体操作,

在这个程序中主要完成创建一个主窗口,因为它是后台操作,所以不可见.
其清单为:

//file of Skeleton.h

#ifndef _SKELETON_H_
#define _SKELETON_H_

//CSkeletonApp class-Skeleton Application Object

class CSkeletonApp:public CWinApp
{
    public:
        CSkeletonApp();
        virtual ~CSkeletonApp();
        
    public:
        virtual BOOL InitInstance();
    
    protected:
        DECLARE_MESSAGE_MAP()
        //the last method has no ';'
};//end of class CSkeletonApp

#endif

其实现文件清单为:

//the file of Skeleton.cpp

#include"StdAfx.h"
#include"Skeleton.h"
#include"MainFrame.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[]=__FILE__;
#endif

CSkeletonApp theApp;

BEGIN_MESSAGE_MAP(CSkeletonApp,CWinApp)
END_MESSAGE_MAP()

CSkeletonApp::CSkeletonApp(){
}

CSkeletonApp::~CSkeletonApp(){
}

BOOL CSkeletonApp::InitInstance()
{
    m_pMainWnd=new CMainFrame;
    ASSERT(m_pMainWnd);
    if(((CMainFrame*)m_pMainWnd)->Create(NULL,NULL))
    {
        m_pMainWnd->ShowWindow(m_nCmdShow);
        m_pMainWnd->UpdateWindow();
        return TRUE;
    }//end of if
    
    return FALSE;
}//END OF CSkeletonApp::IninInstance


这个文件创建了一个应用程序对象CSkeletonApp,从CWinApp继承来。这其中的InitInstance用来初始化一个

程序,一个程序的初始化包括两部分,一是首次初始化,一是后继初始化。首次初始化是在程序第一次运行

的时候调用的,而当每次程序拷贝运行时,包括第一次都要进行后继初始化,重载InitInstance来初始化。
InitInstance()是被WinMain()调用来初始化的。

这个运用程序对象的InitInstance方法创建了一个窗口对象。并用Create()来完成实际创建工作。当调用

ShowWindow,UpdataWindow绘制程序后,初始化工作完成。

4。MainFrame.h和MainFrame.cpp
这个创建了一个主窗口。用宏定义DECLARE_MESSAGE_MAP为类定义了一个消息映射表,指明如何处

理消息。这个消息映射表的入口放在MainFrame.cpp文件的BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间。
头文件的DECLARE_DYNCREATE宏来使MFC对象能够在运行时动态创建。DECLARE_MESSAGE_MAP和

IMPLEMEN_DYNCREATE成对出现,而且是要动态创建必需的。
其清单为:
//the file of  MainFrame.h

#ifndef _MAINFRAME_H_
#define _MAINFRAME_H_

class CMainFrame:public CFrameWnd
{
    public:
        CMainFrame();
        virtual ~CMainFrame();
    public:
        BOOL Creat(const CString& sTitle);
    protected:
        DECLARE_MESSAGE_MAP()
        DECLARE_DYNCREATE(CMainFrame)
};//end of class CMainFrame

#endif


//the file of MainFrame.cpp

#include"StdAfx.h"
#include"MainFrame.h"
#include"Resource.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[]=__FILE__;
#endif

BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)
END_MESSAGE_MAP()

IMPLEMENT_DYNCREATE(CMainFrame,CFrameWnd)

CMainFrame::CMainFrame()
{
}//end of method CMainFrame

CMainFrame::~CMainFrame()
{
}//end of method ~CMainFrame

BOOL CMainFrame::Create(const CString& sTitle)
{
    CString sClassName;
    sClassName=AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW,::LoadCursor(NULL,IDC_ARROW),
    

(HBRUSH)(COLOR_WINDOW+1),::LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_SKELETON)));
    
    return CFrameWnd::Create(sClassName,sTitle);
}//end of method Create

5。Resource.h和Skeleton.rc
Resoutce.h文件包含了运用程序中的资源(如:图标)的表示符。
其清单为:

//the file of Resource.h

#define IDR_SKELETON 1000

虽然只有一行,但它定义了一个资源的标示符
Skeleton.rc文件使用Icon语句Skeleton图标。
其清单为:
//the file of Skeleton.rc
#include"AfxRes.h"
#include"Resource.h"

IDR_SKELETON ICON"Skeleton.ico"

STRINGTABLE
BEGIN
    AFX_IDS_APP_TITLE"Skeleton v1.0"
END
这一次通过具体的代码,讲述了一个典型的运用程序的源程序框架。好,就到这吧!

回复列表 (共16个回复)

11 楼

谢谢楼主分享和辛苦工作,以上代码在VC++2003编译通过。
其中有一两处笔误,如“ if(((CMainFrame*)m_pMainWnd)->Create(NULL,NULL))”编译不通过,Create可以接受一个字符串参数,所以我改成了Create("Skeleton v1.0")。

12 楼

好文章..谢谢LZ

13 楼

好,分析的很具体,

14 楼


支持

15 楼


对楼主的工作表示12分的敬意!

16 楼


#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[]=__FILE__;
#endif
是什么意思?
为什么总有ifdef_...def..
这样写有什么用?
还有BASED_CODE THIS_FILE[]=__FILE__;为什么在这两个#中定义?为什么定义成静态?
麻烦楼主解答一下!
    致敬!

我来回复

您尚未登录,请登录后再回复。点此登录或注册