AFX_MANAGE_STATE(AfxGetStaticModuleState())DLL导出函数包含MFC资源
AFX_MANAGE_STATE(AfxGetStaticModuleState()) 先看一个例子: 、创建一个动态链接到MFC DLL的规则DLL,其内部包含一个对话框资源。指定该对话框ID如下:
#define IDD_DLL_DIALOG 2000 、创建一个基于对话框的mfc应用程序,它包含两个对话框资源,IDD_UI_DIALOG和IDD_EXE_DIALOG。并将后者的ID指定如下:
#define IDD_EXE_DIALOG 2000
其中前者是这个应用程序的用户界面,单击上面的按钮,将弹出一个对话框。部分代码如下:
// in DLL
void CDLL::ShowDlg(void)
{
CDialog dlg(IDD_DLL_DIALOG); //打开ID为2000的对话框
dlg.DoModal();
}
// in EXE
void CEXE::OnButtonClick()
{
ShowDlg();
} 、单击按钮,弹出的不是期望的DLL中的对话框IDD_DLL_DIALOG,而是应用程序中的对话框IDD_EXE_DIALOG。 解释: 、应用程序进程本身及其调用的每个DLL模块都具有一个全局唯一的HINSTANCE句柄,它们代表了EXE或DLL模块在进程虚拟空间中的起始地址。(进程本身的模块句柄一般为0x400000,而DLL模块的缺省句柄为0x10000000。如果程序同时加载了多个DLL,则每个DLL模块都会有不同的HINSTANCE。应用程序在加载DLL时对其进行了重定位)。
、共享MFC DLL(或MFC扩展DLL)的规则DLL涉及到HINSTANCE句柄问题,HINSTANCE句柄对于加载资源特别重要。EXE和DLL都有其自己的资源,而且这些资源的ID可能重复,如果应用程序与规则DLL共享MFC DLL(或MFC扩展DLL),那么将总是默认使用EXE的资源。
、因此应用程序需要通过资源模块的切换来找到正确的资源。如果应用程序需要来自于DLL的资源,就应将资源模块句柄指定为DLL的模块句柄;如果需要EXE文件中包含的资源,就应将资源模块句柄指定为EXE的模块句柄。 解决办法: 、在DLL中改进: 方法1。 // in DLL
void CDLL::ShowDlg(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CDialog dlg(IDD_DLL_DIALOG); //打开ID为2000的对话框
dlg.DoModal();
} 注:AFX_MANAGE_STATE(AfxGetStaticModuleState());一定是作为接口函数的第一条语句。
其功能是在栈上(这意味着其作用域是局部的)创建一个AFX_MODULE_STATE类的实例,并将其指 针pModuleState返回。
AFX_MODULE_STATE类利用其构造函数和析构函数进行存储模块状态现场及恢复现场的工作。
该宏用于将pModuleState设置为当前的有效模块状态。当离开该宏的作用域时(也就离开了pModuleState所指栈上对象的作用域),先前的模块状态将由类AFX_MODULE_STATE的析构函数恢复。(即自动恢复) 方法2。 // in DLL
void CDLL::ShowDlg(void)
{
HINSTANCE save_hInstance = AfxGetResourceHandle();
AfxSetResourceHandle(theApp.m_hInstance);
CDialog dlg(IDD_DLL_DIALOG); //打开ID为2000的对话框
dlg.DoModal();
AfxSetResourceHandle(save_hInstance);
} 注:AfxGetResourceHandle:获取当前资源模块句柄;AfxSetResourceHandle:设置程序目前要使用的资源模块句柄。
同方法1比较,方法2能够灵活地设置程序的资源模块句柄,而方法1则只能在DLL接口函数退出的时候才会恢复模块句柄。 、在应用程序中改进: // in EXE
void CEXE::OnButtonClick()
{
HINSTANCE exe_hInstance = GetModuleHandle(NULL);
HINSTANCE dll_hInstance = GetModuleHandle("SharedDll.dll");
AfxSetResourceHandle(dll_hInstance); //切换状态
ShowDlg();
AfxSetResourceHandle(exe_hInstance); //恢复状态
} 注:使用状态切换的情况:当DLL导出函数包含MFC资源、类或者需要创建窗口时。
AFX_MANAGE_STATE(AfxGetStaticModuleState())DLL导出函数包含MFC资源的更多相关文章
- C# 遍历DLL导出函数
C#如何去遍历一个由C++或E语言编写的本地DLL导出函数呢 不过在这里我建议对PE一无所知的人 你或许应先补补这方面的知识,我不知道为什么PE方面的 应用在C#中怎么这么少,我查阅过相关 C#的知识 ...
- dll导出函数的两种方式的比较
最初的网页链接已经挂了, 在此贴一个中间的转载链接 https://blog.csdn.net/zhazhiqiang/article/details/51577523 一 概要 vs中导出 dll的 ...
- DLL导出函数
使用DEF文件从DLL导出 模块定义(.def)文件时包含一个或多个描述DLL各种属性的Module语句的文本文件.如果不使用_declspec(dllexport)关键字导出DLL的函数,则DLL需 ...
- DLL导出函数和类的定义区别 __declspec(dllexport)
DLL导出函数和类的定义区别 __declspec(dllexport) 是有区别的, 请看 : //定义头文件的使用方,是导出还是导入 #if defined(_DLL_API) #ifndef D ...
- dll 导出函数名的那些事
dll 导出函数名的那些事 关键字: VC++ DLL 导出函数 经常使用VC6的Dependency或者是Depends工具查看DLL导出函数的名字,会发现有DLL导出函数的名字有时大不相同,导 ...
- 动态链接库DLL导出函数并导入使用
动态链接库DLL导出函数并导入使用 本文完全参考自<vs2008制作dll笔记,回带值样例>. 首先制作DLL文件,在vs2010中新建Win32控制台项目,选择DLL选项,简历头文件,源 ...
- Dll 导出函数那些破事
经常使用VC6的Dependency查看DLL导出函数的名字,会发现有DLL导出函数的名字有时大不相同,导致不同的原因大多是和编译DLL时候指定DLL导出函数的界定符有关系. VC++支持两种语言:即 ...
- 使用dumpbin命令查看dll导出函数及重定向输出到文件【轉】
查看dll导出函数,一般使用Viewdll等第三方工具. VS开发环境中,可以查看32位和64位的dll.具体使用方法如下: 1. 进入VS开发环境,然后Tools -> Visual stud ...
- 使用dumpbin命令查看dll导出函数及重定向输出到文件(VS自带)
以前查看dll导出函数,一般使用Viewdll等第三方工具.但由于Viewdll采用dephi编写,因此仅能查看32位的dll.其实微软已经帮我们提供一个查看dll导出函数的命令,嵌在VS开发环境中, ...
随机推荐
- Java开发高薪之路__大纲篇
本人小白,现对java开发做出以下总结,内容将从初级开始,逐步完善与摸索. 基础篇 网页篇 Android篇 高级建设篇 数据篇 系统篇
- 利用react来制作评论框
学习地址:https://my.oschina.net/leogao0816/blog/379488
- 修改内联CSS(点击按钮连续改变文字大小、位置,.animate()方法)
$(document).ready(function(){ $('#swticher-large').click(function(){ var $ ...
- 转Global.asax文件
Global.asax 文件是什么 Global.asax 文件,有时候叫做 ASP.NET 应用程序文件,提供了一种在一个中心位置响应应用程序级或模块级事件的方法.你可以使用这个文件实现应用程序 ...
- 51nod 1264 线段相交(几何)
题目链接:51nod 1264 线段相交 如果两条线段相交,则需满足一条线段的一个端点在另一条线段上,或者 两条线段都分别跨越另一条线段延伸的直线上.(如果点p1位于直线p3p4的一边,而点p2位于该 ...
- gitd模式-主从备份恢复
主从节点分配: 192.168.1.100 master binlog server读取节点 192.168.1.101 slave 备份节点 备注:binlog server从master节点备份b ...
- CodeForces #100 C 贪心+STL
题目链接:CodeForces #100 C 题意:现在给出n个snowball的半径,3个半径严格递增或递减的snowball,可以组成1个snowmen.问最多能组成多少个snowmen.并且按 ...
- iOS开发网络篇—文件的上传
iOS开发网络篇—文件的上传 说明:文件上传使用的时POST请求,通常把要上传的数据保存在请求体中.本文介绍如何不借助第三方框架实现iOS开发中得文件上传. 由于过程较为复杂,因此本文只贴出部分关键代 ...
- [强连通分量] POJ 2762 Going from u to v or from v to u?
Going from u to v or from v to u? Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 17089 ...
- PHP 面向对象编程
面向对象——类: 创建一个类: //创建了一个没有内容的Person(人)类 class Person{ } //通过new关键字来 实例化一个类 $teacher = new Person; //t ...