将一个位图的一部分复制到ImageList中
Copy part of one bitmap into an ImageList
快速背景:我有一个TreeView,我使用Windows API调用在c++中创建的(Visual Studio 2008,虽然这不应该有什么区别):
hTreeview = CreateWindowEx(0, WC_TREEVIEW, L"My Treeview", WS_CHILD | WS_VISIBLE | TVS_INFOTIP | TVS_NOHSCROLL | TVS_SHOWSELALWAYS | TVS_EDITLABELS | TVS_SINGLEEXPAND, m_tx, m_ty, m_tw, m_th, hWindow, (HMENU)2, hInstance, NULL);
我已经成功分配了一个ImageList给它使用:
m_hImageList = ImageList_Create(cx, cy, ILC_COLOR24, n, n);
TreeView_SetImageList(hTreeview, m_hImageList, TVSIL_NORMAL);
,其中cx
, cy
, n
均指定(在本例中分别为18,18,5)。这一切都很好,正如我所看到的,因为现在在我的项目旁边为图像留出了空间。
我想要完成的是复制另一个位图的子部分(从文件)。我尝试过的代码(但不起作用)是这样的:
HBITMAP hSkin = (HBITMAP)LoadImage(NULL, szPathBmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
for (long i = 0; i < n; i++)
{
HDC dcDest = CreateCompatibleDC(NULL);
HBITMAP hIcon = CreateCompatibleBitmap(dcDest, cx, cy);
HDC dcSrc = CreateCompatibleDC(NULL);
SelectObject(dcSrc, hSkin);
BitBlt(dcDest, 0, 0, cx, cy, dcSrc, x, y, SRCCOPY);
*pIcon = ImageList_Add(m_hImageList, hIcon, NULL);
DeleteObject(hIcon);
DeleteDC(dcSrc);
DeleteDC(dcDest);
}
DeleteObject(hSkin);
为简洁起见,我省略了错误检查代码,可以假设所有列出的变量都已在程序的其他地方设置(请原谅我没有提供工作源文件,但这是一个非常大的项目,我试图只包括相关的部分)。
我在Treeview中得到的都是黑色的方块(这恰好是Treeview的背景色),所以我假设最后一段代码出了问题——加载皮肤并试图将它的一部分BitBlt成一个新的位图以保存到ImageList。谁能告诉我我做错了什么,或者告诉我一个更好的方法来完成我正在努力做的事情?
我只使用c++和Windows API, 没有。net, MFC或Windows窗体设计器。
提前感谢你的帮助,如果我遗漏了什么,我道歉;
你的代码有几个问题。
首先,当您创建一个新的DC时,它以单色位图开始,因此您的CreateCompatibleBitmap
调用也将产生一个单色位图。相反,您可能希望基于窗口或屏幕DC创建位图。
其次,你从来没有实际选择位图到dcDest
,所以没有任何东西会被绘制到hIcon
。
第三,如果位图当前被选中到设备上下文中,ImageList_Add
将失败,因此在将图标添加到图像列表之前,必须从dcDest
中取消选择hIcon
。
最后,您还忽略了保存原始位图并恢复它们,因此这也将导致GDI泄漏。
试试这样写:
HDC hdcWindow = GetDC(hWnd);
HDC dcDest = CreateCompatibleDC(hDCWindow);
HBITMAP hIcon = CreateCompatibleBitmap(hDCWindow, cx, cy);
HDC dcSrc = CreateCompatibleDC(NULL);
HGDIOBJ hOldSourceBmp = SelectObject(dcSrc, hSkin);
HGDIOBJ hOldDestBmp = SelectObject(dcDest, hIcon);
BitBlt(dcDest, 0, 0, cx, cy, dcSrc, x, y, SRCCOPY);
SelectObject(dcDest, hOldDestBmp);
SelectObject(dcSrc, hOldSourceBmp);
*pIcon = ImageList_Add(m_hImageList, hIcon, NULL);
DeleteObject(hIcon);
DeleteDC(dcSrc);
DeleteDC(dcDest);
ReleaseDC(hWnd, hDCWindow);
- 复制矩阵的一部分并粘贴到另一个矩阵C++上
- C++向量的哪一部分在传递给函数时被复制
- 复制 Simd::View 的一部分
- 如何在不复制的情况下比较字符串的一部分?
- C 如何将二进制文件的一部分复制到新文件
- 使用 C++98 将矢量的一部分移动(而不是复制)到另一个矢量
- 如果将一个值复制到另一部分
- C++将 2D 阵列的一部分复制到另一个 2D 阵列,性能
- MFC 将屏幕的一部分复制到 CBitmap 中
- C++将字符数组的一部分复制到另一个字符数组
- 如何在 c++ 中将一个向量的一部分复制到另一个向量
- 复制存储在内存映射文件中的数组的一部分
- 复制结构的一部分
- 如何将此INT数组的一部分复制到C 中的另一个数组
- 只手动定义复制构造函数和赋值运算符的一部分
- 将std::字符串的一部分复制到另一个未初始化的字符串
- 将二维的一部分复制到自身上
- 将二维数组的 1 维复制到同一数组的另一部分
- 如何在不复制的情况下将 std::string 的一部分放入 streambuf 中
- 如何在不复制的情况下将只读向量传递给作为<int> pair<int,int>向量一部分的函数