快速背景:我有一个使用C ++中的Windows API调用创建的TreeView(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的背景颜色),所以我假设最后一段代码出错了 - 加载皮肤并尝试将BitBlt的一部分转换为新的位图以保存到ImageList。任何人都可以告诉我我做错了什么,或者告诉我一个更好的方法来完成我想要做的事情?
我独家使用C ++和Windows API,没有.NET,MFC或Windows窗体设计器。
先谢谢你的帮助,如果我遗漏了任何东西,我会道歉;这是我的第一篇帖子。
答案 0 :(得分:1)
您的代码存在一些问题。
首先,当您创建一个新DC时,它会以单色位图开头,因此您的CreateCompatibleBitmap
调用也会生成单色位图。相反,您可能希望根据窗口或屏幕DC创建位图。
其次,您实际上从未将位图选择为dcDest
,因此无论如何都不会将任何内容绘制到hIcon
中。
第三,如果当前将位图选入设备上下文,ImageList_Add
将失败,因此在将图标添加到图像列表之前,必须从hIcon
取消选择dcDest
。< / p>
最后,您也忽略了保存原始位图并恢复它们,因此这也会导致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);