我正在开发一个 C++ 应用程序,我需要能够将位图添加到 Windows 运行时剪贴板。我的选择是使用 WRL 或 WinRT,所以我选择了 WRL,因为它似乎有(稍微)更多的文档。经过一番摆弄,我有一些代码可以将文本添加到剪贴板:
RoInitializeWrapper initialise(RO_INIT_SINGLETHREADED);
if (FAILED(initialise))
{
return 1;
}
ComPtr<IClipboardStatics> clipboard;
HRESULT hr2 = GetActivationFactory(HStringReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_Clipboard).Get(), &clipboard);
ComPtr<IDataPackage> dataPackage;
hr2 = ActivateInstance(HStringReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_DataPackage).Get(), &dataPackage);
hr2 = dataPackage.Get()->SetText(HStringReference(L"Testing 1 2 3 4").Get());
hr2 = clipboard.Get()->SetContent(dataPackage.Get());
然而,事实证明添加位图要困难得多。我花了很多时间查看源代码、阅读文档和编写测试代码,最终得到以下结果(注意我从 HD 中读取了一个 BMP 文件用于测试目的):
HRESULT hr2;
ComPtr<IDataWriter> imageDataWriter;
ComPtr<IRandomAccessStream> imageStream;
ComPtr<IRandomAccessStreamReference> imageStreamReference;
RoInitializeWrapper initialise(RO_INIT_SINGLETHREADED);
if (FAILED(initialise))
{
return 1;
}
hr2 = ActivateInstance(HStringReference(RuntimeClass_Windows_Storage_Streams_InMemoryRandomAccessStream).Get(), imageStream.GetAddressOf());
ComPtr<IOutputStream> outputStream;
hr2 = imageStream.As(&outputStream);
ComPtr<IDataWriterFactory> dataWriterFactory;
hr2 = GetActivationFactory(HStringReference(RuntimeClass_Windows_Storage_Streams_DataWriter).Get(), dataWriterFactory.GetAddressOf());
hr2 = dataWriterFactory->CreateDataWriter(outputStream.Get(), imageDataWriter.GetAddressOf());
BYTE* data = nullptr;
std::streampos size;
std::ifstream in(L"c:\\temp\\background.bmp", std::ios::in|std::ios::binary|std::ios::ate);
if (in.is_open())
{
size = in.tellg();
data = new BYTE[size];
in.seekg(0, std::ios::beg);
in.read((char*) data, size);
in.close();
}
hr2 = imageDataWriter->WriteBytes(size, data);
ComPtr<IDataPackage> dataPackage;
hr2 = ActivateInstance(HStringReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_DataPackage).Get(), &dataPackage);
ComPtr<IRandomAccessStreamReferenceStatics> streamRefFactory;
hr2 = GetActivationFactory(HStringReference(RuntimeClass_Windows_Storage_Streams_RandomAccessStreamReference).Get(), streamRefFactory.GetAddressOf());
hr2 = streamRefFactory->CreateFromStream(imageStream.Get(), imageStreamReference.GetAddressOf());
hr2 = dataPackage.Get()->SetBitmap(imageStreamReference.Get());
hr2 = dataPackage->put_RequestedOperation(DataPackageOperation::DataPackageOperation_Copy);
ComPtr<IClipboardStatics> clipboard;
hr2 = GetActivationFactory(HStringReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_Clipboard).Get(), &clipboard);
hr2 = clipboard.Get()->SetContent(dataPackage.Get());
clipboard->Flush();
所有 WRL 函数都返回 S_OK 但剪贴板中实际上没有出现任何内容。当 IRandomAccessStreamReference 超出范围时,我确实得到了一个异常,所以这可能是一个线索。
关于我做错了什么的任何线索?这是我第一次使用 Windows 运行时,老实说,我发现使用它非常令人沮丧。