Скопировать часть одного растрового изображения в 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);

Я упустил код проверки ошибок для краткости, и можно предположить, что все перечисленные переменные были установлены где-то еще в программе (простите, что я не предоставляю рабочий исходный файл, но это очень большой проект, и я попытался включить только те части, которые имеют отношение к делу).

Все, что я получаю в древовидном представлении, это черные квадраты (цвет фона древовидного представления), поэтому я предполагаю, что что-то не так с последним блоком кода — тем, который загружает скин и пытается BitBlt a часть его в новое растровое изображение для сохранения в ImageList. Может ли кто-нибудь сказать мне, что я делаю неправильно, или предложить мне лучший способ выполнить то, что я пытаюсь сделать?

Я использую C ++ и Windows API исключительно, нет .NET, MFC или Windows Form Designer.

Заранее благодарю за помощь, и если я что-то пропустил, прошу прощения; это один из моих первых постов.

1

Решение

Есть несколько проблем с вашим кодом.

Во-первых, когда вы создаете новый DC, он начинается с монохромного растрового изображения, поэтому ваш CreateCompatibleBitmap вызов также будет производить монохромный. Вместо этого вы, вероятно, хотите создать растровое изображение на основе окна или экрана DC.

Во-вторых, вы никогда не выбираете растровое изображение в dcDestтак что ничто не будет втянуто в hIcon тем не мение.

В-третьих, ImageList_Add потерпит неудачу, если растровое изображение в данный момент выбрано в контексте устройства, поэтому необходимо отменить выбор hIcon от dcDest прежде чем добавить значок в список изображений.

Наконец, вы также пренебрегаете сохранением исходных растровых изображений и их восстановлением, поэтому это также приведет к утечке 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);
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]