我的程序需要将HTML文档放进剪贴板中,但我不知道要怎样处理才能使其他程序也能使用它。

我查看了一些关于HTML Clipboard Format (CF_HTML)的参考说明,但我还是找不到准确的定义。

请问我该如何操作?

  解答:  使用带有Windows 剪贴板的CF_HTML Clipboard Format的确容易让人搞胡涂,一部分是因为它不是clipboard format中自带的剪贴板;它是一个注册格式(registered format),所以不是一个常量,因为它的值会因为系统的不同而产生变化。

你可以通过一个简单的API调用 -- RegisterClipboardFormat来获得一个注册剪贴板格式的值。

这个函数的首次调用会通过一个给定的字符串来执行,它返回一个范围在C000-FFFF之间的唯一值。

每一个在系统上处理的后续调用(subsequent call)会返回同样的值。

用于这种格式中的关键字符串就是HTML Format:  Private Declare Function RegisterClipboardFormat Lib user32 Alias RegisterClipboardFormatA(ByVal lpString As String) As LongDim CF_HTML As LongConst RegHtml As String = HTML FormatCF_HTML = RegisterClipboardFormat(RegHtml)  你必须首先构建一个描述性的header,并在将HTML数据放入剪贴板之前先把它放到数据中。

这个header会给其他程序提供描述版本信息、HTML起始数据的偏移量(offset),以及有关实际选择范围(actual selection)起始地方的信息。

用户可能会选择的HTML文档的一部分甚至只是一个元素(比如一个table中的几行)作为一个选择区域。

页面的其他部分,比如内联样式定义(inline style definitions)则可能会被要求进行完全渲染(render)。

你不仅需要将最初所选择的HTML区域放入剪贴板,而且还需要放入一个header,它看起来就像是这样:Version:1.0StartHTML:000000258EndHTML:000001491StartFragment:000001172EndFragment:000001411  应用程序通过StartFragment和EndFragment属性来决定哪些数据需要粘贴,这些数据或许会(也可能不会)用剩下的HTML对所选择的部分进行格式安排。

你必须将HTML注释放入数据中以便将来对所选部分进行识别。

很明显,你必须在构建最后的header之前完成它,否则偏移量会有变化。

一个用于所选数据的opening/closing注释标签分别是!--StartFragment--和!--EndFragment--  列表1. 在你构建一个用于HTML片断的描述性header时这个程序(routine)会很有用。

如果你放入整个HTML文档,则StartFragment标签会紧随body标签放入,而EndFragment标签则会被放在/body之前。

如果你只是放入一段HTML而不是整个文档,那么程序则只会放入html和body标签。

Public Function HtmlDescribed(ByVal Fragment As String) As StringDim Data As StringDim nPos As LongConst Description As String = Version:1.0 vbCrLf StartHTML:aaaaaaaaaa vbCrLf _EndHTML:bbbbbbbbbb vbCrLf StartFragment:cccccccccc vbCrLf _EndFragment:dddddddddd vbCrLfConst FragmentStart As String = !--StartFragment--Const FragmentEnd As String = !--EndFragment--Const Fmt As String = 0000000000' Add the starting and ending tags for the' HTML fragment by looking for body tag.nPos = InStr(1, Fragment, body, vbTextCompare)Select Case nPosCase 0Fragment = htmlbody vbCrLf FragmentStart FragmentCase ElsenPos = InStr(nPos, Fragment, )If nPos 0 And nPos Len(Fragment) ThenFragment = Left$(Fragment, nPos) FragmentStart Mid$(Fragment, nPos 1)End IfEnd SelectnPos = InStr(1, Fragment, /body, vbTextCompare)Select Case nPosCase 0Fragment = Fragment FragmentEnd vbCrLf /body/htmlCase ElseFragment = Left$(Fragment, nPos - 1) FragmentEnd Mid$(Fragment, nPos)End Select' Build the HTML given the description, the' fragment, and the context. And, replace the' offset placeholders in the description with' values for the offsets of StartHMTL,' EndHTML, StartFragment, and EndFragment.' Offsets need to be zero-based when placed on' clipboard, so subtract 1' from each before injecting.Data = Description FragmentData = Replace(Data, aaaaaaaaaa, Format$(Len(Description), Fmt))Data = Replace(Data, bbbbbbbbbb, Format$(Len(Data), Fmt))nPos = InStr(Data, FragmentStart) - 1Data = Replace(Data, cccccccccc, Format$(nPos Len(FragmentStart), Fmt))nPos = InStr(Data, FragmentEnd) - 1Data = Replace(Data, dddddddddd, Format$(nPos, Fmt))' Return attributed string.HtmlDescribed = DataEnd Function在这里我无法对这个header的各个方面都进行详细的介绍,所以我只能讲解一些要点,你可以参考范例代码以及进行更深入的了解。

你必须记住几个要点。

Header中的偏移量是以零为基准的,因此你必须以此来调节你的字符串操作程序(string-manipulation routine )。

而且,如果你不仅需要读取而且需要编写header,你则必须了解字符数(number of digits )(比如Internet Explorer [IE] 是9,Word是10)。

最后,如果你只是将CF_HTML放入剪贴板,那么诸如Word和FrontPage等程序就处理不了了。

你必须同时给剪贴板提供一个格式化的HTML的纯文本编译(plain-text rendition)以实现你所希望的结果。

许多用来执行HTML-to-text转换的工具或是macho可能都需要执行自带的剖析器。

但是Windows程序员是不需要对HTML进行手动解析的。

你可以用OS来取代这个日常任务:  Public Function Html2Text(ByVal Data As String) As StringDim obj As ObjectOn Error Resume NextSet obj = CreateObject(htmlfile)obj.Openobj.Write DataHtml2Text = obj.Body.InnerTextEnd Function  升级IE并不是解析HTML最快的方法,但却是相当好用的方法。