Adobe ActiveX 控件与 MFC






4.44/5 (22投票s)
2005 年 2 月 9 日
5分钟阅读

346079

5319
如何在 C++ 应用程序中使用 Adobe Acrobat 7 Reader ActiveX 控件。
引言
本文是一篇简单的操作指南,介绍如何在 MFC C++ 应用程序中使用 Adobe Acrobat 7 ActiveX 控件。随附的示例项目使用了一个最小化的 MDI MFC 应用程序,展示了您可以在同一个应用程序中使用多个控件实例。代码保持简单精炼,以便更侧重于实际内容。源代码和项目文件使用 Microsoft Visual C++ .NET 2003 编写,但代码可以轻松集成到任何版本的 Visual C++ 中。
背景
早期版本的 Adobe Acrobat 不允许在外部应用程序中使用 ActiveX 控件。根据 Acrobat 开发者 FAQ,ActiveX 控件仅为 Microsoft Internet Explorer Web 浏览器开发,不支持或许可用于任何其他应用程序。随着 Adobe Acrobat 7 的发布,Acrobat Reader ActiveX 控件现在已获得完全支持和文档支持,这为应用程序开发者在向客户分发 PDF 文件时提供了更大的灵活性。通过此控件打开的 PDF 文件还可以利用 Acrobat JavaScript 进行相互通信,就像在网页中打开一样。
使用代码
代码非常简单直接,主要用于展示如何将控件导入到您自己的应用程序中,而不仅仅是复制粘贴演示源代码。我选择使用 CWnd
作为演示项目的视图,而不是 CFormView
,这将帮助您理解如何以编程方式创建控件,而不是简单地将其放置在工具箱的对话框上。
使用 Acrobat Reader 7 控件的第一步是使用类向导从 ActiveX 控件创建 MFC 类。在类视图选项卡中,右键单击您的项目,选择“添加->添加类...”并选择“从 ActiveX 添加 MFC 类”选项。
现在单击“打开”,将出现一个新对话框。在标有“可用 ActiveX 控件”的部分,在组合框中找到并选择“Adobe Acrobat 7.0 Browser Document <1.0>”控件。“IAcroAXDocShim”接口将出现在接口列表中。选择该接口,然后单击“>”箭头为它添加一个类。然后,向导将创建 CAcroAXDocShim
类并将其添加到您的项目中。
您几乎完成了,现在只需要在您自己的窗口中使用这个生成的类。在您的窗口视图类中添加一个类型为“CAcroAXDocShim
”的成员变量。
#include "CAcroAXDocShim.h" class CAcroViewer : public CWnd { public: ... // Attributes private: CAcroAXDocShim m_ctrl; };
添加了变量后,您只需创建它并使用它来打开 PDF 文件。要创建它,首先创建一个控件 ID,它只是一个当前未被应用程序中其他控件使用的整数。然后,在窗口的 OnCreate
处理程序的末尾,调用控件的 Create
函数。所需的第一个参数是窗口名称的字符串,您可以使用任何值,我选择了“AdobeWnd
”。下一个参数是窗口样式,您需要 WS_CHILD
将其设置为子窗口,并需要 WS_VISIBLE
使其可见。接下来是一个用于窗口位置的 RECT
,我使用了全零,因为我创建了一个 WM_SIZE
处理程序来在窗口大小调整时调整控件大小。接下来的参数是窗口父窗口(this
)和创建的控件 ID。
const int CTRL_ID = 280; int CAcroViewer::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; //Create the control, just make sure to use WS_CHILD and WS_VISIBLE. if (!m_ctrl.Create("AdobeWnd", WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), this, CTRL_ID)) { AfxMessageBox("Failed to create adobe wnd"); return -1; } return 0; }
ActiveX 控件现在已在您的应用程序中创建并可见。现在唯一的问题是它的尺寸为 0。要解决此问题,我们向窗口添加一个 WM_SIZE
处理程序,并将控件的大小调整为匹配窗口的客户区矩形。我们必须通过调用 IsWindow(m_hWnd)
来确保窗口有效。在此调用之后,我们只需调用 GetClientRect()
并将该矩形传递给 MoveWindow()
来为我们的控件设置大小。
void CAcroViewer::OnSize(UINT nType, int cx, int cy) { CWnd::OnSize(nType, cx, cy); //Resize the control with the window. if (IsWindow(m_hWnd)) { CRect rc; GetClientRect(rc); m_ctrl.MoveWindow(rc); } }
最后要做的事情就是打开一个 PDF 文件。这可以通过对控件调用一个简单的 LoadFile
来完成。“file”参数可以是本地文件系统上的文件,也可以是 HTTP 服务器上文件的 URL。
void CAcroViewer::Open(const char *file) { //Just load the file that is opened. m_ctrl.LoadFile(file); }
关注点
不幸的是,尽管这个控件现在已经脱离了 Microsoft Internet Explorer 浏览器,但它似乎仍然存在之前所有 Acrobat Reader 版本中的 bug。有时,需要打开任务管理器并“结束任务” "AcroRd32.exe"
应用程序才能使事情重新正常工作。这不是此应用程序相关的问题,而是控件本身的问题。当在 Internet Explorer 中打开和关闭多个 PDF 文件时,有时会遇到 PDF 查看器冻结的问题。我希望 Adobe 在发布 Acrobat Reader 7 时能修复这个 bug,但它似乎仍然存在。
结论
我希望本文能帮助那些想要在自己的应用程序中使用 PDF 文件但只有 Acrobat Reader 的用户。如果您拥有 Adobe Acrobat 的完整版本,那么您在自己的应用程序中使用 PDF 文件还有许多其他选择,例如 OLE 自动化。我曾经在 C++ 和 C# 应用程序中广泛地使用 Acrobat 的 OLE 自动化,在大多数情况下这是一种更好的方法,但它仅限于 Acrobat Professional,并且在只有 Acrobat Reader 安装的系统上不受支持。