DLL资源模块状态切换

先看一个例子

1、创建一个动态链接到MFC DLL的规则DLL,其内部包含一个对话框资源。指定该对话框ID如下:
              #define IDD_DLL_DIALOG 2000

2、创建一个基于对话框的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();
}

3、单击按钮,弹出的不是期望的DLL中的对话框IDD_DLL_DIALOG,而是应用程序中的对话框IDD_EXE_DIALOG。

解释

1、应用程序进程本身及其调用的每个DLL模块都具有一个全局唯一的HINSTANCE句柄,它们代表了EXE或DLL模块在进程虚拟空间中的起始地址。(进程本身的模块句柄一般为0x400000,而DLL模块的缺省句柄为0x10000000。如果程序同时加载了多个DLL,则每个DLL模块都会有不同的HINSTANCE。应用程序在加载DLL时对其进行了重定位)。 
2、共享MFC DLL(或MFC扩展DLL)的规则DLL涉及到HINSTANCE句柄问题,HINSTANCE句柄对于加载资源特别重要。EXE和DLL都有其自己的资源,而且这些资源的ID可能重复,如果应用程序与规则DLL共享MFC DLL(或MFC扩展DLL),那么将总是默认使用EXE的资源。
3、因此应用程序需要通过资源模块的切换来找到正确的资源。如果应用程序需要来自于DLL的资源,就应将资源模块句柄指定为DLL的模块句柄;如果需要EXE文件中包含的资源,就应将资源模块句柄指定为EXE的模块句柄。

解决办法

1、在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接口函数退出的时候才会恢复模块句柄。

2、在应用程序中改进:

// 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资源、类或者需要创建窗口时。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MFC(Microsoft Foundation Class)是一种开发Windows桌面应用程序的框架,可以使用动态链接库(DLL)来实现中英文切换。 首先,我们需要创建一个DLL项目,并在其中添加资源文件,包括不同语言的字符串和对应的ID。比如,可以创建两个资源文件,一个是英文字符串,另一个是中文字符串,分别命名为en-US.res和zh-CN.res。 然后,在MFC应用程序中使用LoadLibrary函数加载DLL,并调用FindResource和LoadResource函数加载对应语言的资源。可以通过设置不同的语言标识符参数来选择加载不同的资源。例如,对于英文资源,可以使用以下代码: HMODULE hModule = LoadLibrary(_T("dll路径")); HRSRC hResource = FindResource(hModule, MAKEINTRESOURCE(IDR_ENGLISH), RT_RCDATA); HGLOBAL hMemory = LoadResource(hModule, hResource); LPVOID lpResource = LockResource(hMemory); CString strEnglish((const char*)lpResource); FreeLibrary(hModule); 对于中文资源,只需将IDR_ENGLISH更改为IDR_CHINESE即可。 最后,使用CString或其他方法将获取的字符串显示在MFC应用程序的界面上,即可实现中英文切换。 需要注意的是,为了方便切换语言,在MFC应用程序中还需提供切换语言的选项或设置,通过相应的逻辑代码来实现切换时重新加载DLL并更新界面显示的字符串。 总结起来,借助MFC的特性和DLL的加载能力,我们可以在应用程序中通过加载不同的资源文件来实现中英文切换。 ### 回答2: 在MFC中使用DLL实现中英文切换,可以通过以下步骤进行: 第一步,创建一个DLL项目,用于存储中英文的字符串资源。可以在资源文件中添加对应的中英文字符串,并在代码中定义一个函数来获取这些字符串。 第二步,创建一个MFC应用程序项目。在应用程序的初始化过程中,加载DLL文件并获取所需要的字符串资源。可以使用LoadLibrary函数加载DLL文件,并使用GetProcAddress函数获取相应函数的地址。 第三步,创建一个语言选择界面,用于让用户选择要使用的语言。可以使用对话框或者菜单添加语言选项。用户选择语言后,将相应的语言标识保存在配置文件或注册表中。 第四步,根据用户选择的语言标识,动态修改应用程序中的字符串显示。可以通过调用DLL中的函数来获取对应的中英文字符串,然后将其显示在对应的界面控件上。 第五步,在应用程序的所有界面中添加语言切换的功能。可以在每个界面的菜单栏或功能栏上添加一个语言切换的按钮或选项,用户点击按钮或选择选项后,重新加载相应语言的字符串资源,并刷新界面中的所有文本。 通过以上步骤,就可以实现MFC应用程序的中英文切换功能。用户可以根据自己的需要选择合适的语言,并在应用程序中动态更改界面文字的显示。这样可以提供更好的用户体验,同时方便应对不同语言环境下的需求。 ### 回答3: 在MFC中实现中英文切换可以通过使用动态链接库(DLL)的方式来实现。首先,我们可以在资源文件中创建多语言版本的字符串资源,分别对应中文和英文。然后,将这些字符串资源保存到一个DLL文件中。 在MFC应用程序中,我们需要在主窗口初始化时加载这个DLL文件,以便在运行时可以动态切换语言。可以在InitInstance函数中使用LoadLibrary函数加载DLL文件,并使用AfxSetResourceHandle函数将资源句柄设置为DLL文件的句柄。 当需要切换语言时,我们可以通过调用AfxSetResourceHandle函数来重新设置资源句柄为DLL文件的句柄,然后强制重绘界面。这样就可以实现界面上的文本、标签等显示为不同的语言了。 另外,为了方便管理和切换语言,可以根据需求在应用程序中添加一个菜单或者工具栏,通过点击菜单项或者工具栏按钮在运行时切换语言。当用户通过菜单或者工具栏切换语言时,可以根据用户选择的语言,重新设置资源句柄为相应DLL文件的句柄,并强制重绘界面。 需要注意的是,在切换语言的过程中,我们需要注意重新加载语言资源,例如重新加载菜单资源、工具栏资源等,以便将其显示为对应的语言。 总的来说,通过使用DLL实现中英文切换可以让我们的应用程序更加灵活多语言化,提供更好的用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值