IWebbrowser2:使用 Uint8array(不循环填充)
IWebbrowser2: Using a Uint8array (filling without looping)
我可以在 IWebbrowser2 中创建一个 Uint8array window:
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;
现在我可以在循环中使用 IDispatch::Invoke(..., DISPATCH_PROPERTYPUT, ...)
设置 my_new_uint8array
的项目字段。
但是难道没有一个合适的接口来一次调用就可以填满整个缓冲区吗?例如。我能以某种方式检索包含的缓冲区吗?
有没有接口的定义,比如IUint8Array
?
我想出了一个非常丑陋的 hack:使用 <canvas>
的 ArrayBuffer。我只会 post 伪代码,因为完整的 C++,包括错误检查、展开等,太长了:
前奏:
FEATURE_BROWSER_EMULATION
被设置为 11001
IWebBrowser2::get_ReadyState
returns READYSTATE_COMPLETE
IHTMLDocument6::get_documentMode
returns 11
IHTMLDocument5::get_compatMode
returns "CSS1Compat"
IHTMLDocument2 *doc
和 IHTMLWindow2 *win
已设置。
- 我在我的伪代码中使用简单的字符串,但你当然必须使用
BSTR
s!
- 您可能需要
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
.
之后删除多余的字节
我可以在 IWebbrowser2 中创建一个 Uint8array window:
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;
现在我可以在循环中使用 IDispatch::Invoke(..., DISPATCH_PROPERTYPUT, ...)
设置 my_new_uint8array
的项目字段。
但是难道没有一个合适的接口来一次调用就可以填满整个缓冲区吗?例如。我能以某种方式检索包含的缓冲区吗?
有没有接口的定义,比如IUint8Array
?
我想出了一个非常丑陋的 hack:使用 <canvas>
的 ArrayBuffer。我只会 post 伪代码,因为完整的 C++,包括错误检查、展开等,太长了:
前奏:
FEATURE_BROWSER_EMULATION
被设置为11001
IWebBrowser2::get_ReadyState
returnsREADYSTATE_COMPLETE
IHTMLDocument6::get_documentMode
returns11
IHTMLDocument5::get_compatMode
returns"CSS1Compat"
IHTMLDocument2 *doc
和IHTMLWindow2 *win
已设置。- 我在我的伪代码中使用简单的字符串,但你当然必须使用
BSTR
s! - 您可能需要
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
.