.NET mshtml: как сдать BSTR SAFEARRAY? - PullRequest
2 голосов
/ 28 января 2009

Класс mshtml.HTMLDocumentClass в сборке Microsoft.mshtml.dll имеет метод:

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 :: Метод записи

Записывает одно или несколько выражений HTML в документ в указанном окне.

Синтаксис

HRESULT write(
   SAFEARRAY *psarray
);

Параметры

psarray

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

Таким образом, в действительности методу записи необходим указатель на SAFEARRAY, хотя сборка взаимодействия Microsoft Microsoft.mshtml определяет метод write как получение обычного массива:

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

Игнорируя объявление взаимодействия mshtml, я должен создать объект SAFEARRAY (стихи массив объектов), заполнить его строкой BSTR (стихи String) и вставить его в параметр, который должен быть массив объектов.


Примечание: я не уверен в значении ключевого слова 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[] 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: \ Program Файлы \ Microsoft.NET \ Основное взаимодействие Сборки \ Microsoft.mshtml.dll

Ответы [ 3 ]

1 голос
/ 28 января 2009

Ключевое слово 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, но, возможно, вам, возможно, и не понадобится знать, в зависимости от того, как компилятор помогает / мешает здесь.

1 голос
/ 18 июня 2009

Это работает как очарование таким образом:

[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
1 голос
/ 28 января 2009

Объявление для метода записи в интерфейсе IHTMLDocument2, созданном TLBIMP / VS.NET, является неправильным. Должно быть:

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

Вам нужно будет определить этот интерфейс в коде, а затем использовать его.

...