Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1072426
  • 博文数量: 243
  • 博客积分: 3053
  • 博客等级: 中校
  • 技术积分: 2975
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-02 21:11
文章分类

全部博文(243)

文章存档

2013年(2)

2012年(20)

2011年(5)

2010年(114)

2009年(102)

我的朋友

分类:

2010-12-08 18:20:27

1.                      状态信息的作用

 

在分析了MFC模块状态的实现基础和管理机制之后,现在对状态信息的作用进行专门的讨论。

1模块信息的保存和管理

 

传统上,线程状态、模块状态等包含的信息是全局变量,但是为了支持Win32s、多线程、DLL等,这些变量必须是限于进程或者线程范围内有效,或者限于某个模块内有效。也就是,不再可能把它们作为全局变量处理。因此,MFC引入模块、线程、模块-线程状态等来保存和管理一些重要的信息。

例如:一个模块注册了一个“窗口类”之后,应用程序要保存“窗口类”的名字,以便在模块退出时取消注册的“窗口类”。因此,模块状态使用成员变量m_szUnregisterList在注册成功之后保存的“窗口类”名字。窗口注册见2.2.1节。

又如:Tooltip窗口是线程相关的,每个线程一个,所以线程状态用成员变量m_pToolTip来保存本线程的MFC Tooltip窗口对象。Tooltip窗口见13.2.4.4节。

还有,MFC对象是线程和模块相关的,所以模块线程中有一组变量用来管理本线程的MFC对象到Windows对象的映射关系。关于MFC对象和Windows对象的映射,见稍后的讨论。

模块状态、线程状态、模块线程状态的每个成员变量都有自己存在的必要和作用,这里就不一一论述了,在此,只是强调模块状态自动地实现对模块句柄和资源句柄等信息的保存和管理,这对MFC应用程序是非常重要的。

SDK 下的应用程序或者DLL,通常使用一个全局变量来保存模块/资源句柄。有了模块状态之后,程序员就不必这么作了。规则DLL或者应用程序的模块和资源句柄在调用DllMain或WinMain时被保存到了当前模块的模块状态中。如果是扩展DLL,则其句柄被保存到扩展模块状态中,并通过CDynLinkLibrary对象链接到主模块的模块状态。

图9-8示意了MFC模块状态对资源、CRuntimeClass对象、OLE工厂等模块信息的管理。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

图9-8的说明:

左边的主模块状态表示动态链接到MFC DLL的应用程序或者规则DLL的模块状态,其资源句柄和模块句柄用来查找和获取资源,资源句柄一般是应用程序的模块句柄;CRuntimeClass对象列表和COleObjectFactory对象列表分别表示该模块初始化了的CRuntimeClass对象和该模块的OLE工厂对象;CDynLinkLibrary列表包含了它引用的系列扩展DLL的扩展模块状态(包括核心MFC DLL的状态),链表中的每一个CDynLinkLibrary对象对应一个扩展模块状态,代表了创建该对象的扩展DLL的有关资源、信息。

MFC查找资源、CRuntimeClass类、OLE工厂时,首先查找模块状态,然后,遍历CDynLinkLibrary表搜索相应的对象。下面两节举例说明。

2        MFC资源、运行类信息的查找

 MFC内部使用的资源查找函数是:

HINSTANCE AfxFindResourceHandle(LPCTSTR lpszName, LPCTSTR lpszType):

其中:

参数1是要查找的资源名称,参数2是要查找的资源类型。

返回包含指定资源的模块的句柄。

上述函数的查找算法如下:

1)      如果进程模块状态(主模块)不是系统模块,则使用::FindResource(下同)搜索它,成功则返回;

 

2)      如果没有找到,则遍历CDynLinkLibrary对象列表,搜索所有的非系统模块,成功则返回;

  3) 如果没有找到,则检查主模块的语言资源,成功则返回;

4)      如果没有找到,并且主模块是系统模块,则搜索它,成功则返回;

5) 如果没有找到,则遍历CDynLinkLibrary对象列表,搜索所有的系统模块,成功则返回;

  6) 如果没有找到,则使用AfxGetResourceHanlde返回应用程序的资源。

 需要指出的是,遍历CDynLinkLibrary对象列表时,必须采取同步措施,防止其他线程改变链表。MFC是通过锁定全局变量CRIT_DYNLINKLIST来实现的,类似的全局变量MFC定义了多个。

运行时类信息的查找算法类似。

3.3.4节指出,对象进行“<<”序列化操作时,首先需要搜索到指定类的运行时信息,方法如下:

CRuntimeClass* PASCAL CRuntimeClass::Load(

CArchive& ar, UINT* pwSchemaNum)

1)      遍历主模块的CRuntimeClass对象列表m_classList,搜索主模块是否实现了指定的CRuntimeClass类;

2)      遍历CDynLinkLibrary对象列表m_libraryList;对每一个CDynLinkLibrary对象,遍历它的CRuntimeClass对象列表m_classList。这样,所有的扩展DLL模块的CRuntimeClass对象都会被搜索到。

阅读(1517) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~