为什么我不能直接从CImage发送HBIMAP到剪贴板?

时间:2015-08-31 10:29:33

标签: winapi mfc

我正在研究Windows上的一个小小部件,屏幕截图。

该计划的核心如下(我在互联网上找到了它)。首先从CImage派生,然后添加一个成员函数来执行此操作:

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;
}

工作得很好。如果我想将位图发送到剪贴板,我只需要执行以下操作:

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

我测试了它,我可以用它将程序中的位图复制到Paint,Word,PowerPoint到剪贴板。

然而,我不明白的是,这不起作用:

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

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

似乎有些数据确实已发送到剪贴板,但接收方(如Paint)会抱怨“无法插入剪贴板上的数据”。

有人可以帮忙吗?非常感谢。

1 个答案:

答案 0 :(得分:0)

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();