I've beaten my head against the wall for 7 hours on this Icon problem..HELP?

Alright, here's the deal..I have 32bit alpha blended XP icons that i'm using in a control...
I'm using a manifest for comctl v6, which I read was the solution..but I cannot make Images that come from an ImageList to work with transparency..i know it's not the icons because i can use the *SAME* Icon using GDI+ DrawIcon() and it works perfectly fine.  I'm very desperate for a solution, and i have sample apps if needed..please help me out..
-Randy


Answer this question

I've beaten my head against the wall for 7 hours on this Icon problem..HELP?

  • RCS300

    not sure if this will hurt or help you:  <a href="http://www.dotnet247.com/247reference/msgs/22/112338.aspx">ControlPaint class doesn't draw XP visual styles </a>

    or maybe it's a waste of time, just thought I'd throw it out anyway.

  • ALK

    Randy, sorry for the delayed response.  I looked at what our TabControl does, and, as it is just a wrapper on the ComCtl version, it simply does a SendMessage to the underlying tab control and tells it to use the image list, then ComCtl handles the rendering.  

    So emulating what our TabControl does is out.  Below is some code I've used to draw an Icon.

    Icon ico = new Icon(this.Icon,16,16); 
    Rectangle iconRect = new Rectangle(3, 2, 16, 16); 
    pe.Graphics.DrawIconUnstretched(ico, iconRect); 

    This is actually a modified version of some code you posted here a while back.  <a href="http://windowsforms.net/Forums/ShowPost.aspx tabIndex=1&tabId=41&PostID=594">http://windowsforms.net/Forums/ShowPost.aspx tabIndex=1&tabId=41&PostID=594</a>

    The key is that you need to treat these as Icons and not as Images for GDI+ to draw them correctly.  Instead of using an ImageList, just use a collection of Icons.

    BTW - has anyone ever written any code to take an Icon in an ImageList and convert it back to an Icon   This would be some useful code, especially here.

     - mike

  • Kamal Hathi

    You can DrawImage() onto another Image.  Thats all I can think of.

     - mike

  • Mshorema

    alright..worked with Erik for an hour on it and got it working with comctl v6..
    now here's the question..if i want to use owner drawn items..what's the best approach for being able to draw the images in the correct format
    using DrawImage() isnt working properly, it draws them with the incorrect format..
    do i need to use Bitmap and lock the bits like discussed one one of the forums  i don't mind doing that if necessary, but if i don't have to i don't feel the need to....any ideas

  • Terence Blyth

    Randy, sorry for the delay moderating your last few posts.  Our team started a building move on Friday afternoon and there was some network downtime. 

    ControlPaint's DrawImageDisabled uses one of the Graphics.DrawImage overloads that takes a ColorMatrix.  So you're basically in the same position you were in before, using DrawImage on an Icon doesn't work too well.  And there is no overload of DrawIcon that takes a ColorMatrix.

    I really can't think of a good way to do this.  You could try to get the pixel info from the image and then create an in memory icon, but you'd need to get pretty low level and undersatnd the memory layout of each format.

     - mike

  • Sizzles

    Hrm..alright, thanks mike! I'll play around with it for a bit, i have one idea that i'll try..maybe i can use a color matrix to create the black and white image and then send the black and white image to MY drawThemeIcon function, since i believe the Image itself supports the transparency and the DrawImage() doesnt..i'll keep you posted! Thanks a bunch!

  • ThomasBear

    hrm..is there any way to apply ImageAttributes to an actual Image instead of just when i call DrawImage()  ...i need to colorshear the color image with a black and white color matrix and then save it into a new imagelist and call my drawImage for this new imagelist.images[0] ....make sense
  • Anzu

    alright..hopefully this post goes through, i guess my other two never went through..anyway..Mike, your way with DrawIcon() works fine ..this is what i was doing previously, but for my tab control i really need to maintain the ImageList functionality so that i can assign tabpages an index and such..plus the designer works alot easier for others im working with to add images and such..so i dove into uxtheme.h and tmschema.h and dug out enough info to draw color icons perfectly..the following is a simplified version of the code required, i have copied all the enums as well but thats pretty simple so im not going to flood this post with the enums, however, im still having a problem drawing the images in black and white -- according to what i've read, DrawThemeIcon (the function from uxtheme.dll) accepts iPartId and iStateId, so i assumed i could use like..BP_PUSHBUTTON  and PBS_DISABLED as a state to draw the image greyed out but im not having any succes..so if you could point me in the right direction there thatd be helpful! Thanks! below is the code i'm using!

    [StructLayout(LayoutKind.Explicit)]
    public struct RECT
    {
    [FieldOffset(0)] public int left;
    [FieldOffset(4)] public int top;
    [FieldOffset(8)] public int right;
    [FieldOffset(12)] public int bottom;
    }

    [DllImport("uxtheme.dll")]
    private static extern IntPtr OpenThemeData (IntPtr hWnd, [MarshalAs(UnmanagedType.LPTStr)] string pszClassList);

    [DllImport("uxtheme.dll")]
    private static extern IntPtr CloseThemeData (IntPtr hTheme);

    [DllImport("uxtheme.dll")]
    private static extern IntPtr DrawThemeIcon(IntPtr hTheme, IntPtr hdc, int iPartId, int iStateId, ref RECT pRect, IntPtr himl, int iImageIndex);

    private void DrawThemeIconEx(Graphics g, ImageList il, int ImageIndex, int x, int y, int width, int height)
    {
    RECT rect = new RECT();
    rect.left = x;
    rect.top = y;
    rect.right = x+width;
    rect.bottom = y+height;
    IntPtr hData = OpenThemeData(this.Handle,"Button");
    IntPtr hDC = g.GetHdc();
    DrawThemeIcon(hData,hDC,1,1,ref rect,il.Handle,ImageIndex);
    g.ReleaseHdc(hDC);
    CloseThemeData(hData);
    }

  • Andy Robb

    Thanks mike and erik for the help...thanks to erik's link and some diving into uxtheme.h and tmschema.h i found a solution..mike, your way works very well, just the problem that i run into is that from a design standpoint it's alot easier to keep up with an imageindex for the tabs and have one imagelist for the complete tabcontrol..so here's my solution:

    [StructLayout(LayoutKind.Explicit)]
    private struct RECT
    {
       [FieldOffset(0)] public int left;
       [FieldOffset(4)] public int right;
       [FieldOffset(8)] public int top;
       [FieldOffset(12)] public int bottom;
    }


    [DllImport("uxtheme.dll")]
    private static extern IntPtr OpenThemeData(IntPtr hWnd, [MarshalAs(UnmanagedType.LPTStr)] string pszClassList);
    [DllImport("uxtheme.dll")]
    private static extern IntPtr CloseThemeData(IntPtr hTheme);
    [DllImport("uxtheme.dll")]
    private static extern IntPtr DrawThemeIcon(IntPtr hTheme, IntPtr hdc, int iPartId, int iStateId, ref RECT pRect, IntPtr himl, int iImageIndex);

    <...> then in my function call:

    RECT prect = new RECT();
    prect.left = myRect.Left;
    prect.right = myRect.Right;
    prect.top = myRect.Top;
    prect.bottom = myRect.Bottom;
    IntPtr hData = OpenThemeData(this.Handle,"Button");
    IntPtr hDC = myGraphics.GetHdc();
    DrawThemeIcon(hData, hDC, 0, 0, ref prect, myImageList.Handle, myIndex);
    myGraphics.ReleaseHdc();


    ..This seems to be working fine except for one thing, i cant force it to draw the images as black and white (disabled) which i believe has something to do with the iPartId and iStateId, i copied the enums over to C# but still no success on that..so if anyone has any suggestions please let me know.  previously i was using ControlPaint.DrawImageDisabled() ..so maybe mike could you look at your DrawImageDisabled () function and see how it makes it a black and white  Thanks! Hope this helps in the least bit!

  • PacificTester

    and yes, having some sort of ImageList Image -> Icon conversion method would really eliminate all of these problems, as i jsut want to use ImageList as a container.
  • sabari

    They're png -- can you send me a sample app and source code and let me see if i have the problem on my system

    randy.w@softworks.ca

  • Cden

    http://www.fordpony.org/tabs.jpg


    the left is normal tabcontrol

    the right is ownerdrawn
    coming from the same imagelist and all
    heres the call to draw it:
    e.Graphics.DrawImage(this.ImageList.Images[this.TabPages[e.Index].ImageIndex],e.Bounds.Left+2,e.Bounds.Top+vOffset);

    ideas

  • RayCan

    while file type are your images that are going into your ImageList   I've used pngs of the same quality as yours with transparency from an ImageList (just added through the VS.NET designer, so i believe just embedded resources) and with XP Styles turned on, had them come out looking perfect!
  • g0sh4wk

    What do you mean by "draws them with the incorrect format"   Is it a scaling issue   A color issue   A transparency issue

    You could try DrawImageUnscaled() if it is a scaling issue.

     - mike

  • I've beaten my head against the wall for 7 hours on this Icon problem..HELP?