I'm working on a C++ app and I need to be able to add a bitmap to the Windows Runtime clipboard. My options were to use WRL or WinRT, so I chose WRL as it seemed to have (slightly) more documentation. After a bit of fiddling I had some code to add text to the clipboard:
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());
Adding a bitmap proved to be much harder, however. I spend a lot of time looking at source code, reading docs and writing test code, and eventually ended up with the following (note I read a BMP file from HD for testing purposes):
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();
All the WRL functions return S_OK but nothing actually appears in the clipboard. I do get an exception when the IRandomAccessStreamReference goes out of scope, so that might be a clue.
Any clues as to what I'm doing wrong? This is my first experience with Windows Runtime and to be honest I'm finding it very frustrating to work with.