| 网站首页 | JAVA文章 | AppServers | Web开发 | 应用开发 | 资源下载 | 论坛
    想学好编程,学好外语很重要  [enadd  2006年12月25日]        
设为首页 加入收藏 联系站长
您现在的位置: 编程笔记网 >> 应用开发 >> vc >> 组件 >> 文章正文
在DLL中使用资源(二)        【字体:
在DLL中使用资源(二)
作者:-    文章来源:-    点击数:    更新时间:2006-4-20

2、动态链接到MFC的DLL

    在讨论关于动态链接到MFC的DLL的模块状态问题之前,先来看一个例子。本例可以通过如下步骤来完成:



1)在VC菜单中File->New新建一个命名为DLLShared的MFC AppWizard的工程,下一步选择Regular DLL using shared MFC DLL。



2)在工程中添加一个对话框资源,其ID为:IDD_ABOUTBOX。并在resource.h之中将IDD_ABOUTBOX 的数值改为100。



3)在DLLShared.cpp中定义如下函数:



void ShowDlg()

{

    CDialog dlg(IDD_ABOUTBOX);

    dlg.DoModal();

}



4)在DLLShared.def文件中的EXPORTS语句中添加一行:ShowDlg,以导出ShowDlg函数。



5)编译生成DLLShared.dll和DLLShared.lib。



继续使用上面的Use工程,将前面生成的DLLShared.dll和DLLShared.lib两个文件复制到工程的Debug目录内,并将



extern "C" __declspec(dllexport) void ShowDlg();

#pragma comment(lib,"debug/DLLStatic")



这两行改为:



void ShowDlg();

#pragma comment(lib,"debug/DLLShared")



编译并运行Use.exe。点击按钮,这次你看到了什么?对,没错,这次弹出的是Use.exe的关于对话框。将上述例子的DLL类型换成MFC Extension DLL(using shared MFC DLL)也会出现相同的问题。



为什么会出现上面的问题?这是因为在使用了MFC共享库的时候,默认情况下,MFC使用主应用程序的资源句柄来加载资源模板。虽然我们调用的是DLL中的函数来显示DLL中的对话框,并且对应的对话框模板是存储在DLL中的,但MFC仍旧在主应用程序也就是Use.exe中寻找相应的对话框模板。由于在DLL中所定义的对话框资源ID与主应用程序中所定义的关于对话框的资源ID相同,所以MFC就把主应用程序中的关于对话框显示了出来。如果二者不同,则MFC就认为DLL中所定义的对话框资源不存在,dlg.DoModal会返回0,也就是什么都不会显示。



那么如何解决上述问题呢?解决办法就是在适当的时候进行模块状态切换,以保证具有当前状态的模块是我们所需要的模块从而使用正确的资源。MFC提供了下列函数和宏来完成这些工作:



AfxGetStaticModuleState:这是一个函数,其函数原型为:



AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState( );



此函数在堆栈上构造AFX_MODULE_STATE类的实例pModuleState并对其赋值后将其返回。在AFX_MODULE_STATE类的构造函数中,该类获取指向当前模块状态的指针并将其存储在成员变量中,然后将pModuleState设置为新的有效模块状态。在它的析构函数中,该类将存储在其成员变量中的指针还原为存贮的前一个模块状态。



AFX_MANAGE_STATE:这是一个宏,其原型为:



AFX_MANAGE_STATE( AFX_MODULE_STATE* pModuleState )



该宏用于将pModuleState(指向包含模块全局数据也就是模块状态的AFX_MODULE_STATE结构的指针)设置为当前的即时作用空间中(the remainder of the immediate containing scope)的有效模块状态。在离开包含该宏的作用空间时,前一个有效的模块状态自动还原。



AfxGetResourceHandle:这个函数的原型为:



    HINSTANCE AfxGetResourceHandle( );



    该函数返回了一个保存了HINSTANCE类型的、应用程序默认所加载资源的模块的句柄。



AfxSetResourceHandle:这个函数的原型为:



void AfxSetResourceHandle( HINSTANCE hInstResource );



该函数将hInstResource所代表的模块设置为具有当前状态的模块。



通过使用上述四个函数或宏就可以正确的在动态链接到MFC的DLL中切换模块状态。接下来我们将通过修改上面出现问题的那个例子来介绍如何使用上述四个函数或宏。先来看看Regular DLL using shared MFC DLL类型:



在上述例子的第三步的ShowDlg函数的第一条语句前加上如下语句(要确保该语句在函数实现的第一行):



AFX_MANAGE_STATE(AfxGetStaticModuleState());



之后重新编译生成DLLShared.dll和DLLShared.lib,并将这两个文件重新拷贝到Use工程的Debug目录内。这次编译生成Use.exe并运行,点击按钮,可以看到弹出的时我们在DLL中所加入的那个对话框,而不再是Use.exe的关于对话框了。



通过上面的讲解,相信你已经知道该语句的作用了。在函数ShowDlg的第一行加上这么一句后,每次调用DLL的应用程序使用该函数的时候,MFC库都会自动切换当前模块状态,这样就保证了资源读取的正确性。



AFX_MANAGE_STATE(AfxGetStaticModuleState());是自动切换当前模块状态,也可以通过使用AfxGetResourceHandle和AfxSetResourceHandle来手动切换当前模块状态。具体使用方法如下:



在上述例子的第三步的ShowDlg函数的第一条语句前加上如下语句(要确保该语句在函数实现的第一行):



HINSTANCE save_hInstance = AfxGetResourceHandle();

    AfxSetResourceHandle(theApp.m_hInstance);

[1] [2] [3] 下一页  

文章录入:enadd    责任编辑:enadd 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
  • MFC DLL向导(一)

  • 在DLL中使用资源(一)

  • 用自删除dll实现应用程序的安…

  • 例程详析动态链接库

  • 如何编写控制面板程序

  • MFC DLL向导(二)

  • 在MFC扩展DLL中输出对话框

  • 在存储过程中调用外部的动态…

  • BCB 编写 DLL 终极手册

  •   网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 管理登录 |