DLLScreenCap 示例:演示静态或动态链接到 MFC 的规则 DLL

更新:2007 年 11 月

DLLScreenCap 示例演示了一个屏幕捕获工具的动态链接库 (DLL) 版本。DLLScreenCap 取代了已过时的 DLLTRACE 示例。DLLTRACE 是在 MFC 1.0 版中引入的,用于演示如何编写本身静态链接到 MFC 库的 DLL。DLLScreenCap 向它动态链接到的基于 Microsoft Windows 的应用程序提供基于 C 的程序接口。静态链接到 MFC 库的 DLL 无法成功导出从 MFC 类派生的任何类的成员函数。

技术说明 11:将 MFC 用作 DLL 的一部分中探讨了将 DLL 静态链接到 MFC 库的技术。DLLScreenCap 示例也可以动态链接到 MFC,而无需成为扩展 DLL。在决定通过静态链接到 MFC 来实现自定义 DLL 之前,请考虑将其实现为 MFC 扩展 DLL,详见技术说明 33:MFC 的 DLL 版本中的说明,DLLHUSK 示例对此进行了演示。

与可执行的 MFC 应用程序一样,链接到 MFC 库的非扩展 DLL 需要具有从 CWinApp 派生的类以及该应用程序类的单个对象。但与应用程序的 CWinApp 对象不同的是,DLL 的 CWinApp 对象没有主消息泵。如果 DLL 打开无模式对话框或有自己的主框架窗口,则应用程序的主消息泵必须调用由 DLL 导出的例程,该例程则调用 DLL 应用程序对象的 CWinApp::PreTranslateMessage 成员函数。这可以通过 DLLScreenCap.dll 导出的 FilterDllMsg 函数演示。

ScreenCapApi.h 显示向客户端应用程序提供 DLL 接口的方法之一是用 extern“C”来声明函数。使用 extern“C”有若干优点。首先,它使 DLL 可由非 C++ 客户端应用程序使用。其次,它减少了 DLL 系统开销,原因是 C++ 名称修饰不会应用于导出的名称。另外,它还使显式添加到 .def 文件(以便按顺序导出)更方便,无需再考虑 C++ 名称修饰。

安全说明:

提供该示例代码是为了阐释一个概念,并不代表着最安全的编码实践,因此不应在应用程序或网站中使用该示例代码。对于超出本示例代码的预期用途以外的使用所造成的偶然或继发性损失,Microsoft 不承担任何责任。

获取示例和安装示例的说明:

  • 在 Visual Studio 的“帮助”菜单上,单击“示例”。

    有关更多信息,请参见定位示例文件

  • 示例的最新版本和完整列表可以从 Visual Studio 2008 Samples page(Visual Studio 2008 示例页面)联机获取。

  • 还可以在计算机的硬盘上查找示例。默认情况下,示例和自述文件将复制到 \Program Files\Visual Studio 9.0\Samples\ 下的文件夹中。对于 Visual Studio 速成版,所有示例都位于联机位置。

生成并运行示例

DLLScreenCap 示例由两个项目组成:DLLScreenCap(DLL 项目)和 ScreenCap(调入 DLL 的 EXE 项目)。

从所提供的解决方案生成 ScreenCap 将自动生成 DLLScreenCap,并将 DLL 复制到 ScreenCap 的输出目录中。

注意   由于此示例使用自定义生成步骤来复制文件,因此不应使用 UNC 路径打开解决方案;请将示例文件放在带驱动器号的目录中。

生成并运行 DLLScreenCap 示例

  1. 打开解决方案 DllScreenCap.sln。

  2. 在“解决方案资源管理器”中,右击“ScreenCap”项目文件夹,然后在快捷菜单上单击**“设为启动项目”**。

  3. 在“生成”菜单上单击“生成”。

  4. 在**“调试”**菜单上,单击“开始执行(不调试)”。

“ScreenCap”窗口显示在缩放到窗口大小后捕获的最后一屏。在**“File”菜单上单击“Configure Screen Capture”。这将打开一个对话框,指定是捕获屏幕还是捕获活动窗口,以及要将捕获文件保存到的路径。单击“Screen Capture”**创建捕获文件并更新客户端窗口显示。

转换 DLLScreenCap 以便与 MFC DLL 动态链接

DLLScreenCap 演示如何使用(可调用以显示有模式对话框的)导出函数来创建规则 DLL。在 Visual C++ 的早期版本中,这是唯一可用于规则 DLL 的选择。这些类型的 DLL 以前称为 _USRDLL。

现在,规则 DLL 可以通过共享 MFCx0 DLL 使用 MFC。由于可能需要减小版本的大小,您可以使用共享 MFC DLL 来生成 DLLScreenCap 示例。在 DLLScreenCap.dll 中支持共享库可以将发布版本 DLL 的大小从 100K 以上减小到大约 16K,并可以调试版本的大小从 1 MB 以上减小到 100K。若要在 DLLScreenCap 中支持动态链接,请使用 AFX_MANAGE_STATE 宏来正确地切换全局 MFC 模块状态。

验证 DLLScreenCap 是否可以在共享库中使用

  1. 在解决方案资源管理器中,右击 ScreenCap 项目节点并在快捷菜单上单击“属性”。

    将显示“属性页”对话框。

  2. 从“配置”下拉菜单中选择**“多重配置”**。有关“属性页”对话框的更多信息,请参见设置 Visual C++ 项目属性

  3. 选择**“发布”“调试”**两个版本,更改它们的设置。

  4. 在项目的“常规”属性页中,验证是否选中了指定要在共享 DLL 属性中使用 MFC 的“MFC 的使用”属性。

  5. 验证以下代码行是否位于从 DLL 导出的每个函数的开头(有关这一点的探讨,请参见 管理 MFC 模块的状态数据):

    AFX_MANAGE_STATE(AfxGetStaticModuleState())
    

例如,DllScreenCap.dll 导出 4 个函数:

  • CaptureScreen

  • ConfigureCapture

  • ProcessDLLIdle

  • FilterDLLMsg

在转换后的形式中,FilterDLLMsg 应类似于如下所示:

BOOL WINAPI FilterDllMsg(LPMSG lpMsg)
{
   AFX_MANAGE_STATE(AfxGetStaticModuleState())
   TRY
   {
       return AfxGetApp()->PreTranslateMessage(lpMsg);
   }
   END_TRY
return FALSE;
}

关键字

此示例说明以下关键字:

CDialog::DoModal、CWinApp::InitInstance、CWinApp::OnIdle、CWinApp::PreTranslateMessage、CWnd::DoDataExchange、CWnd::GetClientRect、CWnd::OnPaint、ShowWindow、UpdateWindow、CImage、AFX_MANAGE_STATE、AfxGetStaticModuleState、CWnd::GetDesktopWindow、CWnd::GetActiveWindow、CImage::Create、CImageDC、CImage::Save、SHBrowseForFolder、CImage::Load、CDC::SetStretchBltMode、CImage::StretchBlt、CWnd::OnEraseBkgnd、CWindowDC

请参见

其他资源

MFC 示例