怎么同时使用 程序和动态库 中的资源? 一个对话框工程,其中用到了一个动态库,动态库中也有资源,即是说工程中的资源和动态库中都包含有要使用的资源,那么,如何做呢? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 用AfxSetResourceHandle(HINSTANCE hInstResourec);来定位资源的位置就可以了 只要资源的ID号不同就行------------------------这个做起来比较难啊,但还是一个可行的办法吧能不能在代码中把两个资源给合并起来,如果它们的ID一样的话,能够自动改变也好了:)用AfxSetResourceHandle(HINSTANCE hInstResourec);来定位资源的位置就可以了--------------------------------------------------这个不行的,等到动态库中的资源通用时,工程中的资源肯定不能用了 AfxSetResourceHandle(HINSTANCE hInstResourec);在需要用到具体的资源时传递相应的hInstance,只调用一次当然是不行的。 hHandle=LoadLibrary(...);LoadString(hHandle,...);//动态库资源LoadString(NULL, ...));//本程序资源 loadresource一类resource等着你来用呢。用msdn查查看把 方法一 在DLL接口函数中使用:CODE:AFX_MANAGE_STATE(AfxGetStaticModuleState()); [Copy to clipboard] 我们将DLL中的接口函数ShowDlg改为:CODE:void ShowDlg(void){ //方法1:在函数开始处变更,在函数结束时恢复 //将AFX_MANAGE_STATE(AfxGetStaticModuleState());作为接口函数的第一//条语句进行模块状态切换 AFX_MANAGE_STATE(AfxGetStaticModuleState()); CDialog dlg(IDD_DLL_DIALOG);//打开ID为2000的对话框 dlg.DoModal();} [Copy to clipboard] 这次我们再点击EXE程序中的“调用DLL”按钮,弹出的是DLL中的如图13的对话框!嘿嘿,弹出了正确的对话框资源。 AfxGetStaticModuleState是一个函数,其原型为:CODE:AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState( ); [Copy to clipboard] 该函数的功能是在栈上(这意味着其作用域是局部的)创建一个AFX_MODULE_STATE类(模块全局数据也就是模块状态)的实例,对其进行设置,并将其指针pModuleState返回。 AFX_MODULE_STATE类的原型如下:CODE:// AFX_MODULE_STATE (global data for a module)class AFX_MODULE_STATE : public CNoTrackObject{ public: #ifdef _AFXDLL AFX_MODULE_STATE(BOOL bDLL, WNDPROC pfnAfxWndProc, DWORD dwVersion); AFX_MODULE_STATE(BOOL bDLL, WNDPROC pfnAfxWndProc, DWORD dwVersion,BOOL bSystem); #else AFX_MODULE_STATE(BOOL bDLL); #endif ~AFX_MODULE_STATE(); CWinApp* m_pCurrentWinApp; HINSTANCE m_hCurrentInstanceHandle; HINSTANCE m_hCurrentResourceHandle; LPCTSTR m_lpszCurrentAppName; … //省略后面的部分} [Copy to clipboard] AFX_MODULE_STATE类利用其构造函数和析构函数进行存储模块状态现场及恢复现场的工作,类似汇编中call指令对pc指针和sp寄存器的保存与恢复、中断服务程序的中断现场压栈与恢复以及操作系统线程调度的任务控制块保存与恢复。 许多看似不着边际的知识点居然有惊人的相似! AFX_MANAGE_STATE是一个宏,其原型为: CODE:AFX_MANAGE_STATE( AFX_MODULE_STATE* pModuleState ) [Copy to clipboard] 该宏用于将pModuleState设置为当前的有效模块状态。当离开该宏的作用域时(也就离开了pModuleState所指向栈上对象的作用域),先前的模块状态将由AFX_MODULE_STATE的析构函数恢复。 方法二 在DLL接口函数中使用:CODE:AfxGetResourceHandle();AfxSetResourceHandle(HINSTANCE xxx); [Copy to clipboard] AfxGetResourceHandle用于获取当前资源模块句柄,而AfxSetResourceHandle则用于设置程序目前要使用的资源模块句柄。 我们将DLL中的接口函数ShowDlg改为:CODE:void ShowDlg(void){ //方法2的状态变更 HINSTANCE save_hInstance = AfxGetResourceHandle(); AfxSetResourceHandle(theApp.m_hInstance); CDialog dlg(IDD_DLL_DIALOG);//打开ID为2000的对话框 dlg.DoModal(); //方法2的状态还原 AfxSetResourceHandle(save_hInstance);} [Copy to clipboard] 通过AfxGetResourceHandle和AfxSetResourceHandle的合理变更,我们能够灵活地设置程序的资源模块句柄,而方法一则只能在DLL接口函数退出的时候才会恢复模块句柄。方法二则不同,如果将ShowDlg改为:CODE:extern CSharedDllApp theApp; //需要声明theApp外部全局变量void ShowDlg(void){ //方法2的状态变更 HINSTANCE save_hInstance = AfxGetResourceHandle(); AfxSetResourceHandle(theApp.m_hInstance); CDialog dlg(IDD_DLL_DIALOG);//打开ID为2000的对话框 dlg.DoModal(); //方法2的状态还原 AfxSetResourceHandle(save_hInstance); //使用方法2后在此处再进行操作针对的将是应用程序的资源 CDialog dlg1(IDD_DLL_DIALOG); //打开ID为2000的对话框 dlg1.DoModal();} [Copy to clipboard] 在应用程序主对话框的“调用DLL”按钮上点击,将看到两个对话框,相继为DLL中的对话框(图13)和EXE中的对话框(图14)。 方法三 由应用程序自身切换 资源模块的切换除了可以由DLL接口函数完成以外,由应用程序自身也能完成(下载本工程)。 现在我们把DLL中的接口函数改为最简单的:CODE:void ShowDlg(void){ CDialog dlg(IDD_DLL_DIALOG); //打开ID为2000的对话框 dlg.DoModal();} [Copy to clipboard] 而将应用程序的OnCalldllButton函数改为:CODE:void CSharedDllCallDlg::OnCalldllButton() { //方法3:由应用程序本身进行状态切换 //获取EXE模块句柄 HINSTANCE exe_hInstance = GetModuleHandle(NULL); //或者HINSTANCE exe_hInstance = AfxGetResourceHandle(); //获取DLL模块句柄 HINSTANCE dll_hInstance = GetModuleHandle("SharedDll.dll"); AfxSetResourceHandle(dll_hInstance); //切换状态 ShowDlg(); //此时显示的是DLL的对话框 AfxSetResourceHandle(exe_hInstance); //恢复状态 //资源模块恢复后再调用ShowDlg ShowDlg(); //此时显示的是EXE的对话框} [Copy to clipboard] 方法三中的Win32函数GetModuleHandle可以根据DLL的文件名获取DLL的模块句柄。如果需要得到EXE模块的句柄,则应调用带有Null参数的GetModuleHandle。 好久没来,散分贴(三) 工具栏 状态栏 在 对话框 伸缩 如何识别出图像中的多个相同结构 如何在EDIT中設置字體的屬性,比如顏色 请教各位大侠,在OnCreate中创建StatusBar后,如何动态修改状态的分栏数啊?如何由5个分栏变成4个? 急!在线等待!请问高手,如何通过代码得到文本输入框中选中的文字? 为什么我往list中增加记录,看不见了 怎么实现在一台拔号上网的电脑上向一个ADSL内部网的一台工作站发送数据? dll注入时,引起 afxwin1.inl 22 错误 CList存和取对象不一致的问题 急!!!我现在所有的程序都不好用了,谁知道是怎么回事! 我违犯CSDN规则了?
AfxSetResourceHandle(HINSTANCE hInstResourec);
来定位资源的位置就可以了
------------------------
这个做起来比较难啊,但还是一个可行的办法吧
能不能在代码中把两个资源给合并起来,如果它们的ID一样的话,能够自动改变也好了:)用
AfxSetResourceHandle(HINSTANCE hInstResourec);
来定位资源的位置就可以了
--------------------------------------------------
这个不行的,等到动态库中的资源通用时,工程中的资源肯定不能用了
在需要用到具体的资源时传递相应的hInstance,只调用一次当然是不行的。
LoadString(hHandle,...);//动态库资源
LoadString(NULL, ...));//本程序资源
用msdn查查看把
{
//方法1:在函数开始处变更,在函数结束时恢复
//将AFX_MANAGE_STATE(AfxGetStaticModuleState());作为接口函数的第一//条语句进行模块状态切换 AFX_MANAGE_STATE(AfxGetStaticModuleState());
CDialog dlg(IDD_DLL_DIALOG);//打开ID为2000的对话框
dlg.DoModal();
}
[Copy to clipboard]
这次我们再点击EXE程序中的“调用DLL”按钮,弹出的是DLL中的如图13的对话框!嘿嘿,弹出了正确的对话框资源。 AfxGetStaticModuleState是一个函数,其原型为:CODE:AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState( );
[Copy to clipboard]
该函数的功能是在栈上(这意味着其作用域是局部的)创建一个AFX_MODULE_STATE类(模块全局数据也就是模块状态)的实例,对其进行设置,并将其指针pModuleState返回。 AFX_MODULE_STATE类的原型如下:CODE:// AFX_MODULE_STATE (global data for a module)class AFX_MODULE_STATE : public CNoTrackObject
{
public:
#ifdef _AFXDLL
AFX_MODULE_STATE(BOOL bDLL, WNDPROC pfnAfxWndProc, DWORD dwVersion);
AFX_MODULE_STATE(BOOL bDLL, WNDPROC pfnAfxWndProc, DWORD dwVersion,BOOL bSystem);
#else
AFX_MODULE_STATE(BOOL bDLL);
#endif
~AFX_MODULE_STATE(); CWinApp* m_pCurrentWinApp;
HINSTANCE m_hCurrentInstanceHandle;
HINSTANCE m_hCurrentResourceHandle;
LPCTSTR m_lpszCurrentAppName; … //省略后面的部分
}
[Copy to clipboard]
AFX_MODULE_STATE类利用其构造函数和析构函数进行存储模块状态现场及恢复现场的工作,类似汇编中call指令对pc指针和sp寄存器的保存与恢复、中断服务程序的中断现场压栈与恢复以及操作系统线程调度的任务控制块保存与恢复。 许多看似不着边际的知识点居然有惊人的相似! AFX_MANAGE_STATE是一个宏,其原型为: CODE:AFX_MANAGE_STATE( AFX_MODULE_STATE* pModuleState )
[Copy to clipboard]
该宏用于将pModuleState设置为当前的有效模块状态。当离开该宏的作用域时(也就离开了pModuleState所指向栈上对象的作用域),先前的模块状态将由AFX_MODULE_STATE的析构函数恢复。 方法二 在DLL接口函数中使用:CODE:AfxGetResourceHandle();AfxSetResourceHandle(HINSTANCE xxx);
[Copy to clipboard]
AfxGetResourceHandle用于获取当前资源模块句柄,而AfxSetResourceHandle则用于设置程序目前要使用的资源模块句柄。 我们将DLL中的接口函数ShowDlg改为:CODE:void ShowDlg(void)
{
//方法2的状态变更
HINSTANCE save_hInstance = AfxGetResourceHandle();
AfxSetResourceHandle(theApp.m_hInstance);
CDialog dlg(IDD_DLL_DIALOG);//打开ID为2000的对话框
dlg.DoModal(); //方法2的状态还原
AfxSetResourceHandle(save_hInstance);
}
[Copy to clipboard]
通过AfxGetResourceHandle和AfxSetResourceHandle的合理变更,我们能够灵活地设置程序的资源模块句柄,而方法一则只能在DLL接口函数退出的时候才会恢复模块句柄。方法二则不同,如果将ShowDlg改为:CODE:extern CSharedDllApp theApp; //需要声明theApp外部全局变量void ShowDlg(void)
{
//方法2的状态变更
HINSTANCE save_hInstance = AfxGetResourceHandle();
AfxSetResourceHandle(theApp.m_hInstance); CDialog dlg(IDD_DLL_DIALOG);//打开ID为2000的对话框
dlg.DoModal(); //方法2的状态还原 AfxSetResourceHandle(save_hInstance); //使用方法2后在此处再进行操作针对的将是应用程序的资源 CDialog dlg1(IDD_DLL_DIALOG); //打开ID为2000的对话框
dlg1.DoModal();
}
[Copy to clipboard]
在应用程序主对话框的“调用DLL”按钮上点击,将看到两个对话框,相继为DLL中的对话框(图13)和EXE中的对话框(图14)。 方法三 由应用程序自身切换 资源模块的切换除了可以由DLL接口函数完成以外,由应用程序自身也能完成(下载本工程)。 现在我们把DLL中的接口函数改为最简单的:CODE:void ShowDlg(void)
{
CDialog dlg(IDD_DLL_DIALOG); //打开ID为2000的对话框
dlg.DoModal();
}
[Copy to clipboard]
而将应用程序的OnCalldllButton函数改为:CODE:void CSharedDllCallDlg::OnCalldllButton()
{
//方法3:由应用程序本身进行状态切换
//获取EXE模块句柄 HINSTANCE exe_hInstance = GetModuleHandle(NULL); //或者HINSTANCE exe_hInstance = AfxGetResourceHandle();
//获取DLL模块句柄 HINSTANCE dll_hInstance = GetModuleHandle("SharedDll.dll");
AfxSetResourceHandle(dll_hInstance); //切换状态
ShowDlg(); //此时显示的是DLL的对话框
AfxSetResourceHandle(exe_hInstance); //恢复状态 //资源模块恢复后再调用ShowDlg
ShowDlg(); //此时显示的是EXE的对话框
}
[Copy to clipboard]
方法三中的Win32函数GetModuleHandle可以根据DLL的文件名获取DLL的模块句柄。如果需要得到EXE模块的句柄,则应调用带有Null参数的GetModuleHandle。