回 帖 发 新 帖 刷新版面

主题:那位高人能讲讲有关“宏”的定义,用法等。谢谢!

那位高人能讲讲有关“宏”的定义,用法等。谢谢!

回复列表 (共2个回复)

沙发

#define sdf 3+3*5

C中定义后'sdf' 宏替换为'3+3*5'其他类似!
 
 注:不是高手!

板凳

数据类型
本章列出了微软基础类库中最常见的数据类型。大多数数据类型是与Windows软件开发工具包(SDK)中一致的,也有一些是MFC独有的。下面的数据类型是Windows SDK 和MFC共用的:
l BOOL  布尔值。
l BSTR  32位字符指针。
l BYTE  8位无符号整数。
l COLORREF  用作颜色值的32位值。
l DWORD  32位无符号整数,或者是段地址以及与之相关的偏移量。
l LONG  32位带符号整数。
l LPARAM  32位值,作为参数传递给一个窗口过程或者回调函数。
l LPCSTR  指向字符串常量的32位指针。
l LPSTR  指向字符串的32位指针。
l LPCTSTR  指向一个兼容 Unicode 和DBCS的字符串的32 位指针。
l LPTSTR  指向一个兼容 Unicode 和 DBCS 的字符串的32位指针。
l LPVOID  指向一个未指定类型的32位指针。
l LRESULT  窗口过程或者回调函数返回的32位值。
l UINT  在Windows 3.0和3.1中表示16位的无符号整数,在Win32中表示32位的无符号整数。
l WNDPROC  指向一个窗口过程的32位指针。
l WORD  16位无符号整数。
l WPARAM  作为参数传递给窗口函数或者回调函数的值:在Windows 3.0和3.1 中为16位,在Win32中为32位。微软基础类库中独有的数据类型如下:
l POSITION  用于标记集合中一个元素的位置的值;被MFC中的集合类所使用。l LPCRECT  指向一个RECT结构体常量(不能修改)的32位指针。
在《Win32 SDK 程序员参考》的“数据类型”部分,有个不太通用的数据类型的列表。
MFC类对象的强制类型转换
强制类型转换宏提供了一种方式,可以将一个给定的指针转换为指向特定类的对象的指针,并不需要检查这种转换是否合法。
下面的表格列出了MFC中的强制类型转换宏:
将指针强制转换为MFC类的对象的宏
DYNAMIC_DOWNCAST将一个指针转换为指向一个对象的指针,同时检查这种转换是否合法
STATIC_DOWNCAST将指向一个类的对象的指针转换为另一个相关类型的指针。在调试版本中,如果该对象不能转换为目标类型,会引起ASSERT
运行时对象模型服务
CObject和CRuntimeClass这两种类封装了一些对象服务,包括对运行时对象信息的访问,串行化以及动态对象创建。所有从CObject继承的类都继承了这些功能。
通过访问运行时对象信息,你可以在运行时决定对象的信息。当你需要额外的函数参数类型检查,或者你需要编写与类和对象有关的用于特定目的的代码时,这种在运行时决定对象信息的能力非常有用。C++语言本身并不直接支持运行时对象信息。
串行化是指向一个文件写入或者从一个文件读出对象的内容的过程。通过串行化,你即使在应用程序退出以后也还可以保存对象的信息。当应用程序重新启动以后,你可以从文件中读入对象的内容。这样的数据对象被称为是“永久性”的。
动态对象创建功能使你能够在运行时创建指定类型的对象。例如,文档、视和框架对象必须支持动态创建,因为应用框架必须动态地创建它们。下面的表格列出了支持运行时类信息、串行化和动态创建的MFC宏。如果需要关于运行时对象服务和串行化的更详细的信息,可以参考《Visual C++程序员指南》中的“CObject 类:访问运行时类信息”部分。
运行时对象模式服务宏
DECLARE_DYNAMIC允许对运行时类信息进行访问(必须在类定义中使用)
DECLARE_DYNCREATE允许动态创建和访问运行时类信息(必须在类定义中使用)
DECLARE_SERIAL允许串行化和访问运行时类信息(必须在类定义中使用)
IMPLEMENT_DYNAMIC允许对运行时类信息进行访问(必须在类的实现中使用)
IMPLEMENT_DYNCREATE允许动态创建和访问运行时类信息(必须在类的实现中使用)IMPLEMENT_SERIAL允许串行化和访问运行时类信息(必须在类的实现中使用)
RUNTIME_CLASS返回与指定名字的类对应的CRuntimeClass结构
OLE经常需要在运行时动态地创建对象。例如,一个OLE服务器必须能够在响应客户的请求时动态地创建OLE项目。类似地,一个自动化服务器也必须能够在响应自动化客户的请求时动态地创建项目。微软基础类库特别为OLE提供了两个宏。
OLE Objects的动态创建
DELCARE_OLECREATE允许通过OLE自动化创建对象IMPLEMENT_OLECREATE允许由OLE系统创建对象
诊断服务
微软基础类库支持许多诊断服务功能,这会使你的调试工作更加简单。这些诊断服务包括一些宏和全局函数,它们允许你跟踪程序的内存分配,在运行时转储对象的内容及在运行时打印调试信息。这些用于诊断服务的宏和全局函数可以组成以下几个类别:l 通用诊断宏。l 通用诊断函数和变量。l 对象诊断函数。
在MFC的调试和发行版本中,所有从CObject继承的类都可以使用这些宏和函数。但是,除了DEBUG_NEW和VERIFY以外,其他的在发行版本中都不起任何作用。在调试版本的类库中,所有被分配的内存块都包含一部分“保护字节”。如果这些字节被非正常的内存读写所扰乱,诊断例程就会报告出问题。
如果你在程序文件中包含了如下的程序行:
#define new DEBUG_NEW所有对new的调用将保存了产生内存分配的文件名和行号。函数CMemoryState::Dump- AllObjectsSince 将会显示这些附加信息,使你能够识别内存泄漏。同时还可以参考CDumpContext类在诊断输出中给出的附加信息。另外,C运行时库同样支持一个诊断函数集,你可以利用它来调试程序。如果需要获得更多的信息,请参阅《Microsoft Visual C++ 6.0库参考》中的《MicrosoftVisual C++ 6.0运行库参考》一卷中的“诊断例程”一文。
MFC 通用调试宏
ASSERT在调试版本的库中,如果指定的表达式计算结果为FALSE,则打印出一条消息,然后退出程序ASSERT_KINDOF测试一个对象是否属于一个指定的类或者从指定类继承而来的类
ASSERT_VALID调用对象的AssertValid成员函数测试对象的内部完整性;通常由CObject继承而来DEBUG_NEW在调试模式下提供所有对象分配的文件名和行号以帮助发现内存泄漏TRACE在类库的调试版本中提供了类似printf的功能TRACE0与TRACE类似,但是接受的格式字符串不包括参数TRACE1与TRACE类似,但是接受的格式字符串只包括一个参数TRACE2与TRACE类似,但是接受的格式字符串只包括两个参数TRACE3与TRACE类似,但是接受的格式字符串只包括三个参数VERIFY与ASSERT类似,但是在Release版本中也象Debug版本一样计算表达式的值MFC
通用诊断变量和函数
afxDump全局变量,将CdumpContext信息发送的调试器输出窗口或者调试终端afxMemDF全局变量,控制着调试内存分配器的特性
afxTraceEnabled全局变量,用于开放或者禁止TRACE宏的输出
afxTraceFlags全局变量,用于打开MFC内建的报告特性
AfxCheckError全局变量,用于测试传送的SCODE,检查是否是错误,如果是,抛出适当的错误
AfxCheckMemory检查当前分配的所有内存的完整性
AfxDump如果在调试器内调用,则在调试时转储对象的状态
AfxDumpStack生成当前栈的一个图象。这个函数通常被静态连接
AfxEnableMemoryTracking打开或关闭内存跟踪
AfxIsMemoryBlock检验一个内存块是否被正确地分配
AfxIsValidAddress检验一个内存地址是否属于程序的地址范围
AfxIsValidString检验一个指向字符串的指针是否有效
AfxSetAllocHook允许在每次进行内存分配时调用一个函数MFC 对象诊断函数
AfxDoForAllClasses对所有从CObject继承的支持运行时类型检查的类执行一个指定的功能
AfxDoForAllObjects对所有从CObject继承的用new分配内存的对象执行一个指定的功能
异常处理
在程序执行的过程中,可能会发生一些称为“异常”的非正常状态或者错误。这些异常可能包括内存耗尽,资源分配错误或是找不到文件等。微软基础类库中采用的异常处理模式和ANSI标准化委员会建议的C++异常处理方式很接近。异常处理函数必须在调用可能发生不正常状态的函数之前建立。如果这个函数遇到了不正常的状态,它就抛出一个异常,并且将控制权转移给异常处理函数。微软基础类库中包含的某些宏可以建立异常处理函数。另有一些全局函数有助于抛出异常并在必要时终止程序。这些宏和全局函数可以分为以下几类:l 异常宏,生成异常处理函数的结构。l 异常抛出函数,生成特定类型的异常。l 终止函数,使程序终止。如果需要示例和更多的细节,请参阅《Visual C++程序员指南》中的“异常”部分。
异常宏TRY声明一段代码为异常处理CATCH声明一段代码,用于捕捉前面的TRY块产生的一个异常CATCH_ALL声明一段代码,用于捕捉前面的TRY块产生的所有异常
AND_CATCH声明一段代码,用于捕捉前面的TRY块产生的其他类型的异常
AND_CATCH_ALL声明一段代码,用于捕捉前面的TRY块抛出的所有其他类型的异常
END_CATCH结束上一个CATCH或AND_CATCH块
END_CATCH_ALL结束上一个CATCH_ALL代码块THROW抛出一个指定的异常THROW_LAST抛出当前处理的异常,交给后面的处理函数异常抛出函数
AfxThrowArchiveException抛出一个档案异常
AfxThrowFileException抛出一个文件异常
AfxThrowMemoryException抛出一个内存异常
AfxThrowNotSupportedException抛出一个不支持的异常
AfxThrowResourceException抛出一个Windows的未找到资源异常
AfxThrowUserException在用户初始化的程序动作中抛出一个异常MFC特别为OLE异常提供了两个异常抛出函数。OLE 异常函数
AfxThrowOleDispatchException在OLE自动化函数内抛出一个异常
AfxThrowOleException抛出一个OLE异常为了支持数据库异常,数据库类提供了两个异常类,CDBException和CDaoException,还有一些全局函数用于支持异常类型:
DAO异常函数AfxThrowDAOException从你自己的代码中抛出一个CDaoException异常AfxThrowDBException从你自己的代码中抛出一个CDBException异常  MFC提供了下列终止函数:终止函数AfxAbort当发生了致命错误时用于结束应用程序请参阅  CExceptionCString格式化和消息框显示有一些函数被用于格式化和处理CString对象。不论何时你需要操作CString对象,你都可以利用这些函数,但是在格式化将被显示在消息框中的文本时,这些函数特别有用。这组函数中同时还包括了用于显示消息框的全局例程。CString 函数AfxFormatString1用一个字符串替换给定字符串中的格式字符“%1”
AfxFormatString2用两个字符串替换给定字符串中的两个格式字符“%1”和“%2”
AfxMessageBox显示一个消息框请参阅  CString应用程序信息和管理当你编写一个应用程序的时候,要创建一个从CWinApp继承而来的对象。此时,可能你希望从这个对象的外部获取它的有关信息。微软基础类库提供了下列全局函数,用以帮助你完成这些任务:应用程序信息和管理函数
AfxFreeLibrary减少已调入内存的动态链接库(DLL)模块的引用计数,当引用计数减到0时,这个模块就会被释放
AfxGetApp返回应用程序中唯一的CWinApp对象的指针
AfxGetAppName返回一个包含应用程序名字的字符串
AfxGetInstanceHandle返回一个代表应用程序实例的HINSTANCE变量
AfxGetMainWnd返回指向非OLE应用程序的当前主窗口的指针,或者是服务器程序的现场框架窗口AfxGetResourceHandle返回代表应用程序的缺省资源的HINSTANCE变量。可以利用它来直接访问应用程序的资源
AfxInitRichEdit为应用程序初始化RichEdit控件,如果公共控件库还没有被初始化,则初始化公共控件库AfxLoadLibrary调入一个DLL模块,同时返回一个句柄,可以通过它来得到DLL函数的地址AfxRegisterWndClass注册一个Windows的窗口类,用它来替换MFC自动注册的窗口类
AfxSocketInit在CwinApp::InitInstance的重载函数中调用,用它来初始化Windows的Socket协议AfxSetResourceHandle设置指向应用程序调入的缺省资源的句柄
AfxRegisterClass在使用MFC的DLL中注册一个窗口类
AfxBeginThread创建一个新的线程
AfxEndThread结束当前线程
AfxGetThread获得指向当前CwinThread对象的指针
AfxWinInit由MFC提供的WinMain函数调用,是基于GUI的应用程序中CwinApp初始化的一部分,用于初始化MFC。在使用MFC的控制台程序中必须直接调用请参阅
CwinApp标准命令和窗口Ids
微软基础类库在AFXRES.H中定义了一系列标准的命令和窗口ID。这些ID通常在资源编辑器中使用,ClassWizard也使用它们来将消息映射到你的处理函数。所有的标准命令都带有ID_前缀。例如,当你使用菜单编辑器的时候,你通常会将文件菜单中的打开菜单项与标准的ID_FILE_OPEN命令ID绑定在一起。对于大多数标准命令,应用程序不需要引用其命令ID,因为应用框架本身在它的框架类(CwinThread, CwinApp, Cview, Cdocument等等)的消息映射中处理了这些命令。除了这些标准的命令ID以外,还定义了一些以AFX_ID为前缀的标准ID。这些ID包括标准的窗口ID(以AFX_IDW为前缀),字符串ID(以AFX_IDS_为前缀),以及其他几种类型。以AFX_ID为前缀的ID很少由程序员使用,但是当你需要重载那些引用了AFX_ID的框架函数的时候,你可能需要引用这些ID。这儿并不单独描述这些ID。在技术注释文档的第20,21和22篇中,你可以找
访问类型库类型库揭示了OLE控件与其它具有OLE能力的应用程序之间的接口。如果OLE控件需要提供一个或多个接口,它必须具有一个类型库。下面列出的宏使OLE控件能够提供对它自己的类型库的访问。
类型库访问
DECLARE_OLETYPELIB定义了OLE控件的GetTypeLib成员函数(必须在类定义中使用)IMPLEMENT_OLETYPELIB实现了OLE控件的GetTypeLib成员函数(必须在类实现中使用)
事件映射
不论何时,如果一个控件想要通知它的容器,有些动作(取决于控件的设计者)已经发生(比如按键、鼠标点击,或者控件状态的变化等),它就调用一个事件引发的函数。这个函数通过产生相应的事件来通知控件的容器一些重要的动作已经产生了。微软基础类库提供了一种为事件引发而优化的编程模式。在这种模式中,使用了“事件映射”来指定对于一个特定的控件,哪个函数引发哪个事件。事件映射中为每个事件包含了一个宏。例如,一个引发点击事件的事件映射可能是这样的:
BEGIN_EVENT_MAP(CSampleCtrl,COleControl) //{{AFX_EVENT_MAP(CSampleCtrl)    EVENT_STOCK_CLICK( )//}}AFX_EVENT_MAPEND_EVENT_MAP()EVENT_STOCK_CLICK宏指明这个控件每检测到一次鼠标点击就引发一个点击事件。如果要获得其它预定事件的详细列表,请参阅《Visual C++程序员指南》中的“ActiveX控件事件”一文。
还要一些宏可以用来指明自定义的事件。尽管事件映射宏很重要,通常你并不会直接插入它们。这是因为当你使用事件映射将事件引发的函数与事件联系起来时,ClassWizard会在你的源代码中自动地创建一个事件映射入口。不论何时你想编辑或者添加事件映射入口,你都可以使用ClassWizard。为了支持事件映射,MFC提供了下列宏:
事件映射定义和分界
DECLARE_EVENT_MAP定义一个事件映射,它将被用于一个类中,将事件映射到一个事件引发的函数(必须在类定义中使用)
BEGIN_EVENT_MAP开始一个事件映射的定义(必须在类的实现中使用)
END_EVENT_MAP结束一个事件映射的定义(必须在类的实现中使用)
事件映射宏
EVENT_CUSTOM指明哪个事件引发函数将引发特定的事件
EVENT_CUSTOM_ID指明哪个事件引发函数将引发特定的具有指定调度ID的事件消息映射宏
ON_OLEVERB指明OLE控件处理的一个自定义的动词
ON_STDOLEVERB重载一个OLE控件的标准动词映射事件接收映射当一个嵌入的OLE控件引发一个事件时,该控件的容器通过一个MFC提供的称为“事件接收映射”的机制接收事件。这种事件接收映射为每个特定的事件分配处理函数,包括这些事件的参数。如果需要获得有关事件接收映射的更多的信息,请参阅《Visual C++程序员指南》中的“ActiveX控件容器”一文。
事件接收映射
BEGIN_EVENTSINK_MAP开始一个事件接收映射的定义
DECLARE_EVENTSINK_MAP定义一个事件接收映射END_EVENTSINK_MAP结束一个事件接收映射的定义ON_EVENT为特定的事件指定一个事件处理函数ON_EVENT_RANGE为一系列OLE控件引发的事件定义一个事件处理函数
ON_EVENT_REFLECT在被控件的容器处理之前接收控件所引发的事件
ON_PROPNOTIFY定义一个处理函数以处理OLE控件产生的属性通知
ON_PROPNOTIFY_RANGE定义一个处理函数以处理一个OLE控件集合产生的属性通知ON_PROPNOTIFY_REFLECT在被控件的容器处理之前接收控件发出的属性通知连接映射OLE控件可以向别的应用程序提供接口。这些接口仅允许容器对控件进行访问。如果一个OLE控件希望访问其它OLE对象的外部接口必须建立一个连接点。这个连接点允许一个控件访问外部的调度映射,比如事件映射或通知函数。微软基础类库提供了支持这种连接点的编程模式。在这种模式中,利用“连接映射”来为OLE控件指派接口(或者连接点)。连接映射中为每个连接点包含了一个宏。如果要获得有关连接映射的更多信息,参见CConnectionPoint类。
典型的情况是,一个控件将仅仅支持两个连接点:一个用于事件,一个用于属性通知。这是由COleControl基类实现的,并且不需要控件的编写者再作什么额外的工作。你希望在你的类中实现的任何附加的连接点都必须手动添加。为了支持连接映射和连接点,MFC提供了下列宏:
连接映射定义和分界
BEGIN_CONNECTION_PART声明一个嵌入类,它实现了附加的连接点(必须在类定义中使用)END_CONNECTION_PART结束一个连接点的定义(必须在类定义中使用)
CONNECTION_IID指定控件的连接点的接口
IDDECLARE_CONNECTION_MAP声明一个连接映射将被用在一个类中(必须在类定义中使用)BEGIN_CONNECTION_MAP开始一个连接映射的定义(必须在类实现中使用)
END_CONNECTION_MAP结束一个连接映射的定义(必须在类实现中使用)
CONNECTION_PART指定控件的连接映射中的连接点下面的函数帮助建立和断开一个使用连接点的连接:连接点的初始化/终止AfxConnectionAdvise在源端和接收端之间建立一个连接AfxConnectionUnadvise中断源端和接收端之间的一个连接
宏、全局函数和全局变量
这个部分描述了MFC库中的全局函数、全局变量以及宏。注意  许多全局函数都以“Afx”前缀开始——除了一些例外,如对话框数据交换(DDX)函数和许多数据库函数以外,都遵从这个约定。所有的全局变量都以“Afx”前缀开始。宏没有任何特定的前缀,但是它们都是大写的。MFC库和活动模板库(ATL)共用一些字符串转换宏。参考ATL文档中的“字符串转换宏”,在那儿讨论了这些宏。如果需要有关C运行库的调试版本以及诊断函数的信息,请参阅《MicrosoftVisual C++6.0库参考》的《Microsoft Visual C++6.0运行库》一卷中的“调试例程”一文。
AfxAbortvoid AfxAbort( ); 宏、全局函数和全局变量这个部分描述了MFC库中的全局函数、全局变量以及宏。注意  许多全局函数都以“Afx”前缀开始——除了一些例外,如对话框数据交换(DDX)函数和许多数据库函数以外,都遵从这个约定。所有的全局变量都以“Afx”前缀开始。宏没有任何特定的前缀,但是它们都是大写的。MFC库和活动模板库(ATL)共用一些字符串转换宏。参考ATL文档中的“字符串转换宏”,在那儿讨论了这些宏。如果需要有关C运行库的调试版本以及诊断函数的信息,请参阅《MicrosoftVisual C++6.0库参考》的《Microsoft Visual C++6.0运行库》一卷中的“调试例程”一文。
AfxAbortvoid AfxAbort( ); 参数pfnThreadProc指向工作线程的控制函数。不能是NULL。这个函数必须按下面的方式定义:UINT MyControllingFunction( LPVOID pParam );pThreadClass从CWinThread继承的对象的RUNTIME_CLASS。pParam将要传送给控制函数的参数,如pfnThreadProc中定义的函数参数所示。nPriority设定的线程的优先级。如果为0,则使用与创建它线程相同的优先级。在《Win32程序员参考》的“SetThreadPriority”中有可用的优先级的完整列表和描述。nStackSize指定新线程使用的栈的以字节为单位的大小。如果为0,则缺省的栈大小与创建它的线程的栈大小相同。dwCreateFlags指定控制线程的创建过程的附加标志。这个标志可以是两个值之一:l CREATE_SUSPENDED经过一个延迟后启动这个线程。这个线程将在调用ResumeThread 以后才会启动。l 0创建后立即启动这个线程。lpSecurityAttrs指向一个SECURITY_ATTRIBUTES结构,它指定了线程的安全特性。如果为空,将使用与创建它的线程相同的安全特性。如果需要获得有关这个结构的详细信息,请参阅《Win32程序员参考手册》。说明调用这个函数以创建一个新的线程。AfxBeginThread的第一种形式创建了一个工作线程。第二种形式创建了一个用户界面线程。AfxBeginThread创建一个新的CWinThread对象,调用它的CreateThread函数以启动这个线程,并且返回这个线程的指针。整个过程都进行检查以保证如果创建失败,所有的对象都会被适当地释放。为了结束这个线程,可以在线程内调用AfxEndThread,或者从工作线程的控制函数内返回。关于AfxBeginThread的更多信息,请参阅《Visual C++程序员指南》中的“多线程:创建工作线程”和“多线程:创建用户界面线程”。请参阅  AfxGetThreadAfxCheckErrorvoid AFXAPI AfxCheckError(SCODE sc);throw CMemoryExcetion *throw COleException *说明这个函数检测传递的SCODE是否是个错误。如果它是个错误,这个函数将抛出一个异常。如果传递的SCODE是个E_OUTOFMEMORY,它就调用AfxThrowMemoryException 抛出一个CMemoryException。否则,它调用AfxThrowOleException抛出一个COleException。这个函数可以用来检查你的应用程序中对OLE函数调用的返回值。通过测试应用程序中函数调用的返回值,你就可以用很少的代码正确地响应错误状态。注意  这个函数在调试版本和非调试版本中具有相同的效果。
示例
LPDISPATCHpDisp=NULL;AfxCheckError(CoCreateInstance(CLSID,NULL,CLSCTX_LOCAL_SERVER,IID_IDispatch, (LPVOID)&pDisp));// 如果有错误,则已经抛出了一个异常// 我们可以开始使用返回的指针COleDispatchDriver disp(pDisp);//等等...AfxCheckMemoryBOOL AfxCheckMemory( );返回值如果没有内存错误,则为非零值;否则为0。说明这个函数使自由内存池有效并在需要时输出错误信息。如果这个函数没有检测到内存冲突,它什么也不输出。当前在堆中分配的所有内存块都会被检查,包括那些用 new分配的内存,但是不包括那些用直接调用内存分配函数分配的内存,例如malloc函数或者Windows的GlobalAlloc函数。如果发现有内存块存在错误,就会在调试器上输出错误信息。
如果你在程序模块中包含了下面的程序行:#define new DEBUG_NEW后面对AfxCheckMemory的调用都会显示发生内存分配的文件名和行号。注意  如果你的模块中包含了一个或多个串行化类的实现,那么你必须在最后一个IMPLEMENT_SERIAL宏之后包含#define程序行。这个函数仅在MFC的调试版本中起作用。
示例// AfxCheckMemory的例子
CAge* pcage = new CAge( 21 );  // CAge 是从 CObject.继承而来的
Age* page = new Age( 22 );     // Age 不是从 CObject.继承的
*(((char*) pcage) - 1) = 99;   // 破坏前面的保护字节
*(((char*) page) - 1) = 99;    // 破坏前面的保护字节
AfxCheckMemory();
程序的结果如下:memory check error at $0067495F = $63, should be $FDDAMAGE: before Non-Object block at $00674960Non-Object allocated at file test02.cxx(48)Non-Object located at $00674960 is 2 bytes long
memory check error at $00674905 = $63, should be $FDDAMAGE: before Object block at $00674906Object allocated at file test02.cxx(47)Object located at $00674906 is 6 bytes longAfxConnectionAdviseBOOL AFXAPI AfxConnectionAdvise(LPUNKNOWN pUnkSrc,REFIID iid,LPUNKNOWN pUnkSink,BOOL bRefCount,DWORD FAR*pdwCookie);
返回值如果建立了连接则为非零值,否则为0。参数pUnkSrc指向调用接口的对象的指针。pUnkSink指向实现接口的对象的指针。
结构、风格、回调函数和消息映射
这个部分描述了微软基础类库使用的结构,风格和回调函数,还描述了MFC的消息映射。MFC使用的结构这个主题后面是对不同成员函数调用的结构的描述。有关每个结构的用法的进一步信息参看每个结构的“请参阅”列表中列出的类和成员函数。ABC 结构ABC结构具有如下形式:
typedef struct _ABC
{ /* abc */   
int     abcA;  
UINT    abcB;
int     abcC;
} ABC;
ABC结构包含了TrueType字体中字符的宽度。成员abcA指定了字符的A宽度。A宽度是指画出的字符图形离当前位置的距离。abcB指定了字符的B宽度。B宽度是指画出的字符图形的宽度。abcC指定了字符的C宽度。C宽度是指加在当前位置上的距离,用于提供字符图形右边的空白。注释字符的总宽度是A,B和C宽度的总和。A或C宽度都可以是负的,指明上悬或下垂。请参阅  CDC::GetCharABCWidthsABCFLOAT 结构ABCFLOAT结构具有如下形式:
typedef struct _ABCFLOAT
{ /* abcf */
FLOAT   abcfA;    
FLOAT   abcfB;    
FLOAT   abcfC;
} ABCFLOAT;
ABCFLOAT结构包含了字符的A,B和C宽度。成员abcfA指定了字符的A宽度。A宽度是指画出的字符图形离当前位置的距离。abcfB指定了字符的B宽度。B宽度是指画出的字符图形的宽度。abcfC指定了字符的C宽度。C宽度是指加在当前位置上的距离,用于提供字符图形右边的空白。注释A,B和C宽度是根据字体的基准线测量的。字符的增量(总宽度)是A,B和C宽度的总和。A或C宽度都可以是负数,表明上悬或下垂。请参阅  CDC::Get CharABCWidthsAFX_EXTENSION_MODULE 结构AFX_EXTENSION_MODULE 结构具有如下形式:
struct AFX_EXTENSION_MODULE{
BOOL bInitialized;   
HMODULE hModule;   
HMODULE hResource;   
CRuntimeClass* pFirstSharedClass;   
COleObjectFactory* pFirstSharedFactory;};
AFX_EXTENSION_MODULE被用在MFC扩展DLL的初始化过程中,用于保存扩展DLL模块的状态。成员bInitialized如果DLL模块已经用AfxInitExtensionModule初始化了,则为TRUE。hModule指定了DLL模块的句柄。hResource指定了DLL的自定义资源模块的句柄。pFirstSharedClass指向有关DLL模块的第一个运行时类的信息(CRuntimeClass结构)的指针。用于提供运行时类列表的开始部分。pFirstSharedFactory指向DLL模块的第一个对象工厂(COleObjectFactory对象)的指针。用于提供类工厂列表的开始部分。注释MFC扩展DLL需要在它们的DllMain函数中做两件事情:l 调用AfxInitExtensionModule并检查返回值。l 如果DLL要引出CRuntimeClass对象或者拥有它自己的资源,就创建一个CDynLinkLibrary对象。AFX_EXTENSION_MODULE结构被用于保存扩展DLL模块状态的一个备份,包括运行时对象的一个拷贝,它已经在进入DllMain函数之前被扩展DLL作为常规静态对象构造过程的一部分初始化过了。
例如:
static AFX_EXTENSION_MODULE extensionDLL;extern "C" int APIENTRYDllMain(HINSTANCE hInstance,DWORD dwReason,LPVOID){//初始化这个DLL的扩展模块    VERIFY(AfxInitExtensionModule(extensionDLL, hInstance));
AFX_EXTENSION_MODULE结构中保存的模块信息可以被拷贝到CDynLinkLibrary对象中。例如:// CDynLinkLibrary 类IMPLEMENT_DYNAMIC(CDynLinkLibrary, CCmdTarget)// 构造函数CDynLinkLibrary::CDynLinkLibrary(AFX_EXTENSION_MODULE& state,BOOL bSystem){#ifndef _AFX_NO_OLE_SUPPORT   m_factoryList.Construct(offsetof(COleObjectFactory, m_pNextFactory));#endif m_classList.Construct(offsetof(CRuntimeClass, m_pNextClass));   // 从AFX_EXTENSION_MODULE 结构中拷贝信息   ASSERT(state.hModule != NULL);   m_hModule = state.hModule;   m_hResource = state.hResource;   m_classList.m_pHead = state.pFirstSharedClass;#ifndef _AFX_NO_OLE_SUPPORT   m_factoryList.m_pHead = state.pFirstSharedFactory;#endif   m_bSystem = bSystem;请参阅  AfxInitExtensionModule, AfxTermExtensionModuleBITMAP结构BITMAP结构具有如下形式:typedef struct tagBITMAP {  /* bm */    int     bmType;    int     bmWidth;    int     bmHeight;    int     bmWidthBytes;    BYTE    bmPlanes; BYTE    bmBitsPixel;    LPVOID  bmBits;} BITMAP;BITMAP结构定义了逻辑位图的高,宽,颜色格式和位值。成员bmType指定了位图的类型。对于逻辑位图,这个成员必须为0。bmWidth指定了位图的宽度,以像素为单位。宽度必须大于0。bmHeight指定了位图的高度,以扫描行为单位。高度必须大于0。bmWidthBytes指定了每个扫描行中字节的数目。这个值必须是个偶数,因为图形设备接口(GDI)假定位图中的位值构成一个整数(2字节)数组。换句话说,bmWidthBytes*8必须是16的倍数,大于或等于bmWidth与bmBitsPixel相乘所得的值。bmPlanes指定了位图中颜色平面的数目。bmBitsPixel指定了每个位平面中用于定义一个像素所需的颜色位数。bmBits指向位图中位值的位置。bmBits成员必须是一个指向单字节数组的长指针。注释现在使用的位图格式有单色的和彩色的。单色的位图使用每个位平面一位的格式。每个扫描线是16的倍数。对于一个高度为n的单色位图,扫描线是按照如下方式组织的:Scan 0Scan 1...Scan n-2Scan n-1单色设备上的像素不是黑就是白。如果位图中对应的位是1,则像素就被打开(白)。如果对应的位是0,则像素被关闭(黑)。所有具有RC_BITBLT位的设备都支持位图,该位是在CDC::GetDeviceCaps成员函数的RASTERCAPS索引中设置的。每个设备都有它自己的颜色格式。为了在不同的设备间传递位图,使用Windows的GetDIBits和SetDIBits函数。请参阅  CBitmap::CreateBitmapIndirectBITMAPINFO 结构BITMAPINFO结构具有如下形式:typedef struct tagBITMAPINFO {    BITMAPINFOHEADER    bmiHeader;    RGBQUAD             bmiColors[1];} BITMAPINFO;BITMAPINFO结构定义了Windows设备无关位图(DIB)的度量和颜色信息。成员bmiHeader指定了一个BITMAPINFOHEADER结构,包含了有关设备相关位图的度量和颜色格式的信息。bmiColors指定了一个RGBQUAD或DWORD数据类型的数组,定义了位图中的颜色。注释设备无关位图由两个部分组成:一个BITMAPINFO结构,描述了位图的度量和颜色信息;一个字节数组,定义了位图的像素。数组中的字节被组合在一起,但是每个扫描行必须用零填补,在一个LONG边界结束。如果高度为正的,位图的起始位置在左下角。如果高度为负,起始位置在左上角。BITMAPINFOHEADER结构中的biBitCount成员决定了定义像素的位数以及位图中的最大颜色数。这个成员可以是下列值之一:l 位图是单色的,bmiColors成员包含两个入口。位图数组中的每一位代表一个像素。如果该位被清除,则用bmiColors表中的第一种颜色显示该像素。如果该位被置位,则用表中的第二种颜色显示该像素。l 位图最多有16种颜色,bmiColors成员中包含了最多可达16个入口。位图中的每个像素用一个4位的值来表示,该值用作颜色表的索引。例如,如果位图中的第一个字节是0x1F,这个字节代表两个像素。第一个像素包含了颜色表中第二种颜色,第二个像素包含了颜色表中第十六种颜色。l 位图最多有256种颜色,bmiColors成员包含了多达256个入口。在这种情况下,数组中的每个字节代表一个像素。

我来回复

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