Я могу создать массив Uint8 в окне IWebbrowser2:
IHTMLWindow2 window = ...;
DISPID dispid_uint8array = ...;
VARIANT self;
self.vt = VT_NULL;
VARIANT length;
length.vt = VT_I4;
length.lVal = 100;
VARIANT args[2] = { self, length };
DISPID named_args[1] = { DISPID_THIS };
DISPPARAMS params;
params.rgvarg = args;
params.rgdispidNamedArgs = named_args;
params.cArgs = 2;
params.cNamedArgs = 1;
VARIANT result;
result.vt = VT_EMPTY;
HRESULT hr = container->Invoke(
dispid_uint8array, IID_NULL, LOCALE_USER_DEFAULT,
DISPATCH_METHOD, ¶ms, &result, nullptr, nullptr
);
assert(hr == S_OK);
assert(result.vt == VT_DISPATCH);
IDispatch my_new_uint8array = result.pdispVal;
Теперь я могу установить элементы полей my_new_uint8array
с помощью IDispatch::Invoke(..., DISPATCH_PROPERTYPUT, ...)
в петле.
Но не существует ли надлежащего интерфейса для заполнения всего буфера одним вызовом? Например. я могу как-то получить содержащийся буфер?
Где-то есть определение интерфейса, что-то вроде IUint8Array
?
Я придумал невероятно уродливый хак: использование ArrayBuffer <canvas>
, Я буду публиковать только псевдокод, потому что полный C ++, включая проверку ошибок, распаковку и т. Д., Слишком длинный:
Прелюдия:
FEATURE_BROWSER_EMULATION
был установлен на 11001
IWebBrowser2::get_ReadyState
возвращается READYSTATE_COMPLETE
IHTMLDocument6::get_documentMode
возвращается 11
IHTMLDocument5::get_compatMode
возвращается "CSS1Compat"
IHTMLDocument2 *doc
а также IHTMLWindow2 *win
установлены.BSTR
конечно!queryInterface
один или два раза, чтобы результаты соответствовали.Как получить «Uint8Array»:
ULONG len_in_dwords = (LENGTH_I_WANT + 3) / 4;
IHTMLCanvasElement *canvas = doc->createElement("canvas");
ICanvasRenderingContext2D *context = canvas->getContext("2d");
ICanvasPixelArrayData *array_data = context->createImageData(len_in_dwords, 1);
// use this variable for interfaces that accept an ArrayBuffer
IDispatch *array_buffer = Get property "buffer" of array_data;
// use this variable to edit the content:
BYTE *byte_buffer;
ULONG buffer_length_in_bytes;
array_data->GetBufferPointer(&byte_buffer, &buffer_length_in_bytes);
// no need for that anymore:
canvas->Release();
context->Release();
array_data->Release();
ArrayBuffer array_buffer
всегда имеет размер, кратный четырем. Это работает для меня, но может не работать для других случаев использования. Ты можешь использовать array_buffer
метод slice(0, LENGTH_I_WANT)
удалить лишние байты после memcpy’ing byte_buffer
,
Других решений пока нет …