|
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  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 |
|