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 メソッド

指定されたウィンドウ内のドキュメントに 1 つ以上の HTML 式を書き込みます。

構文

HRESULT write(
   SAFEARRAY *psarray
);

パラメーター

psarray

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

したがって、実際には、Microsoft のMicrosoft.mshtml相互運用機能アセンブリで書き込みメソッドが通常の配列を取るように定義されていても、書き込みメソッドには SAFEARRAY へのポインターが必要です。

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 に変換されました。ここで、0 番目の要素には BSTR 文字列 (長さの接頭辞付きの Unicode 文字列) が含まれています。

私の問題は、SAFEARRAY を構築しようとすること、文字列を BSTR に変換すること、BSTR を SAFEARRAY の 0 番目の要素に配置すること、および SAFEARRAY を含む変数をオブジェクト配列 (object[ ]))。

これが本当の問題です: BSTR SAFEARRAY を作成する方法は?


Microsoft.mshtml

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

4

3 に答える 3

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 に答える
1

IHTMLDocument2TLBIMP/VS.NET で作成したインターフェースの write メソッドの宣言が正しくありません。そのはず:

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

このインターフェースをコードで定義してから、それを使用する必要があります。

于 2009-01-28T20:23:58.870 に答える