.NET mshtml:如何传递BSTR SAFEARRAY?

时间:2009-01-28 19:51:34

标签: .net com interop mshtml

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 interface,其记录为:

  

IHTMLDocument2 :: write方法

     

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

     

语法

HRESULT write(
   SAFEARRAY *psarray
);
     

参数

     

psarray

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

因此,在现实的写入方法需要一个指向一个SAFEARRAY,即使微软的 Microsoft.mshtml 互操作组件限定的方式为采取规则阵列:

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);

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

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

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

doc.write(html);
编译器将

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

我的问题变得试图构建SAFEARRAY,转换一个字符串转换为BSTR,放置BSTR到SAFEARRAY的第零个元素,并传递一个包含一个SAFEARRAY到一个可变只接受一个对象阵列的一个(对象[])。

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


  

Microsoft.mshtml

     

C:\程序   Files \ Microsoft.NET \ Primary Interop   组件\ Microsoft.mshtml.dll

3 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分: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一无所知,但根据编译器如何帮助/阻碍,你可能也不必知道它。

答案 2 :(得分: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