概述
虽然使用Acrobat Reader和Word等专用软件能够比较方便的阅读上述格式的资料文件,但如果需要在自己编写的应用程序中打开上述格式文档仍免不了自己动手进行处理。有多种途径可以实现此目的:通过创建子进程直接调用外部Acrobat Reader或Word应用程序打开指定文档;使用COM自动化技术在应用程序中嵌入Acrobat Reader或Word而打开指定文档;使用合适的ActiveX控件等等。其中,第一种方法是在应用程序之外打开文档,会使程序显的不是很“专业”,第二种方法同样会在打开文档而使嵌入对象处于现场激活状态时将Acrobat Reader或Word程序控制菜单嵌入到自己的程序当中,而在许多情况下这并不是我们所希望的。本文将针对最后一种方式,即通过对“Microsoft Web浏览器”ActiveX控件的使用而在应用程序中完成对PDF、Word格式文档文件的打开、显示。当用户用以该方法编写的应用程序在打开这些格式文档文件时将不再感觉是在Acrobat Reader或Word程序中的浏览。
控件的创建
“Microsoft Web浏览器”控件随Visual C++开发环境一起安装到系统。从“Project”菜单下“Add To Project”弹出菜单的“Components and Controls…”子菜单弹出“Components and Controls Gallery”对话框,进入“Registered ActiveX Controls”目录并选中“Microsoft Web浏览器”控件,点击“Insert”按钮将其添加到VC++开发环境的控件工具栏中。
通常对ActiveX控件的使用多是在资源视图中将指定的ActiveX控件拖拽到相应的对话框中,并完成对其属性的设置和对事件处理函数的添加。但由于本程序应用“Microsoft Web浏览器”控件的目的是为了浏览PDF和Word等格式的文档,因此应用程序框架采取多文档视图结构比较合适,在这种情况下显然不能再以传统方式创建控件而应通过代码来完成动态创建。
在将 “Microsoft Web浏览器”控件插入到工程后,派生于CWnd类的CWebBrowser2类被添加到工程,它提供了一个可供重载使用的虚函数Create()和一个类成员函数Create():
virtual BOOL Create(LPCTSTR lpszClassName,LPCTSTR lpszWindowName,DWORD dwStyle,const RECT& rect,CWnd* pParentWnd, UINT nID,CCreateContext* pContext = NULL); BOOL Create(LPCTSTR lpszWindowName,DWORD dwStyle,const RECT& rect, CWnd* pParentWnd, UINT nID, CFile* pPersist = NULL, BOOL bStorage = FALSE, BSTR bstrLicKey = NULL); |
通过该函数将可以象动态创建编辑框、按钮等标准控件一样动态创建。这里需要特别指出的是,一个“Microsoft Web浏览器”控件只能负责对一个文档的维护,也就是说,在多文档结构的本程序中需要为每一个打开的文档分配一个“Microsoft Web浏览器”控件以进行管理。这在具体实施上,只需在文档或视图类中声明CWebBrowser2类对象即可。下面这段代码在视图类完成,在OnInitialUpdate()函数更新视图时完成对控件的动态创建,创建的控件将占据视图的全部客户区:
CWebBrowser2 m_Web; …… // 得到客户区 CRect rect; GetClientRect(&rect); // 创建控件窗体 m_Web.Create(NULL, WS_CHILD | WS_VISIBLE, rect, this, ID_WORD); |
文档的打开显示
本程序在文件打开显示上采取的策略是:由程序框架负责获取需要打开的文件路径,并新建一文档。在视图更新“Microsoft Web浏览器”控件创建完毕后,由CWebBrowser2类成员函数Navigate ()负责对具体文档的维护管理。这部分工作的具体处理代码如下:
// 主框架类: // 显示打开文件对话框 CFileDialog fileDlg(TRUE, "*.doc", "*.doc", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Word文件(*.doc)|*.doc|PDF文件(*.pdf)|*.pdf|Web页(*.htm)|*.htm|所有文件(*.*)|*.*||", NULL); if (fileDlg.DoModal() == IDOK) { // 得到文件路径 m_sPath = fileDlg.GetPathName(); // 新建文档 PostMessage(WM_COMMAND, ID_FILE_NEW, 0); } …… // 视图类: // 得到并保存要打开的文件路径 m_sFilePath = ((CMainFrame*)AfxGetApp()->GetMainWnd())->m_sPath; ((CMainFrame*)AfxGetApp()->GetMainWnd())->m_sPath = "about:blank"; // 打开指定的文件 m_Web.Navigate(m_sFilePath, NULL, NULL, NULL, NULL); // 窗体设置为大小可变 m_Web.SetResizable(TRUE); |
为了在刷新视图或窗口尺寸变更时能够即使刷新显示,还需要在OnDraw()函数和WM_SIZE消息响应函数OnSize()中添加额外的处理代码:
// 重绘窗口 (OnDraw()函数) if (m_Web.m_hWnd != NULL) m_Web.RedrawWindow(); …… void CShowWordView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); if (m_Web.m_hWnd != NULL) { // 得到新的客户区 CRect rect; GetClientRect(&rect); // 设置新的窗口位置 m_Web.SetWindowPos(&wndTop, rect.left, rect.top, rect.Width(), rect.Height(), NULL); // 重绘窗体 m_Web.RedrawWindow(); } } |
其中,SetWindowPos()函数将重新设置“Microsoft Web浏览器”控件窗口的放置位置以使其能够占据尺寸更改后的文档窗口的全部客户区大小。
小结
领测软件测试网最新更新
关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved 北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备10010545号-5 技术支持和业务联系:info@testage.com.cn 电话:010-51297073 |