IWebbrowser2:使用Uint8array(填充而不循环)

时间:2017-08-24 15:37:10

标签: c++ windows com arraybuffer iwebbrowser2

我可以在IWebbrowser2窗口中创建一个Uint8array:

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, &params, &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

1 个答案:

答案 0 :(得分:1)

我想出了一个令人难以置信的丑陋黑客:使用<canvas>的ArrayBuffer。我只发布伪代码,因为完整的C ++,包括错误检查,解包等等,太长了:

<强>前奏:

  • FEATURE_BROWSER_EMULATION设置为11001
  • IWebBrowser2::get_ReadyState返回READYSTATE_COMPLETE
  • IHTMLDocument6::get_documentMode返回11
  • IHTMLDocument5::get_compatMode返回"CSS1Compat"
  • IHTMLDocument2 *docIHTMLWindow2 *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的大小始终为4。这对我有用,但可能不适用于其他用例。您可以使用array_buffer的方法slice(0, LENGTH_I_WANT)删除memcpy到byte_buffer后的额外字节。