Search code examples
delphic++builder

How do you add TBitmap objects to a TImageCollection at runtime for use with a TVirtualImageList?


I need to load a TImageCollection to be used with a TVirtualImageList at runtime from TBitmap objects. How do you load them to the collection and assign them so the TVirtualImage list will pick the correct graphic for a given index/size?

The background is I need to get Icon resources in to the collection which means assigning a TIcon to a TBItmap via Assign()

I tried this but the test of a TTreeView with the TVirtualImageList had blank icons so it didn't seem to work (unless I have to do something special with the TVritualImageList) - I'm also not sure if I need to delete the TWICImage object or not:

for (UINT i=IDI_USER_ICON_START; i<=IDI_USER_ICON_END; i++) {
    // add new image index item
    TImageCollectionItem *item=ImageCollection->Images->Add();

    // load our icon of the correct size
    TIcon *icon=new TIcon;
    icon->Handle=reinterpret_cast<HICON>(LoadImageW(HInstance, MAKEINTRESOURCE(i), IMAGE_ICON, 16, 16, 0));
    // convert to bitmap
    TBitmap *bitmap=new TBitmap;
    bitmap->Assign(icon);
    // convert to wicimage
    TWICImage *wicimage=new TWICImage;
    wicimage->Assign(bitmap);
    // add a new format for the 16x16 image and add it
    TImageCollectionSourceItem *imageformat=item->SourceImages->Add();
    imageformat->Image=wicimage;

    // now handle 32x32
    icon->Handle=reinterpret_cast<HICON>(LoadImageW(HInstance, MAKEINTRESOURCE(i), IMAGE_ICON, 32, 32, 0));
    // convert to bitmap
    bitmap->Assign(icon);
    // convert to new wicimage
    wicimage=new TWICImage;
    wicimage->Assign(bitmap);
    // add a new format for the 32x32 image and add it
    imageformat=item->SourceImages->Add();
    imageformat->Image=wicimage;

    //delete wicimage;
    delete bitmap;
    delete icon;
}

Solution

  • Figured it out. Start with AutoFill on the TVirtualImageList set to false then after filling the TImageCollection you set the AutoFill to true to fill the image list.

    Here's the cleaned up code:

    // initialize objects to create
    TIcon *icon=NULL;
    TBitmap *bitmap=NULL;
    
    __try {
        try {
            // create objects needed
            static const int imgformats[]={16,24,32,48,64};
            icon=new TIcon;
            bitmap=new TBitmap;
    
            for (UINT i=IDI_USER_ICON_START; i<=IDI_USER_ICON_END; i++) {
                // add new image index item
                TImageCollectionItem *collectionitem=ImageCollection->Images->Add();
    
                for (int iif=0; iif<ARRAYSIZE(imgformats);iif++) {
                    // load our icon of the correct size
                    icon->Handle=reinterpret_cast<HICON>(LoadImage(HInstance, MAKEINTRESOURCE(i), IMAGE_ICON, imgformats[iif], imgformats[iif], 0));
                    // convert to bitmap
                    bitmap->Assign(icon);
                    // add a new image for the image format
                    TImageCollectionSourceItem *imageitem=collectionitem->SourceImages->Add();
                    // copy bitmap over as the new image format
                    imageitem->Image->Assign(bitmap);
                }
            }
        }
        catch(Exception &E) {
    
        }
    }
    __finally {
        // clean up as needed
        delete bitmap;
        delete icon;
    }
    
    // fill image lists
    VirtualImageList16->AutoFill=true;
    VirtualImageList32->AutoFill=true;