2

Microsoft.mshtml.dll 程序集中的 mshtml.HTMLDocumentClass 类有一个方法:

public virtual void write(params object[] psarray);

暂时避免真正的问题,您将使用什么代码来调用write()?你会使用:

String html = "<html><body>Hello, world!</body></html>";
mshtml.HTMLDocumentClass doc;
...
doc.write(html);

或者你会使用:

String html = "<html><body>Hello, world!</body></html>";
mshtml.HTMLDocumentClass doc;
...
object[] params = new Object[1];
params[0] = html;
doc.write(params);

因为这两个都抛出异常。(类型不匹配。0x80020005)

HTMLDocumentClass.write方法实际上来自IHTMLDocument2接口,它被记录为:

IHTMLDocument2::write 方法

将一个或多个 HTML 表达式写入指定窗口中的文档。

句法

HRESULT write(
   SAFEARRAY *psarray
);

参数

psarray

   [in] A **BSTR** that specifies the text and HTML tags to write.

所以实际上 write 方法需要一个指向 SAFEARRAY 的指针,即使 Microsoft 的Microsoft.mshtml互操作程序集将write方法定义为采用常规数组:

public virtual void write(params object[] psarray);

忽略 mshtml 互操作声明,我必须构造一个SAFEARRAY对象(对象数组),用 BSTR 字符串(字符串)填充它,并将其填充到必须是对象数组的参数中。


注意:我不确定params关键字的含义。它用于指示可变数量的参数。

这是否意味着它可以采用多个数组参数?

object[] array1 = new Object[1];
array1 [0] = alpha;
object[] array2 = new Object[1];
array2 [0] = bravo;
object[] array3 = new Object[1];
array3 [0] = charlie;
object[] array4 = new Object[1];
array4 [0] = delta;

doc.write(array1, array2, array3, array4);

还是 object[] 是传递多个参数的方法,并且您必须逐字创建一个数组?

object[] params = new Object[4];
params[0] = alpha;
params[1] = bravo;
params[2] = charlie;
params[3] = delta;
doc.write(params);

或者 array[] 只是一个诱饵,你真的通过了:

doc.write(alpha, bravo, charlie, delta);

当我最初从本机 Win32 应用程序中使用此代码时,BSTR 被放置在 SAFEARRAY 中。在基于 IDispatch 的自动化中,一切都在数组中。在这种情况下,后期绑定代码:

doc.write(html);

由编译器转换为 SAFEARRAY,其中第零个元素包含 BSTR 字符串(这是一个长度前缀的 unicode 字符串)。

我的问题变成了尝试构建 SAFEARRAY、将字符串转换为 BSTR、将 BSTR 放入 SAFEARRAY 的第零个元素以及将包含 SAFEARRAY 的变量传递给仅接受对象数组(object [ ])。

这是真正的问题:如何创建 BSTR SAFEARRAY?


微软.mshtml

C:\Program Files\Microsoft.NET\Primary Interop Assemblies\Microsoft.mshtml.dll

4

3 回答 3

1

IHTMLDocument2TLBIMP/VS.NET创建的接口的write方法声明不正确。它应该是:

void Write([In, MarshalAs(UnmanagedType.SafeArray)] object[] psarray);

您必须在代码中定义此接口,然后使用它。

于 2009-01-28T20:23:58.870 回答
1

params 关键字表示你可以在这个地方提供多个参数,它会自动分组。例如,如果我有这样的功能:

public int SumNumbers(params int[] value)
{
       //Logic.
}

那么我可以这样称呼它:

int myValue = SumNumbers(1,2,3,4,5,6,7,8,9,10);

数组是自动构建的。所以假设,你可以打电话

mshtml.HTMLDocumentClass doc;
...
doc.write('H','I',' ','M','O','M');

它会起作用。虽然不是很实用。我想你试过打电话

doc.write(myString.ToCharArray());

? 我对 SAFEARRAYS 一无所知,但您可能也不必知道,这取决于编译器如何帮助/阻碍这里。

于 2009-01-28T20:48:34.187 回答
1

它以这种方式就像一个魅力:

[Guid("332C4425-26CB-11D0-B483-00C04FD90119")]
[ComImport]
[TypeLibType((short)4160)]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
internal interface IHTMLDocument2
{
    [DispId(1054)]
    void write([MarshalAs(UnmanagedType.BStr)] string psArray); //modified 
    //void write([MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)] object[] psarray); //instead of
于 2009-06-18T11:47:35.623 回答