创建的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是你project的头,你能够通过AfxGetApp()获得整个进程的指针,然后通过它。能够获得该进程的HWND以及HINSTANCE。和菜单。。。等等。不一而足。能够通过msdn获得很多其它的信息 //2.theApp是个全局变量。差点儿能够在程序的不论什么地方引用。假设你建立一个MDI或者SDIproject,那么。你能够看到一个类以*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. //近期文件列表能够让你非常方便地打开你以前以前打开过的文件,那么,怎样为自己的应用程序加入近期文件列表功能呢?最简单的方法就是在你新建project的时候选择包括近期文件列表功能,也就是在 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,该文件包括了全部当前project文件须要的MFCinclude文件。且这一文件能够随被选择的选项而变化。 ◎AppWizard然后就建立stdafx.cpp。这个文件通常都是一样的。
◎然后AppWizard就建立起project文件,这样第一个被编译的文件就是stdafx.cpp。 ◎当VisualC++编译stdafx.cpp文件时。它将结果保存在一个名为stdafx.pch的文件中。(扩展名pch表示预编译头文件。
) ◎当VisualC++编译随后的每一个.cpp文件时,它阅读并使用它刚生成的.pch文件。VisualC++不再分析Windowsinclude文件。除非你又编缉了stdafx.cpp或stdafx.h。 这个技术非常静止,你不这么觉得吗?(还要说一句。Microsoft并不是是首先採用这样的技术的公司,Borland才是。)在这个过程中你必须遵守下面规则: ◎你编写的不论什么.cpp文件都必须首先包括stdafx.h。 ◎假设你有project文件中的大多数.cpp文件须要.h文件,顺便将它们加在stdafx.h(后部)上,然后预编译stdafx.cpp。 ◎因为.pch文件具有大量的符号信息,它是你的project文件中最大的文件。
假设你的磁盘空间有限。你就希望能将这个你从没使用过的project文件中的.pch文件删除。
执行程序时并不须要它们,且随着project文件的又一次建立。它们也自己主动地又一次建立 */ #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
八、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的资源。假设不能理解这句,能够在你的project里面打开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
至此,wdproject的wd files文件夹下的 Source Files和Header Files文件夹下的文件解析完成。对MFC有没有感觉了如今?接下来解释 wd project下的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的资源的时候就会产生。用到资源的时候,比方说一个图片等等……
至此,wdproject的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给予我们的空project框架上谱写自己东西吧!
加油!