首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用WIC读取剪贴板

用WIC读取剪贴板
EN

Stack Overflow用户
提问于 2017-03-25 21:25:34
回答 1查看 285关注 0票数 0

我正在尝试编写一个函数来读取复制到带有Windows映像组件的剪贴板上的图像。目前,我的代码基于加载资源的方式,但修改后可以使用剪贴板。初始化流之前的所有操作都很好,但是一旦我尝试使用CreateDecoderFromeStream,它就失败了。我试过从许多地方复制图像,但都没有效果。复制的图像格式有什么不同,不能被WIC读取吗?

下面是我的代码..。

创建要从剪贴板读取的内存对象

代码语言:javascript
复制
COMStreamSPtr WIC::createStreamFromClipboard() {
    IStream* ipStream = NULL;
    COMStreamSPtr stream = nullptr;
    CoInitialize(nullptr);
    if (!IsClipboardFormatAvailable(CF_BITMAP) && !IsClipboardFormatAvailable(CF_DIB) && !IsClipboardFormatAvailable(CF_DIBV5))
        goto Return;

    if (!OpenClipboard(NULL))
        goto Return;

    // Load the clipboard
    HGLOBAL hMem = GetClipboardData(CF_BITMAP);
    if (hMem == NULL || hMem == INVALID_HANDLE_VALUE)
        hMem = GetClipboardData(CF_DIB);
    if (hMem == NULL || hMem == INVALID_HANDLE_VALUE)
        hMem = GetClipboardData(CF_DIBV5);
    if (hMem == NULL || hMem == INVALID_HANDLE_VALUE)
        goto CloseClipboard;

    // Lock the clipboard, getting a pointer to its data
    LPVOID pvSourceClipboardData = GlobalLock(hMem);
    if (pvSourceClipboardData == NULL)
        goto CloseClipboard;

    // Read the clipboard data size
    DWORD dwClipboardSize = GlobalSize(hMem);
    if (dwClipboardSize == 0)
        goto GlobalUnlock;

    // Allocate memory to hold the clipboard data
    HGLOBAL hgblClipboardData = GlobalAlloc(GMEM_MOVEABLE, dwClipboardSize);
    if (hgblClipboardData == NULL)
        goto GlobalUnlock;

    // Get a pointer to the allocated memory
    LPVOID pvClipboardData = GlobalLock(hgblClipboardData);
    if (pvClipboardData == NULL)
        goto FreeData;

    // Copy the data from the clipboard to the new memory block
    CopyMemory(pvClipboardData, pvSourceClipboardData, dwClipboardSize);
    GlobalUnlock(hgblClipboardData);

    // Create a stream on the HGLOBAL containing the data
    if (SUCCEEDED(CreateStreamOnHGlobal(hgblClipboardData, TRUE, &ipStream))) {
        stream = std::make_shared<COMStream>(ipStream);
        goto CloseClipboard;
    }

FreeData:
    // Couldn't create stream; free the memory
    GlobalFree(hgblClipboardData);
GlobalUnlock:
    // Unlock the clipboard data
    GlobalUnlock(hMem);
CloseClipboard:
    // Close the clipboard
    CloseClipboard();
Return:
    // No need to unlock or free the resource
    CoUninitialize(); // CoInialize is called by my COMObjects in the constructor so this is just decrementing the count.
    return stream;
}

在代码的其他地方使用返回的流。

代码语言:javascript
复制
WICBitmapDecoderSPtr WIC::createDecoderFromStream(COMStreamSPtr stream) {
    if (isCOMObjectNull(stream))
        return nullptr;

    IWICImagingFactory* ipFactory = NULL;
    IWICBitmapDecoder* ipDecoder = NULL;
    WICBitmapDecoderSPtr decoder = nullptr;

    // Create the factory
    if (FAILED(CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&ipFactory))))
        goto Return;

    // Create the decoder
    if (FAILED(ipFactory->CreateDecoderFromStream(stream->ipObject, NULL, WICDecodeMetadataCacheOnDemand, &ipDecoder)))
        goto ReleaseFactory; // FAILS HERE

    decoder = std::make_shared<WICBitmapDecoder>(ipDecoder);
ReleaseFactory:
    ipFactory->Release();
Return:
    return decoder;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-28 20:51:22

我终于想出了怎么做。我所做的就是使用IWICImagingFactoryCreateBitmapFromHBITMAP函数,因为从剪贴板上读取HBITMAP非常简单,所以解决方案就变得非常直接。

代码语言:javascript
复制
IWICBitmapSource* WIC::readSourceFromClipboard() {
    IWICBitmapSource* ipSource = NULL;
    if (Clipboard::containsFormat(CF_BITMAP)) {
        if (OpenClipboard(NULL)) {
            HBITMAP hBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);
            ipSource = createSourceFromHBitmap(hBitmap);
            CloseClipboard();
        }
    }
    return ipSource;
}

IWICBitmapSource* WIC::createSourceFromHBitmap(HBITMAP hBitmap) {
    if (hBitmap == NULL)
        return NULL;

    IWICImagingFactory* ipFactory = NULL;
    IWICBitmap* ipBitmap = NULL;

    CoInitialize(NULL);

    // Create the factory
    if (FAILED(CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&ipFactory))))
        goto Return;

    // Create the bitmap
    if (FAILED(ipFactory->CreateBitmapFromHBITMAP(hBitmap, NULL, WICBitmapIgnoreAlpha, &ipBitmap)))
        goto ReleaseFactory;

ReleaseFactory:
    ipFactory->Release();
Return:
    CoUninitialize();
    return ipBitmap;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43022143

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档