如何将保存到“.BMP”文件的缓冲区复制到使用win32 API的剪贴板? 也就是说,我有一个Windows V3位图的原始缓冲区(包括标题),我可以从字面上write()到一个文件,并将导致一个有效的.BMP文件,但我想将其复制到剪贴板。
在OS X上,在普通的C中,代码看起来像这样(按预期工作):
#include <applicationservices/applicationservices.h> int copyBitmapToClipboard(char *bitmapBuffer,size_t buflen) { PasteboardRef clipboard; CFDataRef data; if (PasteboardCreate(kPasteboardClipboard,&clipboard) != noErr) { return PASTE_OPEN_ERROR; } if (PasteboardClear(clipboard) != noErr) return PASTE_CLEAR_ERROR; data = CFDataCreateWithBytesNocopy(kcfAllocatorDefault,bitmapBuffer,buflen,kcfAllocatorNull); if (data == NULL) { CFRelease(clipboard); return PASTE_DATA_ERROR; } if (PasteboardPutItemFlavor(clipboard,42,kUTTypeBMP,data,0) != noErr) { CFRelease(data); CFRelease(clipboard); return PASTE_PASTE_ERROR; } CFRelease(data); CFRelease(clipboard); return PASTE_WE_DID_IT_YAY; }
我不确定如何使用win32 API完成此操作。 这就像我已经得到,但它似乎沉默地失败(即,该函数返回一个成功的错误代码,但是当试图粘贴,菜单项被禁用)。
#include <windows/windows.h> int copyBitmapToClipboard(char *bitmapBuffer,size_t buflen) { if (!OpenClipboard(NULL)) return PASTE_OPEN_ERROR; if (!EmptyClipboard()) return PASTE_CLEAR_ERROR; if (SetClipboardData(CF_DSPBITMAP,bitmapBuffer) == NULL) { CloseClipboard(); return PASTE_PASTE_ERROR; } CloseClipboard(); return PASTE_WE_DID_IT_YAY; }
任何人都可以提供一些见解,如何解决这个问题?
从Windows剪贴板获取32位RGBA图像
如何从Windows剪贴板中读取位图
Win32 C / C ++从内存缓冲区加载映像
在bitmap.h中,为什么bitmap_zero需要memset?
GDI GradientFill不能在离屏位图上工作
编辑
按照Aaron和martinr的build议,我现在修改了以下代码:
#include <windows/windows.h> int copyBitmapToClipboard(char *bitmapBuffer,size_t buflen) { HGLOBAL hResult; if (!OpenClipboard(NULL)) return PASTE_OPEN_ERROR; if (!EmptyClipboard()) return PASTE_CLEAR_ERROR; hResult = GlobalAlloc(GMEM_MOVEABLE,buflen); if (hResult == NULL) return PASTE_DATA_ERROR; memcpy(GlobalLock(hResult),buflen); GlobalUnlock(hResult); if (SetClipboardData(CF_DSPBITMAP,hResult) == NULL) { CloseClipboard(); return PASTE_PASTE_ERROR; } CloseClipboard(); return PASTE_WE_DID_IT_YAY; }
但它仍然有同样的结果。 我究竟做错了什么?
最终编辑
工作代码:
#include <windows/windows.h> int copyBitmapToClipboard(char *bitmapBuffer,size_t buflen) { HGLOBAL hResult; if (!OpenClipboard(NULL)) return PASTE_OPEN_ERROR; if (!EmptyClipboard()) return PASTE_CLEAR_ERROR; buflen -= sizeof(BITMAPFILEHEADER); hResult = GlobalAlloc(GMEM_MOVEABLE,bitmapBuffer + sizeof(BITMAPFILEHEADER),buflen); GlobalUnlock(hResult); if (SetClipboardData(CF_DIB,hResult) == NULL) { CloseClipboard(); return PASTE_PASTE_ERROR; } CloseClipboard(); GlobalFree(hResult); return PASTE_WE_DID_IT_YAY; }
谢谢,马丁!
Windows CF_DIB到剪贴板中的CF_BITMAP
将位图转换为字节数组
WindowsImagingComponent或System.Windows.Media.Imaging
如何直接在Windows中分配video卡内存?
我认为hMem需要是LocalAlloc的一个返回值,一个HMEMORY而不是一个指针。
编辑
对不起,是的,GlobalAlloc与GMEM_MOVEABLE是必需的,而不是LocalAlloc。
编辑
我建议你使用CF_DIB剪贴板数据格式类型。
除了没有BITMAPFILEHEADER之外,DIB与BMP相同,因此除了第一个sizeof(BITMAPFILEHEADER)字节之外,复制源字节。
编辑
从OpenClipboard()文档( http://msdn.microsoft.com/en-us/library/ms649048(VS.85).aspx ):
“如果应用程序调用OpenLipboard与hwnd设置为NULL,EmptyClipboard将剪贴板所有者设置为NULL;这将导致SetClipboardData失败。
你需要设置一个窗口; 即使你没有做WM_RENDERFORMAT类型的东西。
我发现Windows API很多。 我没有使用剪贴板API本身,但与其他API我通常发现,创建一个隐藏的窗口,并将该句柄传递给相关的API足以保持安静。 如果你是从DLL而不是EXE创建一个窗口的话,通常会有一些关于这个问题的注释。 阅读关于DLL,消息循环和窗口创建的最新微软词汇。
至于BITMAPINFO ,这不是剪贴板想要看到的流的开始部分: – 你给SetClipboardData的缓冲区应该在BITMAPFILEHEADER停止之后开始。
你需要传递一个句柄给SetClipboard()(即 – 分配给GlobalAlloc()的内存),而不是传递一个直接的指针到你的位图。
回声亚伦和马丁。 这里举例,关键部分:
// Allocate a global memory object for the text. hglbcopy = GlobalAlloc(GMEM_MOVEABLE,(cch + 1) * sizeof(TCHAR)); if (hglbcopy == NULL) { CloseClipboard(); return FALSE; } // Lock the handle and copy the text to the buffer. lptstrcopy = GlobalLock(hglbcopy); memcpy(lptstrcopy,&pBox->atchLabel[ich1],cch * sizeof(TCHAR)); lptstrcopy[cch] = (TCHAR) 0; // null character GlobalUnlock(hglbcopy); // Place the handle on the clipboard. SetClipboardData(CF_TEXT,hglbcopy);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。