我有一个WPF应用程序,支持从Chrome接收拖放数据。当
IDataObject
收到数据时,数据格式为“Chromium Web自定义MIME数据格式”。这是因为我使用 JavaScript 中的 dataTransfer.setData
自定义 MIME 类型。这是预期的行为。
我的问题是,这个数据的实际规格是什么?
数据是
MemoryStream
字节,我可以将其转换为 Unicode 字符串。给定 MIME 类型 application/x-myapp.document+text
和值 {F5F5A3C3-3594-430B-988F-BA1C0154201E}
,字符串将如下所示:
" \0\u0001\0#\0application/x-myapp.document+text\0&\0{F5F5A3C3-3594-430B-988F-BA1C0154201E}"
如果我用空终止符分割字符串,它将分为六个部分:
(_确定这是数据的大小(长度),而不是字符串的任何真实字符)
\u0001
(确定这是数据项的数量)
#
application/x-myapp.document+text
自定义MIME类型)
&
{F5F5A3C3-3594-430B-988F-BA1C0154201E}
自定义值)
HTML 5 Drag Data Store
,或者可能是
drag store item list
。再次,我的最后一个问题:
该数据的实际格式是什么?是 HTML 5 规范定义的数据,还是实际上是 Windows 剪贴板格式?
我也尝试过使用
BinaryReader
但没有规范,我无法以产生正确结果的方式读取数据,并且我一直在使用 HTML 5 规范(
https://html.spec.whatwg .org/multipage/dnd.html#the-drag-data-store).
阅读“Chromium Web 自定义 MIME 数据格式”:
bool ClipboardUtil::GetWebCustomData(
IDataObject* data_object, std::map<string16, string16>* custom_data) {
DCHECK(data_object && custom_data);
if (FAILED(data_object->QueryGetData(GetWebCustomDataFormat())))
return false;
STGMEDIUM store;
if (SUCCEEDED(data_object->GetData(GetWebCustomDataFormat(), &store))) {
{
base::win::ScopedHGlobal<char> data(store.hGlobal);
ReadCustomDataIntoMap(data.get(), data.Size(), custom_data);
}
ReleaseStgMedium(&store);
return true;
}
return false;
}
实际数据的解析是通过以下方法完成的:https://chromium.googlesource.com/chromium/src/+/refs/heads/main/ui/base/clipboard/custom_data_helper.cc
void ReadCustomDataIntoMap(
const void* data,
size_t data_length,
std::unordered_map<std::u16string, std::u16string>* result) {
base::Pickle pickle(reinterpret_cast<const char*>(data), data_length);
base::PickleIterator iter(pickle);
uint32_t size = 0;
if (!iter.ReadUInt32(&size))
return;
for (uint32_t i = 0; i < size; ++i) {
std::u16string type;
if (!iter.ReadString16(&type)) {
// Data is corrupt, return an empty map.
result->clear();
return;
}
auto insert_result = result->insert({type, std::u16string()});
if (!iter.ReadString16(&insert_result.first->second)) {
// Data is corrupt, return an empty map.
result->clear();
return;
}
}
}
第一个 UInt32 是键/值对的数量。 然后通过读取键名称 (String16) 和值 (String16) 循环遍历项目。
我看到这些是 GetFormats() 中的项目:
[0]: "DragContext"
[1]: "DragImageBits"
[2]: "chromium/x-renderer-taint"
[3]: "FileDrop"
[4]: "FileNameW"
[5]: "FileName"
[6]: "Chromium Web Custom MIME Data Format"
任何提示表示赞赏! 谢谢