WEB开发网
开发学院软件开发VC 在DLL中使用资源 阅读

在DLL中使用资源

 2009-10-06 20:29:53 来源:WEB开发网   
核心提示:编译并运行Use.exe,点击按钮,在DLL中使用资源(4),这次你看到了什么?对,没错,点击按钮,可以看到弹出的时我们在DLL中所加入的那个对话框,这次弹出的是Use.exe的关于对话框,将上述例子的DLL类型换成MFC Extension DLL(using shared MFC DLL)也会出现相同的问题

编译并运行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的关于对话框了。

上一页  1 2 3 4 5  下一页

Tags:DLL 使用 资源

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接