bbfu has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to use images in association with Win32::GUI::TreeView but I'm having some problems. I can get simple bitmaps to show up, but I'd like to use partially transparent bitmaps (ie bitmaps with associated bitmap masks), or (ideally) icon images in the TreeView. From what I've read in the docs, the following code is correct, but it doesn't work. Hopefully some wise monk can help me out. :)

Of course, the problem may be in the bitmap or icon files I'm using, so they're available at the following URLs:
FolderOpen.bmp
FolderOpenMask.bmp
FolderOpen.ico

#!perl/bin/perl use warnings; use strict; use Win32::GUI; my $main = Win32::GUI::Window->new( -name => 'Main', -width => 300, -height => 250, ); my $il = Win32::GUI::ImageList->new(16, 16, 32, 1, 5); # This shows the image, but it's not masked $il->Add('FolderOpen.bmp', 'FolderOpenMask.bmp'); # As does this #$il->AddBitmap( # Win32::GUI::Bitmap->new('FolderOpen.bmp', 0), # Win32::GUI::Bitmap->new('FolderOpenMask.bmp', 0), #); # And icon files don't work at all #$il->AddBitmap(Win32::GUI::Bitmap->new('FolderOpen.ico', 1)); my $tv = $main->AddTreeView( -name => 'TreeView', -width => 280, -height => 200, -top => 10, -left => 5, -buttons => 1, -rootlines => 1, -imagelist => $il, ); # Also, this doesn't seem to work, for some reason. # The ImageList has to be passed when constructing the TreeView. # Why? #$tv->SetImageList($il, 24); my $root = $tv->InsertItem( -text => 'Foo', -indent => 1, -image => 0, ); $tv->InsertItem( -text => 'Bar', -indent => 1, -image => 0, ); $tv->InsertItem( -text => 'Baz', -indent => 1, -image => 0, -parent => $root, ); $main->Show(1); Win32::GUI::Dialog(); sub Main_Terminate { return -1; }

bbfu
Black flowers blossom
Fearless on my breath

Replies are listed 'Best First'.
Re: Win32::GUI::TreeView and bitmap masks
by knexus (Hermit) on Sep 09, 2003 at 09:38 UTC
    I played around with this for a while and got it to work, although I am not certain that I did it "properly" or not. The documentation does not make the requirements clear, at least not to me. ;) As far as I can tell at the moment the Mask BMP is irrelevant, and seems to be optional according to the doc. I did not take the time to delve into the MS Doc to see what may be happening under the hood, I may do that later out of curiosity ;-)

    So, what I did was edit the BMP in photoshop, editing the black border out to "transparent" and saved the file. This seems to work. I also created a FolderClosed.Bmp and adjusted the $tv->InsertItem calls so that you get Open Folders when it's selected and Closed Folders when unselected.

    The code with just a couple changes is below along with links to the updated image files.

    Good luck, I hope this helps.

    Update: Per bbfu's reply, I was wrong about the transparency being in the new image. I was fooled by how photoshop treated the file and then saved it as a BMP, Sorry. I guess it was too early in the AM for me. I am looking at it further now.

    Update: Ok, it's fixed, see latest files and code below: Details, Enjoy!

    FolderOpen
    OpenMask
    FolderClosed
    ClosedMask
    Tree.pl

    #!perl/bin/perl use warnings; use strict; use Win32::GUI; my $main = Win32::GUI::Window->new( -name => 'Main', -width => 300, -height => 250, ); # NOTE: To use bitmap masks, the flag ILC_MASK (0x0001) must be set. # Also, using a 16 color bmp seem to require ILC_COLOR16 (0x0010) my $il = Win32::GUI::ImageList->new(16, 16, 0x0011, 4, 5); # This shows the image, but it's not masked $il->Add('FolderOpen.bmp', 'FolderOpenMask.bmp'); $il->Add('FolderClosed.bmp', 'FolderClosedMask.bmp'); # As does this #$il->AddBitmap( # Win32::GUI::Bitmap->new('FolderOpen.bmp', 0), # Win32::GUI::Bitmap->new('FolderOpenMask.bmp', 0), #); # And icon files don't work at all #$il->AddBitmap(Win32::GUI::Bitmap->new('FolderOpen.ico', 1)); my $tv = $main->AddTreeView( -name => 'TreeView', -width => 280, -height => 200, -top => 10, -left => 5, -buttons => 1, -rootlines => 1, -imagelist => $il, ); # Also, this doesn't seem to work, for some reason. # The ImageList has to be passed when constructing the TreeView. # Why? #$tv->SetImageList($il, 24); my $root = $tv->InsertItem( -text => 'Foo', -indent => 1, -selected => 0, -image => 1, -selectedimage => 0, ); $tv->InsertItem( -text => 'Bar', -indent => 1, -image => 1, -selectedimage => 0, ); $tv->InsertItem( -text => 'Baz', -indent => 1, -image => 1, -selectedimage => 0, -parent => $root, ); $main->Show(1); Win32::GUI::Dialog(); sub Main_Terminate { return -1; }

      As far as I know, Windows bitmaps don't support a transparent "color". The images you linked to come up for me as having a white background. This looks fine if the user's settings have the TreeView's background color as white (which is the default) but if they change the "Window" setting in their Appearances section of Display properties, then the folder icons have a small white box around them.

      This is why I was hoping to get "true" transparency using either a mask or an actual .ico file, which does support a transparent "color."

      bbfu
      Black flowers blossom
      Fearless on my breath

        Update: Ok, after wiping the egg off my face, I believe I have the answer now.

        In order to use an image list with masks the flag "ILC_MASK" must be set in the call to ImageList_Create, Otherwise the image list contains only one bitmap. Also, To properly display your 16 color bitmaps I had to also include "ILC_COLOR16".

        See the MS Doc here for more: ImageList_Create

        Note: Win32::GUI::ImageList->new essentially just calls Win32::GUI::ImageList::Create(@_) in GUI.pm which maps to ImageList_Create(cx, cy, flags, cInitial, cGrow) in GUI.xs. So, to set the flags the MS Win32 API wants just supply them to the constructor.

        # NOTE: To use bitmap masks, the flag ILC_MASK (0x0001) must be set. # Also, using a 16 color bmp seem to require ILC_COLOR16 (0x0010) my $il = Win32::GUI::ImageList->new(16, 16, 0x0011, 4, 5); # This Will NOW use masked BMP images $il->Add('FolderOpen.bmp', 'FolderOpenMask.bmp'); $il->Add('FolderClosed.bmp', 'FolderClosedMask.bmp');
        I also updated the files and links in my orignal reply: Re: Win32::GUI::TreeView and bitmap masks.

        I hope this works better ;-)