MFC Wizard创建的空应用程序中各个文件内容的解析

创建的MFC应用程序名为:wd,那么:

一、wd.h解析

// wd.h : main header file for the WD application
//


#if !defined(AFX_WD_H__89BE48D2_F377_4DF1_8C44_4D7372A61CE0__INCLUDED_)
#define AFX_WD_H__89BE48D2_F377_4DF1_8C44_4D7372A61CE0__INCLUDED_


//
//以下语句的作用是:判断当前微软编译器的版本,如果版本大于1000,那么“#pragma once”这个语句就会被编译。
//


#if _MSC_VER > 1000 //Microsoft Compiler version 在_MSC_VER较小时,它对一些东西的支持与新版不同
#pragma once //这是一个比较常用的C/C++杂注,只要在头文件的最开始加入这条杂注,就能够保证头文件只被编译一次
#endif // _MSC_VER > 1000


#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif


#include "resource.h"       // main symbols


/
// CWdApp:
// See wd.cpp for the implementation of this class
//


class CWdApp : public CWinApp
{
public:
CWdApp();


// Overrides 指示你可以对InitInstance函数进行重载
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CWdApp)
public:
virtual BOOL InitInstance(); //它的作用是初始化实例对象,它是一个虚函数,mfc已经定义了这个函数,但你可以重载它来完成自己的初始化实例功能,如果没有定义就会调用Mfc的默认函数。
//}}AFX_VIRTUAL


// Implementation 指示你可以去实现OnAppAbout函数
//{{AFX_MSG(CWdApp)
afx_msg void OnAppAbout(); // afx_msg本身只是一个注释宏,就是起注释作用的宏定义,指明当前函数是mfc框架中的消息响应函数;OnApptAbout()函数就是当选择 "帮助"里面的 "关于"菜单时,调用的函数一般是弹出一个对话框显示程序的一些信息
                          
// NOTE - the ClassWizard will add and remove member functions here.
//    DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()//DECLARE_MESSAGE_MAP()宏的作用是向类中添加消息映射必要的结构体和函数声明,只需要添加一次,放在什么位置并不重要,就如同类里其他普通函数的声明可以相互交换顺序一样。
//函数的修饰符也是可以自己决定的,遵循一般原则。比如你需要在类外部也可以调用该消息响应函数,就可以定义成public的
};




/


//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.


#endif // !defined(AFX_WD_H__89BE48D2_F377_4DF1_8C44_4D7372A61CE0__INCLUDED_)



二、wd.h对应的.cpp文件wd.cpp解析

// wd.cpp : Defines the class behaviors for the application.
//


#include "stdafx.h"
#include "wd.h"


#include "MainFrm.h"
#include "ChildFrm.h"
#include "wdDoc.h"
#include "wdView.h"


///
//以下这段宏定义只是在程序开发和调试时有用,如果软件已经交付使用,则可以去掉
///


#ifdef _DEBUG  //如果定义了_DEBUG,表示在调试状态下编译
#define new DEBUG_NEW //当在debug模式下时,我们分配内存时的new被替换成DEBUG_NEW,而这个DEBUG_NEW不仅要传入内存块的大小,还要传入源文件名和行号,这就有个好处,即当发生内存泄漏时,我们可以在调试模式下定位到该问题代码处。若删掉该句,就不能进行定位了。而在release版本下的new就是简单的new,并不会传入文件名和行号。
#undef THIS_FILE //表示清除当前定义的宏,使得THIS_FILE无定义
static char THIS_FILE[] = __FILE__; //将THIS_FILE定义为一个静态数组,THIS_FILE是一个char数组全局变量,字符串值为当前文件的全路径,这样在Debug版本中当程序出错时出错处理代码可用这个变量告诉你是哪个文件中的代码有问题。
                                    //__FILE__  是编译器能识别的事先定义的ANSI  C  的6个宏之一,__FILE__ 包含当前程序文件名的字符串
#endif


/
// CWdApp


//消息映射的定义
BEGIN_MESSAGE_MAP(CWdApp, CWinApp)
//{{AFX_MSG_MAP(CWdApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout) //ON_COMMAND 是一个消息映射,这里是把 ON_COMMAND 消息中的 ID_APP_ABOUT 消息映射到函数 OnAppAbout,如果程序中接到这个消息,就会调用这个函数。
// NOTE - the ClassWizard will add and remove mapping macros here.
//    DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
// Standard file based document commands
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
// Standard print setup command
ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()


/
// CWdApp construction


CWdApp::CWdApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}


/
// The one and only CWdApp object



//CSDN中对theApp的用法的总结:
//1.theApp是你工程的头,你可以通过AfxGetApp()获得整个进程的指针,然后通过它,可以获得该进程的HWND以及HINSTANCE,和菜单。。。等等。不一而足。可以通过msdn获得更多的信息
 
//2.theApp是个全局变量,几乎可以在程序的任何地方引用。如果你建立一个MDI或者SDI工程,那么,你可以看到一个类以*App结尾,这个theApp就是它的一个实例,在这个类中添加的public变量可以通过theApp引用。当然,由于WinApp是它的基类,theApp保存有许多有关程序运行期间的很多信息,如执行程序名,路径什么的。
 
//3.加个成员及方法,可以随时用AfxGetApp访问
 
//4.theApp是CWinApp类的派生类的对象,是一个全局变量。全局变量在WinMain()前被创建。
 
//5.theApp就是应用程序的实例,没有他你就什么都不能做啊!他初始了进程啊!


//6.你可以理解为 theApp像一般程序中的main函数一样。
/


CWdApp theApp;


/
// CWdApp initialization


BOOL CWdApp::InitInstance()
{
/
//要想在应用程序中使用ActiveX控件,必须使你的应用程序成为ActiveX控件包容器。
//ActiveX   控件包容器就是完全支持ActiveX控件,并能把控件组合进自己的窗口或对话框的父应用程序。
//利用MFC的AppWizard,你可以很方便地创建你的包容器程序。事实上,在用AppWizard创建新的应用程序时,
//你的应用程序就被缺省设置为控件包容器,即在第3步选中支持ActiveX   Controls的复选框。如果你在创建过程中没有选择这项技术支持,
//以后也可以手动地加入这项支持。如果你手动添加这个函数,和APPWIZEARD添加效果是一样的
/
AfxEnableControlContainer();


// Standard initialization
// If you are not using these features and wish to reduce the size
//  of your final executable, you should remove from the following
//  the specific initialization routines you do not need.


//
//如果原文件定义了_AFXDLL,说明原文件中有某些类,函数等,是以MFC DLL的形式提供的(也就是动态连接到MFC),
//如果原文件中没定义_AFXDLL,则这些类,函数等的实现代码是被直接插入原文件(也就是静态连接到MFC)
//Enable3dControls()和Enable3dControlsStatic()函数的作用
//如果成功地载入了CTL3D32.DLL,则为TRUE;否则为FALSE。
    //如果操作系统支持控件的三维外观,则这个函数将返回FALSE。
///
#ifdef _AFXDLL
Enable3dControls();// Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic();// Call this when linking to MFC statically
#endif


// Change the registry key under which our settings are stored.
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization.
SetRegistryKey(_T("Local AppWizard-Generated Applications"));//这个函数的功能是:设置MFC程序的注册表访问键,并把读写ini文件的成员函数映射到读写注册表。


///
//This method is called from within the InitInstance method to enable and load the list of most recently used (MRU) files and last preview state. If nMaxMRU is zero, no MRU list will be maintained.
    //最近文件列表可以让你很方便地打开你以前曾经打开过的文件,那么,如何为自己的应用程序加入最近文件列表功能呢?最简单的方法就是在你新建工程的时候选择包含最近文件列表功能,也就是在 MFC AppWizard 的第 4 步的时候使 “How  many files would you like on your recent file list?” 的值不为 0 即可。
LoadStdProfileSettings();  // Load standard INI file options (including MRU)


// Register the application's document templates.  Document templates
//  serve as the connection between documents, frame windows and views.



//像MVC架构一样,Model-View-Controller(MVC),其中的Model就是MFC的Document,
//而Controller相当于MFC的Document Template。
//每当使用者欲打开一份文件,程序应该做出Document、View、Frame各一份。
//这三个成为一个运行单元,由所谓的Document Template掌管。
//MFC有一个CDocTemplate负责此事,他又有两个派生类,分别是CMultiDocTemplate和CSingleDocTemplate。
//如果你的程序能够处理两中数据类型,你必须制造两个Document Template,并使用AddDocTemplate函数将他们一一加入系统之中
    //谁来管理Document Template呢?是CWinApp。也就是下面InitInstance中应有的相关行为:


CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(
IDR_WDTYPE,
RUNTIME_CLASS(CWdDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CWdView));
AddDocTemplate(pDocTemplate);




// create main MDI Frame window
CMainFrame* pMainFrame = new CMainFrame;
if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
return FALSE;
m_pMainWnd = pMainFrame;//使用此数据成员存储指向您的线程的主窗口对象



//MFC应用一般都会在它的应用对象中使用函数InitInstance创建这个类的一个本地实例。
//然后把该对象传给CWinApp::ParseCommandLine,ParseCommandLine又重复调用ParseParam填充CCommandLineInfo对象。
//最后,CCommandLineInfo对象被传给CWinApp::ProcessShellCommand来处理命令行参数和选项
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);


// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;


// The main window has been initialized, so show and update it.
pMainFrame->ShowWindow(m_nCmdShow);
pMainFrame->UpdateWindow();


return TRUE;
}




/
// CAboutDlg dialog used for App About
//定义“关于”窗口的相关内容


class CAboutDlg : public CDialog
{
public:
CAboutDlg();


// Dialog Data
//{{AFX_DATA(CAboutDlg)
申明枚举类型用enum开头,花括弧中把IDD_ABOUTBOX的值赋给IDD;本来如果不赋值的话,
//IDD值就默认为0(注意枚举元素看做常量,故有确定值),而编者想改变IDD的值为IDD_ABOUTBOX的值,故进行了赋值。
//const int IDD = IDD_ABOUTBOX
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA


// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
//DoDataExchange(CDataExchange* pDX) 是MFC CWnd的一个重要的函数。
        //在此函数中可以利用一系列的DDX_xxxx(..)函数实现UI与data的数据交互,以及用DDV_xxx(...)来实现数据验证
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
//}}AFX_VIRTUAL


// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
// No message handlers
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};


CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}


void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()


// App command to run the dialog
//模态对话框的消息处理
//(1) 模态对话框弹出来后,首先会让父窗口失效,使其不能接受用户的输入(键盘鼠标消息)。
//1 EnableWindow(hwndParent, FALSE) ;
//(2) 父窗口消息循环被阻塞(会卡在DoModal处,等待返回),由模态对话框的消息循环来接管(因此整个程序不会卡住)。
//接管后,模态对话框的消息循环仍然会将属于父窗口及其子控件的窗口消息(不包括键盘鼠标相关的窗口消息)发送给它们各自的WindowProc窗口函数,进行响应处理。
//(3) 模态对话框销毁时(点击IDOK或IDCANCEL),父窗口消息循环重新激活,继续DoModal后的逻辑。
// 激活后,父窗口有可以重新接受用户的输入(键盘鼠标消息)。
//1 EnableWindow(hwndParent, TRUE) ;
//从上面的过程中,我们可以得到如下结论:


//对于窗口消息,模态对话框主窗口(及其子控件)与父窗口(及其子控件)都是用自身的WindowProc函数接收并处理,互不干扰。


//只是父窗口(及其子控件)无法接受到键盘鼠标消息相关的窗口消息。


//对于命令消息,由模态对话框主窗口的WindowProc接收。可以在模态对话框主窗口的OnCmdMsg中做命令绕行,使得其他的CCmdTarget对象也可以处理命令消息。


//对于控件通知,由其父窗口的WindowProc接收并处理,一般不进行命令绕行被其他的CCmdTarget对象处理。
void CWdApp::OnAppAbout()
{
CAboutDlg aboutDlg;
aboutDlg.DoModal();
}


/
// CWdApp message handlers



三、wdDoc.h解析

// wdDoc.h : interface of the CWdDoc class
//
/


#if !defined(AFX_WDDOC_H__F4400C08_CE4D_4041_AEA6_E5197466CE3A__INCLUDED_)
#define AFX_WDDOC_H__F4400C08_CE4D_4041_AEA6_E5197466CE3A__INCLUDED_


#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000




class CWdDoc : public CDocument
{
//MFC中的CDocument类,是文档类。
//要理解这个类的作用,首先你要明白MFC中 文档/视图结构 的概念。
//文档/视图结构中,将框架窗口(CFrameWnd)、视图窗口(CView)、文档类(CDocument)捆绑到一个“模板”类,形成一个标准的窗口模板CDocTemplate。
//这个概念中,认为一个窗口,应该是有“数据支撑“的,也就是需要很多数据、变量,可能需要访问文件、数据库等等,而这些数据和操作,放在视图窗口类是不合理的(因为这些东西不符合窗口元素的概念),而且多视图访问文档类公用数据也会很方便(多视图之间的访问并不方便),同时也避免让视图类过于臃肿庞大。
    //基于这些理念,MFC设计了一个文档类,专门用于文件操作、序列化操作等,并协助模板类管理视图。
//MFC中,一个文档/视图结构,包含了唯一的模板类、唯一的文档类、唯一的框架窗口和一个或多个视图窗口。在任何视图中都可以方便的访问文档类的数据。
protected: // create from serialization only
CWdDoc();


//使用DECLARE_DYNCREATE宏可以使每个CObject的派生类的对象具有运行时动态创建的能力。
//框架利用这种能力来动态创建对象,例如,当它在串行化过程中从磁盘读取对象的时候。
//文档、视图和框架类必须支持动态创建,因为框架需要动态地创建它们。
//在类的.H模块中加入DECLARE_DYNCREATE宏,然后在每个需要访问这个类的对象的.CPP模块中包含这个模块。
    //如果在类声明中包含了DECLARE_DYNCREATE,那么必须在类的实现中包含IMPLEMENT_DYNCREATE宏。
DECLARE_DYNCREATE(CWdDoc)


// Attributes
public:


// Operations
public:


// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CWdDoc)
public:
//创建一个新文档时程序的消息响应函数,一般用于编写创建新文档时用户对自己文档对象的内容初始化内容。
//比如创建一个文档,显示一个圆,在OnNewDocument中可以设置圆心位置和半径
virtual BOOL OnNewDocument();


//从档案文件中读取该对象或向档案文件中写入该对象。
//必须为希望串行化的每个类覆盖Serialize。被覆盖的Serialize首先必须调用基类的Serialize函数。
//在类的声明中必须使用DECLARE_SERIAL宏,并且在类的执行过程中也必须使用IMPLEMENT_SERIAL宏。
//使用CArchive::IsLoading或CArchive::IsStoring函数,用于决定是否装载或存储了档案文件。
//通过CArchive::ReadObject和CArchive::WriteObject来调用Serialize函数。这些函数与CArchive插入操作符()相关联。


//CArchive 对象提供了一个类型安全缓冲机制,用于将可序列化对象写入 CFile 对象或从中读取可序列化对象。
//通常,CFile 对象表示磁盘文件;但是,它也可以是表示“剪贴板”的内存文件(CSharedFile 对象)
virtual void Serialize(CArchive& ar);
//}}AFX_VIRTUAL


// Implementation
public:
virtual ~CWdDoc();
#ifdef _DEBUG
//MSDN中对AssertValid的说明:When you write your own class, 
//you should override the AssertValid function to provide diagnostic services 
//for yourself and other users of your class. 
//The overridden AssertValid usually calls the AssertValid function of its base class before checking data members unique to the derived class.
//看一个例子,立马明白:主要是在debug模式时比较有用
//void CAge::AssertValid() const
//{
//CObject::AssertValid();
//ASSERT( m_years > 0 ); 
//ASSERT( m_years < 105 );
//}
virtual void AssertValid() const;


//在VC6.0或VC8.0的菜单项——视图(View)下,有个输出(Output)子菜单项。你在编译或调试时,都会出来一个输出子窗口。
//输出子窗口的信息那里来的?其实大部分信息都是由一个全局对象CDumpContext afxDump提供,因为afxDump是全局对象,
//你在任何MFC程序的任何CObject的派生类中都可以操作它。CDumpContext的构造函数关联了一个文件类,MFC自己会往里面写入很多信息,
//同时编程人员通过重载Dump(CDumpContext& dc)函数,也可以向输出窗口输出信息。dc指针指向全局对象afxDump,dc的使用有点向cout,例如:
//dc << "Hello World!" << endl;
//一般CDumpContext由编程环境调用,其实咱们编程人员也可以自己定义新的CDumpContext对象,它的构造函数需要一个CFile指针,你可以把需要的信息写的这个关联文件里面。
//总之,Dump函数的作用可以简单理解为:为调试程序做一些输出准备的。
virtual void Dump(CDumpContext& dc) const;
#endif


protected:


// Generated message map functions
protected:
//{{AFX_MSG(CWdDoc)
// NOTE - the ClassWizard will add and remove member functions here.
//    DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};


/


//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.


#endif // !defined(AFX_WDDOC_H__F4400C08_CE4D_4041_AEA6_E5197466CE3A__INCLUDED_)


四、wdDoc.cpp解析

// wdDoc.cpp : implementation of the CWdDoc class
//


#include "stdafx.h"
#include "wd.h"


#include "wdDoc.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


/
// CWdDoc


//通过DECLARE_DYNCREATE宏来使用IMPLEMENT_DYNCREATE宏,以允许CObject派生类对象在运行时自动建立。
IMPLEMENT_DYNCREATE(CWdDoc, CDocument)


BEGIN_MESSAGE_MAP(CWdDoc, CDocument)
//{{AFX_MSG_MAP(CWdDoc)
// NOTE - the ClassWizard will add and remove mapping macros here.
//    DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/
// CWdDoc construction/destruction


CWdDoc::CWdDoc()
{
// TODO: add one-time construction code here


}


CWdDoc::~CWdDoc()
{
}


BOOL CWdDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())//首先调用父类CDocument的OnNewDocument函数
return FALSE;


// TODO: add reinitialization code here
// (SDI documents will reuse this document)


return TRUE;
}






/
// CWdDoc serialization


void CWdDoc::Serialize(CArchive& ar)
{
/*
    就是判断是保存文件还是读取文件
CArchive 对象既可以用来保存文件又可以用来读取文件
进行判断是保存还是读取,以确定如何进行操作。


CArchive::IsStoring


BOOL IsStorng( ) const;


返回值:
如果正在存储归档文件,则返回非零值,否则为0。


*/
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}


/
// CWdDoc diagnostics


#ifdef _DEBUG
void CWdDoc::AssertValid() const
{
CDocument::AssertValid();//调用父类的断言验证函数
}


void CWdDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);//调用父类的Dump函数
}
#endif //_DEBUG


/
// CWdDoc commands



五、wdView.h文件解析

// wdView.h : interface of the CWdView class
//
/

#if !defined(AFX_WDVIEW_H__F5CC8836_372A_495A_9999_190EB90AB633__INCLUDED_)
#define AFX_WDVIEW_H__F5CC8836_372A_495A_9999_190EB90AB633__INCLUDED_

#if _MSC_VER > 1000

/*
这里在对#pragma进行一个解释:
在所有的预处理指令中,#Pragma 指令可能是最复杂的了,
它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。
#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,
给出主机或操作系统专有的特征。

反正记住:#pragma是针对编译器的预处理指令 就行了
*/
#pragma once
#endif // _MSC_VER > 1000


class CWdView : public CView
{
protected: // create from serialization only
	CWdView();
	DECLARE_DYNCREATE(CWdView)//与CDocument一样,这里DECLARE_DYNCREATE宏定义,也是为了使得CWdView类具有运行时动态创建的能力

// Attributes
public:
	/*
		视图对象是用来显示文档对象的内容,函数GetDocument()用于获取当前文档对象的指针
		通过获取的文档类指针可以在视图中显示文档内容
	*/
	CWdDoc* GetDocument();

// Operations
public:

// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CWdView)
	public:
	/*
	OnDraw函数是通常在里边写渲染文档的代码
	其中CDC类是设备描述表 在windows编程的时候要用到的,不必关系其内部实现,只管调用其拥有的函数即可。
	Windows使用与设备无关的图形设备环境(DC :Device Context) 进行显示 。MFC基础类库定义了设备环境对象类----CDC类
	在Windows应用程序中,设备环境与图形对象共同工作,协同完成绘图显示工作。就像画家绘画一样,设备环境好比是画家的画布,图形对象好比是画家的画笔。
	*/
	virtual void OnDraw(CDC* pDC);  // overridden to draw this view

	/*
	PreCreateWindow是窗口类的虚函数,可以在自己的窗口类中重载此函数,用以改变窗口的样式,
	对mfc来说,这个函数是隐式调用的,不用自己显式调用。只要窗口被创建,则这个函数已经自动调用了,
	你只需要在需要的时候把这个函数重写一下就可以了
	REATESTRUCT是一个结构,可以根据自己的需要修改这个结构的成员,以此改变新建的窗口的外观
	*/
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
	protected:
	
	//以下函数是在MFC中CView类已经封装好了打印相关的功能函数

	/*OnPreparePrinting方法在打印或预览文档前由MFC调用,在OnPreparePrinting函数中准备打印信息CPrintInfo* pInfo;
	其原型如下:pInfo参数是指向包含当前打印作业信息的CPrintInfo对象的指针。
	注意:如果打印作业被用户在结果打印对话框中取消,则
	CView::OnPreparePrinting()方法调用CView::DoPreparePrinting()方法并返回零值。
	*/
	virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);

	/*
	MSDN上的解释:Called by the framework at the beginning of a print or print preview job, after OnPreparePrinting has been called
	*/
	virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
	/*
	打印结束时调用的函数
	*/
	virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
	//}}AFX_VIRTUAL

// Implementation
public:
	virtual ~CWdView();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// Generated message map functions
protected:
	//{{AFX_MSG(CWdView)
		// NOTE - the ClassWizard will add and remove member functions here.
		//    DO NOT EDIT what you see in these blocks of generated code !
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

#ifndef _DEBUG  // debug version in wdView.cpp
inline CWdDoc* CWdView::GetDocument()//GetDocument()函数默认返回一个Doc指针
   { return (CWdDoc*)m_pDocument; }
#endif

/

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_WDVIEW_H__F5CC8836_372A_495A_9999_190EB90AB633__INCLUDED_)


六、wdView.cpp文件解析

// wdView.cpp : implementation of the CWdView class
//

#include "stdafx.h"
#include "wd.h"

#include "wdDoc.h"
#include "wdView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CWdView

IMPLEMENT_DYNCREATE(CWdView, CView)

BEGIN_MESSAGE_MAP(CWdView, CView)
	//{{AFX_MSG_MAP(CWdView)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/
// CWdView construction/destruction

CWdView::CWdView()
{
	// TODO: add construction code here

}

CWdView::~CWdView()
{
}

BOOL CWdView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);//默认首先调用父类的PreCreateWindow函数
}

/
// CWdView drawing

void CWdView::OnDraw(CDC* pDC)
{
	CWdDoc* pDoc = GetDocument();//首先获取将被显示在窗口中的数据对象 
	ASSERT_VALID(pDoc);//用来调试,主要判断 Doc对象是否获取成功;
	// TODO: add draw code for native data here
}

/
// CWdView printing

BOOL CWdView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);//首先调用父类的打印准备函数
}

void CWdView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CWdView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/
// CWdView diagnostics

#ifdef _DEBUG
void CWdView::AssertValid() const
{
	CView::AssertValid();
}

void CWdView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CWdDoc* CWdView::GetDocument() // non-debug version is inline
{
	//这里的m_pDocument是指向将要别序列化的Doc类,m_pDocument定义在CArchive类中
	//此处判断获取的Doc是否是需要的运行时类
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CWdDoc)));
	return (CWdDoc*)m_pDocument;
}
#endif //_DEBUG

/
// CWdView message handlers

奋斗奋斗奋斗奋斗至此,6个比较重要的文件解析完毕,来一个美丽的分割线,接下来解析剩下的文件奋斗奋斗奋斗奋斗

七、StdAfx.h文件解析

// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//
//
/*
1、首先对StdAfx这个名字进行解析,这个名字是Standard Application Fram Extend的缩写 
2、笼统的讲,这个文件没有函数库,只是定义了一些环境参数,增加所需的系统库,使得编译出来的程序能在32位的操作系统环境下运行,
3、它存在的意义,是一个巧妙制作,请仔细阅读:
Windows和MFC的include文件都非常大,即使有一个快速的处理程序,编译程序也要花费相当长的时间来完成工作。由于每个.CPP文件都包含相同的include文件,为每个.CPP文件都重复处理这些文件就显得很傻了。 
为避免这种浪费,AppWizard和VisualC++编译程序一起进行工作,如下所示: 
◎AppWizard建立了文件stdafx.h,该文件包含了所有当前工程文件需要的MFCinclude文件。且这一文件可以随被选择的选项而变化。 
◎AppWizard然后就建立stdafx.cpp。这个文件通常都是一样的。 
◎然后AppWizard就建立起工程文件,这样第一个被编译的文件就是stdafx.cpp。 
◎当VisualC++编译stdafx.cpp文件时,它将结果保存在一个名为stdafx.pch的文件里。(扩展名pch表示预编译头文件。) 
◎当VisualC++编译随后的每个.cpp文件时,它阅读并使用它刚生成的.pch文件。VisualC++不再分析Windowsinclude文件,除非你又编缉了stdafx.cpp或stdafx.h。 
这个技术很精巧,你不这么认为吗?(还要说一句,Microsoft并非是首先采用这种技术的公司,Borland才是。)在这个过程中你必须遵守以下规则:
◎你编写的任何.cpp文件都必须首先包含stdafx.h。 
◎如果你有工程文件里的大多数.cpp文件需要.h文件,顺便将它们加在stdafx.h(后部)上,然后预编译stdafx.cpp。 
◎由于.pch文件具有大量的符号信息,它是你的工程文件里最大的文件。 
如果你的磁盘空间有限,你就希望能将这个你从没使用过的工程文件中的.pch文件删除。执行程序时并不需要它们,且随着工程文件的重新建立,它们也自动地重新建立
*/
#if !defined(AFX_STDAFX_H__1D7D39ED_AD6E_4D9F_A5D7_546C4C48DE9E__INCLUDED_)
#define AFX_STDAFX_H__1D7D39ED_AD6E_4D9F_A5D7_546C4C48DE9E__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers

#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <afxdisp.h>        // MFC Automation classes
#include <afxdtctl.h>		// MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>			// MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT


//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__1D7D39ED_AD6E_4D9F_A5D7_546C4C48DE9E__INCLUDED_)


八、StdAfx.cpp文件解析(这个没啥讲的喔!)

// stdafx.cpp : source file that includes just the standard includes
//	wd.pch will be the pre-compiled header
//	stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"


九、Resource.h和wd.rc文件解析

首先,Resourch.h文件是一个头文件,该文件的解析如下:

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by WD.RC
//
/
/*
1、VC会根据你在可视化界面的设计,会自动管理该文件.包括.rc文件
2、当你添加一个资源并保存时,VC会自动在resource.h文件中增加一个宏定义。该定义确定资源的ID。
但是当你删除一个资源时,VC并不会在resource.h中删除该ID的定义。不过这个并不会影响你对资源的使用。
因为当你下次添加资源时以相同的ID来定位资源时,VC会自动搜索头文件,如果已经存在并且未被使用,则不重新定义该ID。
如果已经存在且已经被使用,系统将会对你进行提示
3、resource.h就是.rc文件的头文件 .rc文件里的常量全在resource.h定义 一般情况下不用你去写和修改 vc会帮你写和改 
*/
#define IDD_ABOUTBOX				100
#define IDR_MAINFRAME				128
#define IDR_WDTYPE				129

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS			1
#define _APS_NEXT_RESOURCE_VALUE	130
#define _APS_NEXT_CONTROL_VALUE		1000
#define _APS_NEXT_SYMED_VALUE		101
#define _APS_NEXT_COMMAND_VALUE		32771
#endif
#endif


其次,wd.rc是一个和Resourch.h对应的目录,存放Resource.h中对应ID的资源;如果不能理解这句,可以在你的工程里面打开xx.rc文件看看即可。

十、MainFrm.h文件解析

MainFrm.h是用来生存程序主窗口的MainFrm.cpp类的头文件;

// MainFrm.h : interface of the CMainFrame class
//
/

#if !defined(AFX_MAINFRM_H__66FE9084_4CA5_468F_AD1F_25852054AC1F__INCLUDED_)
#define AFX_MAINFRM_H__66FE9084_4CA5_468F_AD1F_25852054AC1F__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CMainFrame : public CMDIFrameWnd
{
	DECLARE_DYNAMIC(CMainFrame)//同样,这一句是为了使得该类能够在运行时创建
public:
	CMainFrame();

// Attributes
public:

// Operations
public:

// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CMainFrame)

	/*
	PreCreateWindow(CREATESTRUCT& cs)函数是在创建主窗口之前,
	要做的一些操作,它在OnCreate函数调用之前被调用。
	其中主要的内容都不必修改,除了对框架的属性以及添加响应函数时可能进行修改
	*/
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
	//}}AFX_VIRTUAL

// Implementation
public:
	virtual ~CMainFrame();
#ifdef _DEBUG//同样是为了调试时检查用的断言
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:  // control bar embedded members
	CStatusBar  m_wndStatusBar;//一个CStatusBar 对象是一个带有一行文本输出窗格的控件,或者称为“指示器”。这些输出窗格常被用作消息行和状态指示器。
	CToolBar    m_wndToolBar;//工具条是一个CToolBar类对象,通常作为成员对象嵌入程序的CMainFrame类中,也就是说嵌入主框架窗口中。因此,MFC生成框架窗口的时候同时生成工具条,销毁框架窗口的时候同时销毁工具条

// Generated message map functions
protected:
	//{{AFX_MSG(CMainFrame)

	/*
	1、OnCreate主要用来创建窗口的风格,如最大化、最小化窗口、宽度等
	2、其中的LPCREATESTRUCT是一指向结构体createstruct的指针。该结构体中定义窗口的一些基本信息如x,y坐标等。
	*/
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
		// NOTE - the ClassWizard will add and remove member functions here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

/

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MAINFRM_H__66FE9084_4CA5_468F_AD1F_25852054AC1F__INCLUDED_)

十一、MainFrm.cpp类解析

MainFrm.cpp类是用来生存主窗口的

// MainFrm.cpp : implementation of the CMainFrame class
//

#include "stdafx.h"
#include "wd.h"

#include "MainFrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CMainFrame

IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)//与头文件中的Declare对应

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
	//{{AFX_MSG_MAP(CMainFrame)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code !
	ON_WM_CREATE()//WM_CREATE的消息映射入口项:ON_WM_CREATE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/*
1、调用CMFCStatusBar::SetIndicators函数为状态栏划分窗格,并为每个指示器设置显示文本。

   CMFCStatusBar::SetIndicators函数需要一个ID数组的参数,在MainFrm.cpp中,如下定义了一个窗格ID的数组indicators[]
2、   indicators数组定义了状态栏窗格的划分信息。第一个元素一般为ID_SEPARATOR,对应的窗格用来显示命令提示信息,
上面数组中的后三项为指示器文本的字符串ID,可以根据这些ID在String Table字符串资源中找到相应的字符串,查找方法是,
在Resource View资源视图中,打开String Table字符串资源,可以看到有ID、Value和Caption三列,在ID列中找到需要的ID,
对应的Caption列文本就是要查找的字符串。ID_INDICATOR_CAPS、ID_INDICATOR_NUM和ID_INDICATOR_SCRL对应的字符串分别是CAP、NUM、SCRL,
对应的三个窗格分别为Caps Lock指示器、Num Lock指示器和Scroll Lock指示器。
*/
static UINT indicators[] =
{
	ID_SEPARATOR,           // status line indicator
	ID_INDICATOR_CAPS,
	ID_INDICATOR_NUM,
	ID_INDICATOR_SCRL,
};

/
// CMainFrame construction/destruction

CMainFrame::CMainFrame()
{
	// TODO: add member initialization code here
	
}

CMainFrame::~CMainFrame()
{
}

/*
创建主窗口
*/
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	//若父类CMDIFramWnd创建失败,则返回-1
	if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	//加载toolbar
	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))
	{
		/*
		1、这里看到TRACE0这个玩意,看来是为调试而准备的;
		2、	TRACE0 
			TRACE0(exp) 
		说明: 
			与TRACE相似,但他把跟踪字符串放在代码段中,而不是DGROUP,因此使用少的DGROUP空间。
			TRACE0是一组跟踪宏的一个变体,这些宏可用于调试输出。这一组包括TRACE0,TRACE1,TRACE2和TRACE3,这些宏不同在于所取参数的数目不同。
			TRACE0只取一个格式化字符串并可用于简单文本消息。TRACE1取一格式化字符串加上一个变量——一个将转储的变量。
			同样,TRACE2,TRACE3分别取2个或3个参数(在格式化字符串之后)。如果用户以便以了应用程序的发行版,那么它只把数据转储到afxDump。 
		注释: 
			此宏只在MFC的DEBUG中有效。
		*/
		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
	}

	// TODO: Delete these three lines if you don't want the toolbar to
	//  be dockable
	//很显然,下面的三行主要用于设置工具栏和菜单栏可停靠,可在生成的主窗口的 查看 下看到 工具栏和 菜单栏 是否可停靠。
	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
	EnableDocking(CBRS_ALIGN_ANY);
	DockControlBar(&m_wndToolBar);

	return 0;
}

/*
默认调用父类CMDIFramWnd的PreCreateWindows函数
*/
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	if( !CMDIFrameWnd::PreCreateWindow(cs) )
		return FALSE;
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return TRUE;
}

/
// CMainFrame diagnostics

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
	CMDIFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
	CMDIFrameWnd::Dump(dc);
}

#endif //_DEBUG

/
// CMainFrame message handlers

十二、ChildFrm.h文件解析

ChilFrm.h文件是应用程序子窗口生成类ChildFrm.cpp的头文件,比较简单,基本不用说了,因为里面的东西前面已经说过很多次了

// ChildFrm.h : interface of the CChildFrame class
//
/

#if !defined(AFX_CHILDFRM_H__2976A9A6_F4A2_45CC_99C0_06074DF20356__INCLUDED_)
#define AFX_CHILDFRM_H__2976A9A6_F4A2_45CC_99C0_06074DF20356__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


class CChildFrame : public CMDIChildWnd
{
	DECLARE_DYNCREATE(CChildFrame)//声明该类运行时可创建
public:
	CChildFrame();

// Attributes
public:

// Operations
public:

// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CChildFrame)
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
	//}}AFX_VIRTUAL

// Implementation
public:
	virtual ~CChildFrame();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

// Generated message map functions
protected:
	//{{AFX_MSG(CChildFrame)
		// NOTE - the ClassWizard will add and remove member functions here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

/

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_CHILDFRM_H__2976A9A6_F4A2_45CC_99C0_06074DF20356__INCLUDED_)

十三、ChildFrm.cpp

// ChildFrm.cpp : implementation of the CChildFrame class
//

#include "stdafx.h"
#include "wd.h"

#include "ChildFrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CChildFrame

IMPLEMENT_DYNCREATE(CChildFrame, CMDIChildWnd)

BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWnd)
	//{{AFX_MSG_MAP(CChildFrame)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code !
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CChildFrame construction/destruction

CChildFrame::CChildFrame()
{
	// TODO: add member initialization code here
	
}

CChildFrame::~CChildFrame()
{
}

BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	if( !CMDIChildWnd::PreCreateWindow(cs) )
		return FALSE;

	return TRUE;
}



/
// CChildFrame diagnostics

#ifdef _DEBUG
void CChildFrame::AssertValid() const
{
	CMDIChildWnd::AssertValid();
}

void CChildFrame::Dump(CDumpContext& dc) const
{
	CMDIChildWnd::Dump(dc);
}

#endif //_DEBUG

/
// CChildFrame message handlers

吐舌头至此,wd工程的wd files目录下的 Source Files和Header Files目录下的文件解析完毕,对MFC有没有感觉了现在?接下来解释 wd 工程下的Resource Files目录下的文件

十四、Toolbar.bmp

显然是工具栏的bmp图

十五、wd.ico

显然是MFC窗口的图标

十六、wdDoc.ico

显然是文档的图标

十七、wd.rc2解析

1、rc和rc2都是资源文件,包含了应用程序中用到的所有的资源。

2、两者不同在于:rc文件中的资源可以直接在VC集成环境中以可视化的方法进行编辑和修改;

     而rc2中的资源不能在VC的集成环境下直接进行编辑和修改, 而是由根据需要手工地进行编辑。

3、RC2文件:包含项目使用的附加资源的脚本文件。可以在项目的 .rc 文件的顶部包括 .rc2 文件。 
4、.rc2 文件用于存放由多个不同项目使用的资源。不必为不同的项目多次创建相同的资源,而是可以将它们放在一个 .rc2 文件中,然后将该 .rc2 文件包括在主 .rc 文件中。

5、.rc2 扩展资源文件,当调用到其它project的资源的时候就会产生,用到资源的时候,比如说一个图片等等……

吐舌头至此,wd工程的wd files目录下的 Resource Files目录下的文件解析完毕,接下来解析wd files目录下的最后一个目录External Dependencies目录下的文件

十八、basetsd.h文件解析

/*++

Copyright (c) 1997-1998  Microsoft Corporation

Module Name:

    basetsd.h

Abstract:

    Type definitions for the basic sized types.

Author:

    Jeff Havens (jhavens)   23-Oct-1997

Revision History:

--*/

/*
1、为了帮助程序员修改现有的源代码,转而使用新的数据类型,microsoft将在nt 5.0 beta 2版中包含一些开发辅助工具,其中包括一个定义新数据类型的头文件basetsd.h和一个语法检查器。
2、由于不能将指针转换成int、uint、long、ulong、dword等字长固定为32位的类型,如果需要对指针做运算,应把指针转换为int-ptr或uint-ptr,这两种类型在不同平台上才有正确的字长。另外,由于handle实质上是一个指针(void *),因此把handle转换成long或ulong等类型也是不正确的。
3、如果需要对指针进行截断,那么应使用ptrtolong()和ptrtoulong()两个函数(在basetsd.h中定义)来进行,它们可以屏蔽掉指针截断警告,不过截断的结果不能够再当指针使用了。
4、说白了,这是微软新增的一个对指针操作的一种新的工具
*/

#ifndef _BASETSD_H_
#define _BASETSD_H_

#ifdef __cplusplus
extern "C" {
#endif

//
// The following types are guaranteed to be signed and 32 bits wide.
//

typedef int LONG32, *PLONG32;
typedef int INT32, *PINT32;

//
// The following types are guaranteed to be unsigned and 32 bits wide.
//

typedef unsigned int ULONG32, *PULONG32;
typedef unsigned int DWORD32, *PDWORD32;
typedef unsigned int UINT32, *PUINT32;

//
// The INT_PTR is guaranteed to be the same size as a pointer.  Its
// size with change with pointer size (32/64).  It should be used
// anywhere that a pointer is cast to an integer type. UINT_PTR is
// the unsigned variation.
//
// HALF_PTR is half the size of a pointer it intended for use with
// within strcuture which contain a pointer and two small fields.
// UHALF_PTR is the unsigned variation.
//

#ifdef _WIN64

typedef __int64 INT_PTR, *PINT_PTR;
typedef unsigned __int64 UINT_PTR, *PUINT_PTR;

#define MAXINT_PTR (0x7fffffffffffffffI64)
#define MININT_PTR (0x8000000000000000I64)
#define MAXUINT_PTR (0xffffffffffffffffUI64)

typedef unsigned int UHALF_PTR, *PUHALF_PTR;
typedef int HALF_PTR, *PHALF_PTR;

#define MAXUHALF_PTR (0xffffffffUL)
#define MAXHALF_PTR (0x7fffffffL)
#define MINHALF_PTR (0x80000000L)

#pragma warning(disable:4311)   // type cast truncation

#if !defined(__midl)
__inline
unsigned long
HandleToUlong(
    void *h
    )
{
    return((unsigned long) h );
}

__inline
unsigned long
PtrToUlong(
    void  *p
    )
{
    return((unsigned long) p );
}

__inline
unsigned short
PtrToUshort(
    void  *p
    )
{
    return((unsigned short) p );
}

__inline
long
PtrToLong(
    void  *p
    )
{
    return((long) p );
}

__inline
short
PtrToShort(
    void  *p
    )
{
    return((short) p );
}
#endif
#pragma warning(3:4311)   // type cast truncation

#else


typedef long INT_PTR, *PINT_PTR;
typedef unsigned long UINT_PTR, *PUINT_PTR;

#define MAXINT_PTR (0x7fffffffL)
#define MININT_PTR (0x80000000L)
#define MAXUINT_PTR (0xffffffffUL)

typedef unsigned short UHALF_PTR, *PUHALF_PTR;
typedef short HALF_PTR, *PHALF_PTR;

#define MAXUHALF_PTR 0xffff
#define MAXHALF_PTR 0x7fff
#define MINHALF_PTR 0x8000

#define HandleToUlong( h ) ((ULONG) (h) )
#define PtrToUlong( p ) ((ULONG) (p) )
#define PtrToLong( p ) ((LONG) (p) )
#define PtrToUshort( p ) ((unsigned short) (p) )
#define PtrToShort( p ) ((short) (p) )

#endif

//
// SIZE_T used for counts or ranges which need to span the range of
// of a pointer.  SSIZE_T is the signed variation.
//

typedef UINT_PTR SIZE_T, *PSIZE_T;
typedef INT_PTR SSIZE_T, *PSSIZE_T;

//
// The following types are guaranteed to be signed and 64 bits wide.
//

typedef __int64 LONG64, *PLONG64;
typedef __int64 INT64, *PINT64;


//
// The following types are guaranteed to be unsigned and 64 bits wide.
//

typedef unsigned __int64 ULONG64, *PULONG64;
typedef unsigned __int64 DWORD64, *PDWORD64;
typedef unsigned __int64 UINT64, *PUINT64;

#ifdef __cplusplus
}
#endif

#endif // _BASETSD_H_

终于结束了,请深吸气回来,呼气出去!对MFC的每个文件心存感激!接下来,好好在这个wizard给予我们的空工程框架上谱写自己东西吧!加油!




  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值