首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将GDI+位图放在剪贴板上?

如何将GDI+位图放在剪贴板上?
EN

Stack Overflow用户
提问于 2016-02-02 13:32:50
回答 1查看 1.5K关注 0票数 2

我想把一个GDI+ Bitmap放在剪贴板上。显而易见的办法是:

所以我尝试了伪码

代码语言:javascript
复制
void PlaceBitmapOnClipboard(Bitmap image)
{
   //Convert GDI+ Bitmap to GDI Bitmap
   HBITMAP bmp;
   image.GetHBITMAP(0, @bmp);

   OpenClipboard(this.Handle);
      EmptyClipboard();
      SetClipboardData(CF_BITMAP, bmp);
   CloseClipboard();
}

为了说明起见,省略了错误检查;但没有一项功能失败:

  • GetHBITMAP及其HRESULT样式错误
  • SetClipboardData也不返回null

但是,当我试图在剪贴板上使用CF_BITMAP时,它不能粘贴到油漆中:

那么,填充函数的正确代码是什么:

代码语言:javascript
复制
void PlaceBitmapOnClipboard(Bitmap image)
{
   //TODO: Ask Stackoverflow to figure this out

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-02 17:46:59

我们需要打电话:

SetClipboardData(CF_BITMAP, hbitmap_ddb)

其中hbitmap_ddb必须是兼容位图,而不是从Gdiplus::GetHBitmap获得的DIB。

或者我们叫:

SetClipboardData(CF_DIB, hmemory)

其中hmemory不是HBITMAPhmemory文档中描述为:

一种内存对象,包含一个BITMAPINFO结构,后面跟着位图位。

使用CF_BITMAP示例

使用CreateDIBitmap创建基于DIB位图的兼容位图。然后使用新的DDB位图调用SetClipboardData

代码语言:javascript
复制
Gdiplus::Bitmap gdibmp(L"file.bmp");
if(gdibmp.GetLastStatus() != Gdiplus::Ok)
    return;
HBITMAP hbitmap;
auto status = gdibmp.GetHBITMAP(0, &hbitmap);
if(status != Gdiplus::Ok)
    return;
BITMAP bm;
GetObject(hbitmap, sizeof bm, &bm);
DIBSECTION ds;
if(sizeof ds == GetObject(hbitmap, sizeof ds, &ds))
{
    HDC hdc = GetDC(NULL);
    HBITMAP hbitmap_ddb = CreateDIBitmap(hdc, &ds.dsBmih, CBM_INIT,
        ds.dsBm.bmBits, (BITMAPINFO*)&ds.dsBmih, DIB_RGB_COLORS);
    ReleaseDC(NULL, hdc);
    if(OpenClipboard(hwnd))
    {
        EmptyClipboard();
        SetClipboardData(CF_BITMAP, hbitmap_ddb);
        CloseClipboard();
    }
    DeleteObject(hbitmap_ddb);
}
DeleteObject(hbitmap);

使用CF_DIB的示例

使用GlobalAlloc分配内存,并将BITMAPINFOHEADER复制到该内存,然后是位。没有必要担心颜色表,因为Gdiplus::HBitmap返回32位位图(据我所知,至少在现代显示上是这样)。

代码语言:javascript
复制
Gdiplus::Bitmap gdibmp(L"file.bmp");
if(gdibmp.GetLastStatus() != Gdiplus::Ok)
    return;

HBITMAP hbitmap;
auto status = gdibmp.GetHBITMAP(NULL, &hbitmap);
if(status != Gdiplus::Ok)
    return;
BITMAP bm;
GetObject(hbitmap, sizeof bm, &bm);

BITMAPINFOHEADER bi =
{ sizeof bi, bm.bmWidth, bm.bmHeight, 1, bm.bmBitsPixel, BI_RGB };

std::vector<BYTE> vec(bm.bmWidthBytes * bm.bmHeight);
auto hdc = GetDC(NULL);
GetDIBits(hdc, hbitmap, 0, bi.biHeight, vec.data(), (BITMAPINFO*)&bi, 0);
ReleaseDC(NULL, hdc);

auto hmem = GlobalAlloc(GMEM_MOVEABLE, sizeof bi + vec.size());
auto buffer = (BYTE*)GlobalLock(hmem);
memcpy(buffer, &bi, sizeof bi);
memcpy(buffer + sizeof bi, vec.data(), vec.size());
GlobalUnlock(hmem);

if(OpenClipboard(hwnd))
{
    EmptyClipboard();
    SetClipboardData(CF_DIB, hmem);
    CloseClipboard();
}
DeleteObject(hbitmap);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35154938

复制
相关文章

相似问题

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