runsisi's

technical notes

使用MFC规则DLL, DLL的资源问题

2018-12-20 runsisi#coding

网上关于 MFC 规则 DLL 的创建和使用的资料比较多,其实也就那两三篇转过来转过去:)
但是好像都只是用自己写的 MFC 主程序调用 MFC DLL,涉及到 DLL 的资源问题时都会提及三种解决方法:

  1. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  2. AfxGetResourceHandle(); AfxSetResourceHandle();
  3. 在主程序中使用方法 2;

如果是自己写的 MFC 主程序自然三种方法都可以,但是如果不是这种情况呢?

比如:

  1. 主程序是 SDK 写的,然后调用 MFC DLL
  2. 主程序根本就不是我们自己写的,MFC DLL 只是作为一个 HOOK DLL 注入主程序中
  3. 主程序是用其他 GUI 库写的

在这几种情况下上述的 2、3 两种方法是无法使用的,想想为什么? 只有方法 1 可行,当然我们也可以使用如下的方法:

_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
AFX_MODULE_STATE* pOldModState = pThreadState->m_pModuleState;
// Ur code here
pThreadState->m_pModuleState = pOldModState;

为什么使用 MFC DLL? 呵呵。 有的文章里有这样一段话: AFX_MANAGE_STATE(AfxGetStaticModuleState()); 的方法只能等函数的作用空间结束之后才恢复资源句柄。由于可执行文件必须重画工具条等原因,因此建议只要有可能就必须恢复资源句柄,否则可能会遇到许多问题。比如说,如果用户移动 DLL 的对话框,而此时资源句柄仍然为 DLL 的资源,那么程序就会崩溃。最好的恢复句柄的时机在对话框响应 WM_INITDIALOG 消息的时候,因为这时对话框的模板等已经读出了。

不知道这段话的结论是怎样得出来的,而所谓的恢复句柄的方法我也不知道他是怎么恢复的。实际测试的结果是根本不需要考虑这个,即使是单线程主程序,MFC DLL 在主程序的主线程内执行;如果 MFC DLL 是在单独的一个线程内执行,则更加不需要考虑这个问题;如果主程序是 SDK 程序则根本不需要考虑这个问题,因为 SDK 程序都是直接操作句柄的。

如果觉得有错那就使用我提供的另外一种方法,或者使用花括号吧,呵呵。