⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 在dll中使用资源(1).htm

📁 我在网上收集的一些有关vcDLL编程的文章。
💻 HTM
📖 第 1 页 / 共 2 页
字号:
  </span> <span lang=EN-US>switch(message) <br>
  <br>
  </span> <span lang=EN-US>{ <br>
  <br>
  </span> <span lang=EN-US> case WM_INITDIALOG: <br>
  <br>
  </span>   <span lang=EN-US> return TRUE; <br>
  <br>
  </span>   <span lang=EN-US> <br>
  <br>
  </span> <span lang=EN-US> case WM_COMMAND: <br>
  <br>
  </span>   <span lang=EN-US> if(LOWORD(wParam)==IDOK) <br>
  <br>
  DialogBox(hinst,MAKEINTRESOURCE(IDD_ABOUTBOX), <br>
  <br>
  hDlg,(DLGPROC)AboutProc); <br>
  <br>
  </span>   <span lang=EN-US> return TRUE;</span>  <span lang=EN-US> <br>
  <br>
  </span> <span lang=EN-US> case WM_CLOSE: <br>
  <br>
  </span>   <span lang=EN-US> DestroyWindow(hDlg); <br>
  <br>
  </span>   <span lang=EN-US> hwndDLG = NULL; <br>
  <br>
  </span>   <span lang=EN-US> return TRUE; <br>
  <br>
  </span> <span lang=EN-US>} <br>
  <br>
  </span> <span lang=EN-US>return FALSE; <br>
  <br>
  } <br>
  <br>
  <br>
  <br>
  BOOL CALLBACK AboutProc(HWND hDlg, UINT message, <br>
  <br>
  WPARAM wParam, LPARAM lParam) <br>
  <br>
  { <br>
  <br>
  </span> <span lang=EN-US> switch(message) <br>
  <br>
  </span> <span lang=EN-US>{ <br>
  <br>
  </span>   <span lang=EN-US> case WM_CLOSE: <br>
  <br>
  </span>     <span lang=EN-US> EndDialog(hDlg,NULL); <br>
  <br>
  </span>     <span lang=EN-US> hwndDLG = NULL; <br>
  <br>
  </span>     <span lang=EN-US> return TRUE; <br>
  <br>
  </span> <span lang=EN-US>} <br>
  <br>
  </span> <span lang=EN-US>return FALSE; <br>
  <br>
  } <br>
  <br>
  <br>
  <br>
  4</span>)编译生成<span lang=EN-US>UseDlg.dll</span>和<span lang=EN-US>UseDlg.lib</span>。<span
  lang=EN-US> <br>
  <br>
  <br>
  <br>
  </span>接下来我们建立调用此<span lang=EN-US>DLL</span>的应用程序,其步骤如下:<span lang=EN-US> <br>
  <br>
  <br>
  <br>
  1</span>)在<span lang=EN-US>VC</span>菜单中<span lang=EN-US>File-&gt;New</span>新建一个命名为<span
  lang=EN-US>Use</span>的<span lang=EN-US>MFC AppWizard(exe)</span>工程,下一步选择<span
  lang=EN-US>Dialog Based</span>之后点击<span lang=EN-US>Finish</span>按钮。<span
  lang=EN-US> <br>
  <br>
  <br>
  <br>
  2</span>)在主对话框上面添加一个按钮,之后双击此按钮,会弹出<span lang=EN-US>Add Member Function</span>的对话框,直接点击<span
  lang=EN-US>OK</span>进入<span lang=EN-US>void CUseDlg::OnButton1()</span>函数。并在此函数内添加一个函数调用:<span
  lang=EN-US>ShowDlg();</span>。<span lang=EN-US> <br>
  <br>
  <br>
  <br>
  3</span>)紧跟在<span lang=EN-US>#include</span>语句后面加上如下代码:<span lang=EN-US> <br>
  <br>
  <br>
  <br>
  extern &quot;C&quot; __declspec(dllexport) void ShowDlg(); <br>
  <br>
  #pragma comment(lib,&quot;debug/UseDlg&quot;) <br>
  <br>
  <br>
  <br>
  4</span>)将上面<span lang=EN-US>UseDlg</span>工程中生成的<span lang=EN-US>UseDlg.dll</span>和<span
  lang=EN-US>UseDlg.lib</span>两个文件复制到<span lang=EN-US>Use</span>工程的<span
  lang=EN-US>Debug</span>目录内。<span lang=EN-US> <br>
  <br>
  <br>
  <br>
  5</span>)编译生成<span lang=EN-US>Use.exe</span>。<span lang=EN-US> <br>
  <br>
  <br>
  <br>
  </span>  运行<span lang=EN-US>Use.exe</span>,点击<span lang=EN-US>Button1</span>按钮,可以看到一个名称为<span
  lang=EN-US>Dialog</span>的非模态对话框弹出。点击上面的按钮,可以弹出模态对话框<span lang=EN-US>About</span>。运行成功。<span
  lang=EN-US> <br>
  <br>
  <br>
  <br>
  </span>  让我们来回顾一下在<span lang=EN-US>Win32 DLL</span>中使用对话框的过程。<span
  lang=EN-US> <br>
  <br>
  <br>
  <br>
  </span>在<span lang=EN-US>DLL</span>中,我们定义了两个对话框资源:<span lang=EN-US>IDD_DLG_SHOW</span>和<span
  lang=EN-US>IDD_ABOUTBOX</span>,并且导出了函数<span lang=EN-US>ShowDlg</span>。在函数<span
  lang=EN-US>ShowDlg</span>之中使用<span lang=EN-US>CreateDialog</span>函数创建了非模态对话框<span
  lang=EN-US>IDD_DLG_SHOW</span>,并指定了该对话框的回调函数<span lang=EN-US>DlgProc</span>。在<span
  lang=EN-US>DlgProc</span>之中处理了<span lang=EN-US>WM_INITDIALOG</span>、<span
  lang=EN-US>WM_COMMAND</span>和<span lang=EN-US>WM_CLOSE</span>消息,以响应用户对对话框所做的动作。在处理按钮动作的时候,使用<span
  lang=EN-US>DialogBox</span>函数创建<span lang=EN-US>IDD_ABOUTBOX</span>这个模态对话框,指定其回调函数为<span
  lang=EN-US>AboutProc</span>,并且在<span lang=EN-US>AboutProc</span>中处理其相应消息。<span
  lang=EN-US> <br>
  <br>
  <br>
  <br>
  </span>在<span lang=EN-US>EXE</span>中,我们使用隐式链接的方法来调用<span lang=EN-US>DLL</span>,并使用<span
  lang=EN-US>DLL</span>中导出的<span lang=EN-US>ShowDlg</span>函数来调用<span
  lang=EN-US>DLL</span>中的对话框。<span lang=EN-US> <br>
  <br>
  <br>
  <br>
  </span>  在<span lang=EN-US>Win32 DLL</span>中使用对话框就是这么简单,下面让我们来看一下在<span
  lang=EN-US>MFC DLL</span>中如何使用对话框。<span lang=EN-US> <br>
  <br>
  2</span>.<span lang=EN-US>MFC DLL <br>
  </span>  在<span lang=EN-US>MFC DLL</span>中使用对话框不像<span lang=EN-US>Win32 DLL</span>中那么简单,主要是因为<span
  lang=EN-US>MFC</span>程序中存在一个模块状态(<span lang=EN-US>Module State</span>)的问题,也就是资源重复的问题。(此处的术语模块是指一个可执行程序,或指其操作不依赖于应用程序的其余部分但使用<span
  lang=EN-US>MFC</span>运行库的共享副本的一个<span lang=EN-US>DLL</span>(或一组<span
  lang=EN-US>DLL</span>)。我们所创建的<span lang=EN-US>MFC DLL</span>就是这种模块的一个典型实例。)<span
  lang=EN-US> <br>
  <br>
  <br>
  <br>
  </span>  在每个模块(<span lang=EN-US>EXE</span>或<span lang=EN-US>DLL</span>)中,都存在一种全局的状态数据,<span
  lang=EN-US>MFC</span>依靠这种全局的状态数据来区分不同的模块,以执行正确的操作。这种数据包括:<span lang=EN-US>Windows</span>实例句柄(用于加载资源),指向应用程序当前的<span
  lang=EN-US>CWinApp</span>和<span lang=EN-US>CWinThread</span>对象的指针,<span
  lang=EN-US>OLE</span>模块引用计数,以及维护<span lang=EN-US>Windows</span>对象句柄与相应的<span
  lang=EN-US>MFC</span>对象实例之间连接的各种映射等。但当应用程序使用多个模块时,每个模块的状态数据不是应用程序范围的。相反,每个模块具有自已的<span
  lang=EN-US>MFC</span>状态数据的私有副本。这种全局的状态数据就叫做<span lang=EN-US>MFC</span>模块状态。<span
  lang=EN-US> <br>
  <br>
  <br>
  <br>
  </span>模块的状态数据包含在结构中,并且总是可以通过指向该结构的指针使用。当代码在执行时进入了某一个模块时,只有此模块的状态为<span
  lang=EN-US>“</span>当前<span lang=EN-US>”</span>或<span lang=EN-US>“</span>有效<span
  lang=EN-US>”</span>状态时,<span lang=EN-US>MFC</span>才能正确的区分此模块并执行正确的操作。<span
  lang=EN-US> <br>
  <br>
  <br>
  <br>
  </span>例如,<span lang=EN-US>MFC</span>应用程序可以使用下面代码从资源文件中加载字符串:<span
  lang=EN-US> <br>
  <br>
  <br>
  <br>
  CString str; <br>
  <br>
  str.LoadString(IDS_MYSTRING); <br>
  <br>
  <br>
  <br>
  </span>使用这种代码非常方便,但它掩盖了这样一个事实:即此程序中<span lang=EN-US>IDS_MYSTRING</span>可能不是唯一的标识符。一个程序可以加载多个<span
  lang=EN-US>DLL</span>,某些<span lang=EN-US>DLL</span>可能也用<span lang=EN-US>IDS_MYSTRING</span>标识符定义了一个资源。<span
  lang=EN-US>MFC</span>怎样知道应该加载哪个资源呢?<span lang=EN-US>MFC</span>使用当前模块状态查找资源句柄。如果当前模块不是我们要使用的正确模块,那么就会产生不正确的调用或者错误。<span
  lang=EN-US> <br>
  <br>
  <br>
  <br>
  </span>按照<span lang=EN-US>MFC</span>库的链接方法,一个<span lang=EN-US>MFC DLL</span>有两种使用<span
  lang=EN-US>MFC</span>库的方法:静态链接到<span lang=EN-US>MFC</span>的<span lang=EN-US>DLL</span>和动态链接到<span
  lang=EN-US>MFC</span>的<span lang=EN-US>DLL</span>。下面我们就按照这两种类型的<span
  lang=EN-US>MFC DLL</span>来介绍如何切换当前模块状态以正确的在<span lang=EN-US>MFC DLL</span>中使用资源。<span
  lang=EN-US> <br>
  <br>
  1</span>、静态链接到<span lang=EN-US>MFC</span>的<span lang=EN-US>DLL <br>
  <br>
  </span>静态链接到<span lang=EN-US>MFC</span>的规则<span lang=EN-US>DLL</span>与<span
  lang=EN-US>MFC</span>库静态链接,则此时<span lang=EN-US>MFC</span>库不能共享,所以<span
  lang=EN-US>MFC</span>总是使用它所链接的<span lang=EN-US>DLL</span>的模块状态。这样也就不存在管理模块状态的问题。但使用这种方法的缺点是<span
  lang=EN-US>DLL</span>程序将会变大,而且会在程序中留下重复代码。下面给出的例子验证了这一点。本例可以按照以下步骤来完成:<span
  lang=EN-US> <br>
  <br>
  <br>
  <br>
  1</span>)在<span lang=EN-US>VC</span>菜单中<span lang=EN-US>File-&gt;New</span>新建一个命名为<span
  lang=EN-US>DLLStatic</span>的<span lang=EN-US>MFC AppWizard</span>的工程,下一步选择<span
  lang=EN-US>Regular DLL with MFC statically linked</span>。<span lang=EN-US> <br>
  <br>
  <br>
  <br>
  2</span>)在工程中添加一个对话框资源,其<span lang=EN-US>ID</span>为:<span lang=EN-US>IDD_ABOUTBOX</span>。并在<span
  lang=EN-US>resource.h</span>之中将<span lang=EN-US>IDD_ABOUTBOX </span>的数值改为<span
  lang=EN-US>100</span>。<span lang=EN-US> <br>
  <br>
  <br>
  <br>
  3</span>)在<span lang=EN-US>DLLStatic.cpp</span>中定义如下函数:<span lang=EN-US> <br>
  <br>
  <br>
  <br>
  void ShowDlg() <br>
  <br>
  { <br>
  <br>
  </span> <span lang=EN-US> CDialog dlg(IDD_ABOUTBOX); <br>
  <br>
  </span> <span lang=EN-US> dlg.DoModal(); <br>
  <br>
  } <br>
  <br>
  <br>
  <br>
  4</span>)在<span lang=EN-US>DLLStatic.def</span>文件中的<span lang=EN-US>EXPORTS</span>语句中添加一行:<span
  lang=EN-US>ShowDlg</span>,以导出<span lang=EN-US>ShowDlg</span>函数。<span
  lang=EN-US> <br>
  <br>
  <br>
  <br>
  5</span>)编译生成<span lang=EN-US>DLLStatic.dll</span>和<span lang=EN-US>DLLStatic.lib</span>。<span
  lang=EN-US> <br>
  <br>
  <br>
  <br>
  </span>继续使用上一节中的<span lang=EN-US>Use</span>工程,将前面生成的<span lang=EN-US>DLLStatic.dll</span>和<span
  lang=EN-US>DLLStatic.lib</span>两个文件复制到工程的<span lang=EN-US>Debug</span>目录内,并将<span
  lang=EN-US> <br>
  <br>
  <br>
  <br>
  extern &quot;C&quot; __declspec(dllexport) void ShowDlg(); <br>
  <br>
  #pragma comment(lib,&quot;debug/UseDlg&quot;) <br>
  <br>
  <br>
  <br>
  </span>这两行改为:<span lang=EN-US> <br>
  <br>
  <br>
  <br>
  void ShowDlg(); <br>
  <br>
  #pragma comment(lib,&quot;debug/DLLStatic&quot;) <br>
  <br>
  <br>
  <br>
  </span>编译并运行<span lang=EN-US>Use.exe</span>。点击按钮,可以看到<span lang=EN-US>DLLStatic</span>中的模态对话框弹出。<span
  lang=EN-US> <br>
  <br>
  <br>
  <br>
  </span>本例中,可以注意到<span lang=EN-US>DLL</span>中所定义的<span lang=EN-US>About</span>对话框资源与<span
  lang=EN-US>EXE</span>中所定义的<span lang=EN-US>About</span>对话框资源<span lang=EN-US>ID</span>完全相同,但是当我们点击<span
  lang=EN-US>Use.exe</span>上面的按钮时,弹出的是<span lang=EN-US>DLL</span>中的模态对话框。说明,当使用静态链接到<span
  lang=EN-US>MFC</span>的规则<span lang=EN-US>DLL</span>时,不存在管理模块状态的问题。<span
  lang=EN-US><o:p></o:p></span></span></p>
  </td>
  <td style='padding:0cm 0cm 0cm 0cm'>
  <p class=MsoNormal align=left style='text-align:left;mso-pagination:widow-orphan'><span
  lang=EN-US style='font-size:10.0pt;mso-font-kerning:0pt'><o:p>&nbsp;</o:p></span></p>
  </td>
  <td style='padding:0cm 0cm 0cm 0cm'>
  <p class=MsoNormal align=left style='text-align:left;mso-pagination:widow-orphan'><span
  lang=EN-US style='font-size:10.0pt;mso-font-kerning:0pt'><o:p>&nbsp;</o:p></span></p>
  </td>
 </tr>
</table>

</div>

<p class=MsoNormal><span lang=EN-US><o:p>&nbsp;</o:p></span></p>

</div>

</body>

</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -