Why can't I directly send an HBIMAP from a CImage to clipboard?

浪尽此生 提交于 2020-01-25 04:25:06

问题


I'm working on a small widget, screen capture stuff on Windows.

The core of this program is like the following (I found it on the Internet). First derive from CImage, then add a member function to do this:

BOOL CScreenImage::CaptureRect(const CRect& rect)
{
    // detach and destroy the old bitmap if any attached
    CImage::Destroy();

    // create a screen and a compatible memory device context
    HDC hDCScreen = ::CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
    HDC hDCMem = ::CreateCompatibleDC(hDCScreen);
    //
    // create a bitmap compatible with the screen and select it into the memory DC
    // so you can do whatever you want on the bitmap through the mem DC.
    //
    HBITMAP hBitmap =
    ::CreateCompatibleBitmap(hDCScreen, rect.Width(), rect.Height());
    HBITMAP hBmpOld = (HBITMAP)::SelectObject(hDCMem, hBitmap);
    //
    // bit-blit from screen to memory device context
    // note: CAPTUREBLT flag is required to capture layered windows
    //
    DWORD dwRop = SRCCOPY | CAPTUREBLT;
    BOOL bRet = ::BitBlt(hDCMem, 0, 0, rect.Width(), rect.Height(),
    hDCScreen,
    rect.left, rect.top, dwRop);
    // attach bitmap handle to this object
    Attach(hBitmap);

    // restore the memory DC and perform cleanup
    ::SelectObject(hDCMem, hBmpOld);
    ::DeleteDC(hDCMem);
    ::DeleteDC(hDCScreen);

    return bRet;
}

It worked fine. And if I want to send the bitmap to clipboard, I just need to do the following:

if (::OpenClipboard(hWnd)) {
    HBITMAP hImage = Detach();
    ::EmptyClipboard();
    ::SetClipboardData(CF_BITMAP, hImage);
    ::CloseClipboard();
}

I tested it and I can use it to copy a bitmap from the program to Paint, Word, PowerPoint through the clipboard.

However, what I don't understand is that this dosen't work:

if (::OpenClipboard(this->GetSafeHwnd())) {
    CImage img;
    img.Load(_T("D:\\scc.bmp"));

    ::EmptyClipboard();
    ::SetClipboardData(CF_BITMAP, img.Detach());
    ::CloseClipboard();
}

It seems that some data was indeed sent to the clipboard, but the receiver side (like Paint) would complain "the data on the clipboard cannot be inserted".

Can anyone help? Many thanks.


回答1:


CImage* pImage = GetImage();
CDC memDC;
memDC.CreateCompatibleDC(NULL);

CBitmap bitmap;
bitmap.CreateCompatibleBitmap(GetDC(), pImage->GetWidth(), pImage->GetHeight());
memDC.SelectObject(&bitmap);
pImage->BitBlt(memDC.GetSafeHdc(), 0, 0, pImage->GetWidth(), pImage->GetHeight(), 0, 0, SRCCOPY);

EmptyClipboard();
//put the data on the clipboard
SetClipboardData(CF_BITMAP, bitmap.GetSafeHandle());
CloseClipboard();
memDC.DeleteDC();
bitmap.Detach();


来源:https://stackoverflow.com/questions/32309180/why-cant-i-directly-send-an-hbimap-from-a-cimage-to-clipboard

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!