CListCtrl с доступом CImageList к HBITMAP для модификации

У меня есть CListCtrl, содержащий CImageList, поэтому я могу отображать HBITMAP в своем списке (просто цветной прямоугольник). Я хочу иметь возможность заменить цвет. Например, если я выберу какой-либо цвет в списке, а затем нажму заменить, цвет будет изменен. Я использую следующий код:

   int nItem = 0;
   list<CustomColor>::iterator listCopyIter = pListCopy->begin();
   while( nItem<pListCtrl->GetItemCount() && listCopyIter!=pListCopy->end() )
   {
      if (pListCtrl->GetItemState(nItem, LVIS_SELECTED) == LVIS_SELECTED)
      {
         HBITMAP hBitmap = CreateBitmap(); //Just some function I use

         //IMAGEINFO* pItmData = (IMAGEINFO*)pListCtrl->GetItemData(nItem);
         //pItmData->hbmImage = hBitmap;
         //pListCtrl->SetItemData(nItem, (DWORD_PTR)pItmData);
         pImageList->Replace(nItem, CBitmap::FromHandle(hBitmap), RGB(0,0,0));
         *listCopyIter = color;
         return;
      }
      else
      {
         nItem++;
         listCopyIter++;
      }
   }

Где pListCopy — мой std::list‹ CustomColor >*, pListCtrl — мой CListCtrl*, а pImageList — мой ImageList*.

Проблема в том, что иногда мой CListCtrl не использует ту же позицию, что и ImageList (например, элемент в CListCtrl pos 3 может использовать изображение в ImageList pos 6). В этом случае замененный HBITMAP неверен. Вот почему я попробовал код в комментариях: попытался получить ItemData, привести его к IMAGEINFO, изменить значение HBITMAP и затем установить его обратно. Но это дает мне нарушение прав доступа к записи...

Что я упускаю из виду? Есть ли способ напрямую изменить HBITMAP? Я знаю, что всегда могу получить каждое значение HBITMAP из ImageList и переместить их так, чтобы они синхронизировались с CListCtrl, но это было бы не очень эффективно и довольно некрасиво.


person Papsicle    schedule 19.06.2014    source источник


Ответы (1)


Проблема была в том, что я неправильно использовал GetItemData. GetItemData возвращает DWORD_PTR (32-битное значение). И я никогда раньше не использовал SetItemData. Теперь при создании элемента я использую это:

int nItemPos = pListCtrl->InsertItem(pos, string, imgpos);
pListCtrl->SetItemData(nItemPos, imgpos);

А затем в моей другой функции я просто привожу GetItemData к int, чтобы получить позицию изображения, например:

int pItmPos = (int)pListCtrl->GetItemData(nItem);
pImageList->Replace(pItmPos, CBitmap::FromHandle(hBitmap), RGB(0,0,0));
pListCtrl->RedrawItems(nItem, nItem);
person Papsicle    schedule 19.06.2014