Papsicle
Papsicle

Reputation: 147

CListCtrl with CImageList access HBITMAP for modification

I have a CListCtrl containing a CImageList so I can show HBITMAPs in my list (just plain color rectangle). I want to be able to replace a color. For exemple, if I select some color in the list, then hit replace, the color shall be changed. I use the following code:

   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++;
      }
   }

Where pListCopy is my std::list< CustomColor >* , pListCtrl my CListCtrl* and pImageList my ImageList*.

The problem is, sometimes, my CListCtrl doesn't use the same position as the ImageList (for exemple, item in CListCtrl pos 3 could use an image in ImageList pos 6). In that case, the HBITMAP replaced is wrong. That is why I tried the code in comments: tried getting the ItemData, casting it to IMAGEINFO, changing the value of the HBITMAP and then setting it back. But this gives me a writing access violation...

What am I overlooking? Is there a way to directly change the HBITMAP? I know I could always get every HBITMAP value from the ImageList and reposition them so they are in sync with CListCtrl, but that would not be very efficient and quite ugly.

Upvotes: 0

Views: 707

Answers (1)

Papsicle
Papsicle

Reputation: 147

The problem was I was using GetItemData wrong. GetItemData returns a DWORD_PTR (32 bits value). And I never used a SetItemData before. Now, when creating an item, I use this:

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

And then in my other function, I just cast the GetItemData to int in order to retrieve the image position, like this:

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

Upvotes: 1

Related Questions