in reply to Re: Win32::GUI::TreeView and bitmap masks
in thread Win32::GUI::TreeView and bitmap masks

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

  • Comment on Re2: Win32::GUI::TreeView and bitmap masks

Replies are listed 'Best First'.
Re: Re2: Win32::GUI::TreeView and bitmap masks
by knexus (Hermit) on Sep 09, 2003 at 16:22 UTC
    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 ;-)

      Ok. Since you did so well helping me out with my main question, I'm hoping you can help me out with the side question I snuck into the comments of the original code.

      Namely, why do the images completely fail to display when, instead of passing the image list when I create the TreeView, I try to add it later using $tv->SetImageList($il, 1); (where 1 is the value of TVSIL_NORMAL, unless I'm mistaken).

      In other words, why doesn't the following work:

      #!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, 0x0011, 1, 1); $il->Add('FolderClosed.bmp', 'FolderClosedMask.bmp'); my $tv = $main->AddTreeView( -name => 'TreeView', -width => 280, -height => 200, -top => 10, -left => 5, -buttons => 1, -rootlines => 1, -lines => 1, #-imagelist => $il, # Instead of doing this... ); # I want to do this: $tv->SetImageList($il, 1); 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; }

      In case you're curious why I would want to use SetImageList instead, it's because I'm actually using The GUI Loft to create the window, and don't have (easy) access to the options during creation of the TreeView. Also, I'm just curious why it's not working. :)

      Anyway, thanks again for your help before, and a million thanks if you are able to help me again. :p

      P.S. Welcome to the Monastery. Monk in 2 weeks, eh? You're definately doing well around here. Congrats! :D

      bbfu
      Black flowers blossom
      Fearless on my breath

        Yah, I saw those, but thought the other solution would be sufficient ;-) Also, I saw the ICON one which I was not able to track down in the time I allowed my self.

        Ok, this one was actually pretty easy to track down.

        Now, since it sounds like you will be doing quite a bit with win32 stuff I thought I'd take some time to go through the process I used in tracking these types of things down in the hopes that it will be of more help to you in the long run.
        You know, the "Tech'em to fish rather than Feed'em a fish" thing :-)

        I'm hungry, just gimme da fish!

        Ok, so here's the answer: Use a '0'(zero) as the type parameter.

        $tv->SetImageList($il, 0); # Use Flag TVSIL_NORMAL for MS TreeView_Set +ImageList()
        The Flag TVSIL_NORMAL Indicates the normal image list, which contains selected, nonselected, and overlay images for the items of a tree-view control. You can read more on it here: TreeView_SetImageList

        How do ya catch'em

        When using something like the Win32:GUI module and something does not work right, the first thing I do is just blame it on Microsoft ;-)

        No, really I'm not joking, their APIs often have lots of parameters/options which interact with each other in sometimes less than obvious ways sometimes depending on values in other parameters witin the API call. I'm not bashing MS, this is just the way it is, IMHO. So, to resolve these problems you have to dig into the MS Docs and check the parms!
        In order to do this, however, you have to track down each MS API call being made.

        So, in this case I just started with the method that worked, per your example and walked through it.

        Starting with  my $tv = $main->AddTreeView, go into GUI.pm and look within the TreeView package and you'll see that is really just calls new, which ends up in GUI.xs as _new with a parm of "WIN32__GUI__TREEVIEW". Then in GUI.xs this is used in a switch statement which leads to a section where the constructor options are processed. Looking a little deeper is seems that the "-imagelist" parameter is just saved off into a 'C' structure tagPERLWIN32GUI_CREATESTRUCT. So, this appears to be uninteresting for our purposes, it is a dead-end.

        Moving on to the problem call $tv->SetImageList($il, 24);: Look for it in GUI.pm and you'll see that it does not exist. OK fine, check for it GUI.xs and you'll see there are several Methods by that name, so be sure to find the one in the TreeView package.

        MODULE = Win32::GUI PACKAGE = Win32::GUI::TreeView ... METHOD:SetImageList(IMAGELIST, [TYPE]) ... RETVAL = TreeView_SetImageList(handle, imagelist, type);

        Finally, we come to where the MS API is called, TreeView_SetImageList().

        Look this API call up in the MS Docs (MSDN) and you'll read that type controls the interpretation of imagelist. The options are TVSIL_NORMAL, TVSIL_STATE; and NORMAL sounds like the one for our needs. So, I look it up in the include files to get its value of '0' (zero).

        So, the lesson here is (as in the previous example) when using MS APIs in particular, ALWAYS check out those dang parameters ;-}

        Finally, the Caveats

        Please keep in mind that the break down above is only meant to be helpful, NOT to be preachy or anything else; I know i hate being preached to. Also, there are certainly other ways to go about finding the answer. And most definitly there are better ways to explain it that how I did above. Also, I may have ommitted something along the way. ;-)

        ANYHOW, I sincerely hope this helps.

        try once to use ".ico" file instead of ".bmp". Hope it will work.

      Ah! Works perfectly! Thanks ever so much.

      bbfu
      Black flowers blossom
      Fearless on my breath

        Hey, glad to hear it.

        BTW: I have received so much useful information and help from this board since I started working in perl a couple of weeks ago, so it's really nice to finally be able help a little in return.