分类: C/C++
2008-02-14 11:08:14
本文介绍如下内容
1、如何显示内存中的 HTML 网页;
2、如何屏蔽掉鼠标右键的上下文菜单;
3、如何扩展 HTML 中的脚本(external)对象;
4、如何显示 HTML 样式的对话窗;
5、如何执行 HTML 脚本;
一、如何显示内存中的 HTML 网页
或者因为网页保密的考虑;或者因为软件分发的考虑,有的时候就需要让 IE 或 IE 浏览器控件显示内存或资源中的 HTML 网页。在 MFC 中,CHtmlView::LoadFromResource() 可以显示程序资源中的 HTML 内容。我们都知道MFC的 CHtmlView 其实是对 IWebBrowser2 的一个包装,但是在 IWebBrowser2 中却没有类似的方法。那么它是如何实现的那?步骤如下:
1、首先通过 IWebBrowser2::Navigate2() 显示一个网页,其目的是产生有效的对象,从而得到 IHTMLDocument2 接口;
2、IWebBrowser2::get_Document() 得到 IHTMLDocument2 接口指针;
3、IHTMLDocument2::QueryInterface() 得到 IPersistStreamInit 接口指针;
4、IPersistStreamInit::InitNew() 初始化接口对象;
5、IPersistStreamInit::Load() 装载内存中的 HTML 数据流(IStream *);
内存指针转换为流的方法是:
I、 GlobalAlloc() 申请内存;
II、 复制 HTML 字符串内容到上述的内存中;
III、 CreateStreamFromHGlobal() 转换内存为 IStream 指针;
原理性代码如下:
// 显示一个空白网页 m_ie.Navigate2( &CComVariant(_T("about:blank")),NULL,NULL,NULL,NULL); // 得到 IHTMLDocument2 指针 CComPtr< IDispatch > spDoc(m_ie.GetDocument()); // 得到 IPersistStreamInit 指针 CComQIPtr< IPersistStreamInit, &IID_IPersistStreamInit > spPSI( spDoc ); // 申请内存,复制 HTML 字符串 LPTSTR lpMem = (LPTSTR)::GlobalAlloc( GPTR, ::lstrlen( lpHtml )+1 ); lstrcpy( lpMem, "xxx xxx" ); // 转换内存为流对象指针 CComPtr< IStream > spStream; CreateStreamOnHGlobal( lpMem, TRUE, &spStream ); // 初始化后,装载显示 spPSI->InitNew(); spPSI->Load( spStream );
图一、IE控件显示内存中的 HTML 文件 图二、HTML对话窗
IE 所能支持的数据传输协议,除了大家所熟悉的 http、ftp、file......还有一个协议是 res ,它表示浏览显示文件中的 HTML 资源。你可以在 IE 的地址栏上直接输入这样格式的 URL:"res://文件名/资源名"。
把 HTML 文件加入到程序资源的方法比较简单,在资源卡片中,鼠标右键弹出菜单,执行 Import...(引入),选择指定的 HTML 文件,然后给一个资源名称即可。(在这里,最方便的资源名称用字符串比较好,如果使用整数ID,那么将来在使用的时候是这样的格式:res://文件名/#101,这里假设 101 是资源的ID号。真麻烦!我不太喜欢这样的方式。)对于图片文件等其它的附件,则需要手工编辑资源 RC 文件(用 IDE 环境引入,它会试图用文本方式打开一个2进制文件,多数情况下会“死机”)。下图是事例程序引入资源后的样式:
图三、HTML 资源的引入
手工编辑 RC 文件的部分是:
...... ///////////////////////////////////////////////////////////////////////////// // // HTML // HTML_TOWORD HTML DISCARDABLE "res\\ToWord.htm" // 这两个是HTML文件,可以引入 HTML_DLG HTML DISCARDABLE "res\\html_dlg.htm" ~SEND_R1_C1.GIF HTML DISCARDABLE "res\\~Send_r1_c1.gif" // 下面的是GIF文件,需要手工加入 ~SEND_R1_C2.GIF HTML DISCARDABLE "res\\~Send_r1_c2.gif" LOGO.GIF HTML DISCARDABLE "res\\Logo.gif" SEND_R1_C1.GIF HTML DISCARDABLE "res\\Send_r1_c1.gif" SEND_R1_C2.GIF HTML DISCARDABLE "res\\Send_r1_c2.gif" SPACER.GIF HTML DISCARDABLE "res\\spacer.gif" #endif // Chinese (P.R.C.) resources ///////////////////////////////////////////////////////////////////////////// ......
HRESULT ShowHTMLDialogEx(
HWND hwndParent, IMoniker *pMk, DWORD dwDialogFlags, VARIANT *pvarArgIn, WCHAR *pchOptions, VARIANT *pvarArgOut );
hwndParent | 对话窗的父窗口句柄 | 这个太简单了,不多罗嗦。 |
pMk | URL的命名接口指针 | 表示在对话窗中显示哪个URL的页面。但它不是以简单的URL字符串方式提供的。它使用了moniker(命名)接口指针。 根据URL得到IMoniker *很简单,调用CreateURLMoniker()。唯一要注意的是,这个函数需要连接 Urlmon.lib 库。 |
dwDialogFlags | 对话窗类型 | 可以组合 HTMLDLG_NOUI、HTMLDLG_MODAL、HTMLDLG_MODELESS、HTMLDLG_PRINT_TEMPLATE、HTMLDLG_VERIFY。 示例程序使用的是模式对话窗。HTMLDLG_NOUI 在下一节中介绍。 |
pvarArgIn | 对话窗的输入参数 | 一个传入对话窗的VARIANT变量,对话窗脚本中使用 window.dialogArguments 可以取得。 |
pchOptions | 对话窗样式 | 用字符串表示的对话窗样式。参考 IHTMLWindow2::showModalDialog()函数。 比如:"dialogHeight:100px dialogWidth:200px"表示200点宽,100点高。如果你不想在程序中指定,也可以在HTML中描述。 |
pvarArgOut | 对话窗输出参数 | 对话窗的VARIANT返回值,对话窗脚本中使用 window.returnValue 可以赋值。 |
On Error Resume Next Set wordapp=CreateObject("Word.Application") ''''运行 MS WORD if err<>0 then MsgBox("没有安装 MS WORD") else wordapp.visible = true ''''显示WORD界面 wordapp.Documents.Add "",false, 0 ''''新增一个空文档 wordapp.Selection.TypeText window.dialogArguments ''''键入传递进来的文本 end if window.close '''' 关闭