复制本地图片到剪切板

529 阅读1分钟

需求

在程序中右键复制一张本地图片到剪切板中,供其他软件粘贴使用

坑点

本来这个功能很简单,百度一搜一大堆,但是在实际中出现了不少问题
如果直接读取文件,获取hbitmap,在word和ppt中粘贴时没有任何问题,但是到了excel中,就会出现无法显示图片的问题。

解决方案

暂时不知道excel中是具体解析了参数导致无法展示图片,所以现在的做法是直接讲获取到的hbitmap,再重新绘制一遍,获取到一套新的数据,再将新的数据放到剪切板中,实测是没有问题。
获取hbitmap可以通过CImage,也可以通过Gdiplus::Bitmap::FromFile获取。

代码实现

CImage image;
image.Load(path.c_str());
const int width = image.GetWidth();
const int height = image.GetHeight();
const auto bitmap = image.Detach();
// 重绘获取新的hbitmap
const HDC hScrDC = GetDC(nullptr);
const HDC hScrDC2 = CreateCompatibleDC(hScrDC);
const HDC hMemDC = CreateCompatibleDC(hScrDC);
SelectObject(hScrDC2, bitmap);
auto hBitmap = CreateCompatibleBitmap(hScrDC, width, height);
const auto hOldBitmap2 = static_cast<HBITMAP>(SelectObject(hMemDC, hBitmap));
BitBlt(hMemDC, 0, 0, width, height, hScrDC2, 0, 0, SRCCOPY);
hBitmap = static_cast<HBITMAP>(SelectObject(hMemDC, hOldBitmap2));
DeleteDC(hScrDC);
DeleteDC(hScrDC2);
DeleteDC(hMemDC);
DeleteObject(hOldBitmap2);
THDROP_Files fileList;
fileList.push_back(path);
const auto hmem = fileList.Create_HDROP();
if (OpenClipboard(nullptr)) {
	EmptyClipboard();
	SetClipboardData(CF_HDROP, hmem);
	SetClipboardData(CF_BITMAP, hBitmap);
	CloseClipboard();
}
GlobalUnlock(hmem);
DeleteObject(hBitmap);