Windows Develop Bookmark and Share   
 index > Windows Forms General > Trouble drawing theme elements transparently
 

Trouble drawing theme elements transparently

I'm trying to draw a windows theme element (the window close button, specifically) to an image, and whenever I do, the image has ragged non-transparent bits. I got this code from a sample that didn't do this (it was all owner-drawn, mine draws to an image.) Any idea why it won't draw with full transparency?

Bitmap output = new Bitmap(closeButton.Width, closeButton.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Graphics fx = Graphics.FromImage(output);
      
IntPtr hTheme = OpenThemeData (Handle, "Window");
         
Rectangle rClose = new Rectangle(0, 0, closeButton.Width, closeButton.Height);
RECT reClose = rClose;
RECT reClip = reClose;
IntPtr hDC = fx.GetHdc();
DrawThemeBackground (hTheme, hDC, WP_CLOSEBUTTON, state, ref reClose, ref reClip);
fx.ReleaseHdc (hDC);
fx.DrawImage(output,rClose);
CloseThemeData (hTheme);
fx.Dispose();
dalangalma  Sunday, October 30, 2005 10:50 AM
No ideas why this wouldn't draw the element transparently?
dalangalma  Monday, October 31, 2005 9:11 AM
This works perfectly for me.
What are you doing with the output Bitmap?
Mick Doherty  Monday, October 31, 2005 6:24 PM
Well, I was assigning it to a PictureBox (I'm trying to fake a themed close button). I also called Save on it so I could check it out as a PNG, but the image is non-transparent there too.

A clarification - the image I get is index-transparent, but not alpha transparent. There are little bits that are transparent, but none of the pixels on the edge are half-transparent.  
dalangalma  Monday, October 31, 2005 8:53 PM

Control windows don't support alpha transparency. You need to either use graphical components, all drawn on a single control, or use windows with alpha transparency -- they cannot be child windows.

Regards,
Frank Hileman

check out VG.net: http://www.vgdotnet.com
Animated vector graphics system
Integrated Visual Studio .NET graphics editor

Frank Hileman  Monday, October 31, 2005 9:50 PM

In this case maybe you are not drawing child controls, so my last post may be irrelevent. Have you looked at IsThemeBackgroundPartiallyTransparent?

Frank Hileman  Monday, October 31, 2005 9:54 PM
Yes, I've tried that, but it didn't help. See, I'm not drawing to a control, I'm drawing to a bitmap - it seems that this should be pretty simple in that case, right?
dalangalma  Monday, October 31, 2005 10:51 PM
 

if (IsThemeBackgroundPartiallyTransparent(_hTheme, BP_PUSHBUTTON, _iStateId))
  {
    DrawThemeParentBackground(_hwnd, hdcPaint, prcPaint);
  }

  DrawThemeBackground(_hTheme,
                    hdcPaint,
                    BP_PUSHBUTTON,
                    _iStateId,
                    &rcClient,
                    prcPaint);

 

That is the MSDN sample. If IsThemeBackgroundPartiallyTransparent returns false, there is no alpha blending -- that is the correct behavior.
Frank Hileman  Monday, October 31, 2005 11:53 PM
I think that explains why the button looks so oogly as well Smile You may need your own close button if you want something better.
Frank Hileman  Monday, October 31, 2005 11:55 PM
When I use that code, I still get the same result - all the alpha-blended bits are drawn onto gray, and only the fully-transparent bits are transparent. And I set a breakpoint - IsThemeBackgroundPartiallyTransparent is returning true.

This is weird because the code I took this from (which did all its drawing itself, in WmPaint), does not have this problem - it is able to draw the same button nicely alpha-blended. The only difference is that I draw to a Bitmap.
dalangalma  Tuesday, November 01, 2005 2:28 AM
I don't see any code clearing your bitmap to transparent alpha.

fx.Clear(Color.Transparent);
 
Frank Hileman  Tuesday, November 01, 2005 12:02 PM
I just tried that out (Yeah, I forgot about this thread and gave up) and it still doesn't work...
dalangalma  Sunday, January 15, 2006 12:24 AM
Bitmap output = new Bitmap(closeButton.Width, closeButton.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            Graphics fx = Graphics.FromImage(output);
           

            IntPtr hTheme = OpenThemeData (Handle, "Window");
           
            if (hTheme == IntPtr.Zero)
            {
                fx.Dispose();
                return drawLegacyCloseButton (state);
            }

            Rectangle rClose = new Rectangle(0, 0, closeButton.Width, closeButton.Height);
            RECT reClose = rClose;
            RECT reClip = reClose; // should fx.VisibleClipBounds be used here?
           
            fx.Clear(Color.Transparent);
            IntPtr hDC = fx.GetHdc();
            if (IsThemeBackgroundPartiallyTransparent(hTheme, WP_CLOSEBUTTON, state) != 0)
            {
                DrawThemeParentBackground(this.Handle, hDC, ref reClose);
            }
            DrawThemeBackground (hTheme, hDC, WP_CLOSEBUTTON, state, ref reClose, ref reClip);
            fx.ReleaseHdc (hDC);
            fx.DrawImage(output,rClose);
            CloseThemeData (hTheme);
            fx.Dispose();

            output.Save("close" + state.ToString() + ".png");

            return output;
dalangalma  Sunday, January 15, 2006 12:42 AM

Still works perfectly for me although I did change the code very slightly.

Rectangle and RECT are not interchangeable.

struct RECT
{
  public int Left, Top, Right, Bottom;
  public RECT(int l, int t, int r, int b)
  {
    Left = l;
    Top = t;
    Right = r;
    Bottom = b;
  }
  public RECT(Rectangle r)
  {
    Left = r.Left;
    Top = r.Top;
    Right = r.Right;
    Bottom = r.Bottom;
  }
  public Rectangle ToRectangle()
  {
    return Rectangle.FromLTRB(Left, Top, Right, Bottom);
  }
}

Rectangle rClose = new Rectangle(0, 0, closeButton.Width, closeButton.Height);
RECT reClose = new RECT(rClose);

Although Format32bppArgb does work for me, the format should really be Format32bppPArgb.

Mick Doherty  Sunday, January 15, 2006 11:22 AM

You can use google to search for other answers

Custom Search

More Threads

• Image on button with FlatStyle.System
• Nested events
• Optimizing a file search operation
• getting media files from a winform
• Handle HTTP request from Windows form
• numerical textbox
• Listbox & Picturebox
• Event Handler in plugin code
• English letters from Japanese keyboard
• To get values of Reader