2017-08-24 81 views
1

我可以在一个窗口的IWebBrowser2创建Uint8array:的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; 

现在我可以在循环中使用IDispatch::Invoke(..., DISPATCH_PROPERTYPUT, ...)设置的my_new_uint8array项目领域。

但是,是不是有一个适当的接口来填充整个缓冲区只有一个电话?例如。我可以以某种方式检索包含的缓冲区?

有没有界面的定义,像IUint8Array

+0

这些数组不是更多javascript(查克拉)的东西? https://docs.microsoft.com/en-us/scripting/chakra-hosting/jscreatetypedarray-function我很好奇,你怎么得到dispid_uint8array在第一位? –

+0

@SimonMourier,我只是使用'window-> GetIDsOfNames(...)'提供''Uint8Array“'。 – kay

+0

你有任何机会准备好复制项目吗? –

回答

1

我想出了一个令人难以置信的丑陋的黑客:使用ArrayBuffer的<canvas>。我将只发布的伪代码,因为完整的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'ing后的额外字节为byte_buffer