北京速实简石油科技开发有限公司
首页 公司简介 软件产品 应用案例 代理产品 留言板 联系我们
用精湛的技术提供100分的服务!
 

  从MFC扩展动态链接库中输出对话框似乎是很容易的.你仅需要将相应类用AFX_EXT_CLASS输出即可。如果你用一个应用程序和一个动态链接库建立或许会成功。但是如果你在应用程序和DLL中都插入更多的资源,你将会得到严重错误。
原因如下:

  表示一个指定资源的正常途径是用它的ID。ID是一个用资源编辑器定义的整型常量。现在,假定你已有一个资源(是字符串)命名为ID_MY_TEXT.

CString strText;
strText.LoadString( ID_MY_TEXT );
afxDump << strText;

  上述代码将字符串输出到调试窗口。有时你可能得到一个错误,而且它只发生在如果文本在一个MFC的扩展动态链接库里。错误的原因在于应用程序获取一个资源的途径。因为应用程序和动态链接库都有一个资源文件。不同的资源ID有可能一样(以为VC资源编辑器为每个模块确定ID的起始编号方式)。

  你可能认为在你的应用程序里搜索一个资源的顺序是首先为应用程序,而后为你的DLL。我们需要改变搜索资源的顺序。

  在本站有其他文章详细讲述了从DLL中输出对话框。但是它只能工作在正规的MFC动态链接库中。

  我写了一个类(在DLL的MAIN和对话框中有一些改变),允许你在任何你喜欢的地方调用你的对话框,就象:

CMyApp::OnDLLDialog()
{
CDLLDialog dlg;
dlg.DoModal();
}
  我写了一个简单的类,在类的构造函数中设置动态链接库的资源句柄,在析构函数中设置先前的句柄。

/////////////////////////////////////////////////////////////////////////////////////////////
// File ExtDllState.h
////////////////////////////////////////////////////////////////////////////////////////////
#ifndef __EXTDLLSTATE_H__
#define __EXTDLLSTATE_H__

class CEXTDLLState
{
public:
CEXTDLLState();
~CEXTDLLState();
protected:
HINSTANCE m_hInstOld;
};

#endif
////////////////////////////////////////////////////////////////////////////////////////////
File ExtDllState.cpp
////////////////////////////////////////////////////////////////////////////////////////////
CEXTDLLState::CEXTDLLState()
{
m_hInstOld = AfxGetResourceHandle();
AfxSetResourceHandle(extensionDLL.hModule);
}

CEXTDLLState::~CEXTDLLState()
{
AfxSetResourceHandle(m_hInstOld);
}
//////////////////////////////////////////////////////////////////////////////////////

  你可能看它很短小,但是却能做很多工作:复制上面的类代码到ExDllState.h和ExtDllState.cpp中,将两个文件放入公有的Include目录下,使得每个项目找到它。在你的DLL中,找到main源文件,你会看到类似下面的一些代码:

static AFX_EXTENSION_MODULE MY_DLL_NAMEDLL = { NULL, NULL };
用 "extensionDLL"替换该变量。放入下面的代码:

#include "EXTDLLState.h"
#include "ExtDllState.cpp"

  在文件的其他地方寻找MY_DLL_NAMEDLL的事件,用extensionDLL替换它。事件只能在这个文件里发生,以为该变量是静态的。

  现在,如果你想输出一个对话框,请进入COrresponding类的源文件里并包含EXTDLLState.h,重载函数DoModal()(最好使用ClassWizard),你将看到类似下面的代码:

int CMyDLLDlg::DoModal()
{
// TODO: Add your specialized code here and/or call the base class
return CDialog::DoModal();
}

用"CEXTDLLState State;"替换TODO行,就象下面:

int CDLLDlgDlg::DoModal()
{
CEXTDLLState State;
return CDialog::DoModal();
}

  你能在MFC扩展DLL中想存取资源的任何地方使用CEXTDLLState,而且总能得到正确的结果,我希望它能对你有所帮助。

 
北京速实简石油科技开发有限公司