如何使控件背景色支持TransparentKey(at Win2k/WinXP 32bit Color Desktop)
问题:
在Window 2000和WindowsXP 32bit Color桌面下,自己写了Control,放到DoubleBuffered为True的Form上设置背景颜色(BackColor)为Form的TransparentKey相同的颜色后,发现没有透下去,下面是Demo代码:
控件代码:
![](https://www.cnblogs.com/images/cnblogs_com/winkingzhang/117454/o_winxp32.jpg)
显然这里没有透下去,但是.NET自带Control都可以透下去!
找了很久也没有找到问题所在,只好祭出Reflector,看MS的内部实现了,从
OnPaintBackground(PaintEventArgs pevent)->
PaintBackground(PaintEventArgs e, Rectangle rectangle)->
PaintBackground(PaintEventArgs e, Rectangle rectangle, Color backColor, Point scrollOffset)->
PaintBackColor(PaintEventArgs e, Rectangle rectangle, Color backColor):
在Window 2000和WindowsXP 32bit Color桌面下,自己写了Control,放到DoubleBuffered为True的Form上设置背景颜色(BackColor)为Form的TransparentKey相同的颜色后,发现没有透下去,下面是Demo代码:
控件代码:
1
public class MyControl : Control
2
{
3
protected override void OnPaint(PaintEventArgs e)
4
{
5
// Drawing border
6
if (Application.RenderWithVisualStyles)
7
{
8
new VisualStyleRenderer(VisualStyleElement.TextBox.TextEdit.Hot).DrawEdge(e.Graphics,
9
this.ClientRectangle,
10
Edges.Left | Edges.Top | Edges.Right | Edges.Bottom,
11
EdgeStyle.Raised,
12
EdgeEffects.Mono);
13
}
14
else
15
{
16
ControlPaint.DrawBorder3D(e.Graphics, this.ClientRectangle);
17
}
18![](/Images/OutliningIndicators/InBlock.gif)
19
base.OnPaint(e);
20![](/Images/OutliningIndicators/InBlock.gif)
21
// Drawing demo string/
22
using (StringFormat sf = new StringFormat())
23
{
24
sf.Alignment = StringAlignment.Center;
25
e.Graphics.DrawString("This is Test Control", this.Font, Brushes.Black, this.ClientRectangle, sf);
26
}
27
}
28![](/Images/OutliningIndicators/InBlock.gif)
29
protected override void OnPaintBackground(PaintEventArgs pevent)
30
{
31
base.OnPaintBackground(pevent);
32![](/Images/OutliningIndicators/InBlock.gif)
33
//Here I want fill some shape at Background, for example fill ellipse at half-top client.
34
using (Brush brush = new SolidBrush(Color.Red))
35
{
36
pevent.Graphics.FillEllipse(brush, new Rectangle(0, 0, this.Width, this.Height / 2));
37
}
38
}
39
}
下图是在Window XP 32bit Color桌面下的运行效果:![](/Images/OutliningIndicators/None.gif)
2
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
3
![](/Images/OutliningIndicators/InBlock.gif)
4
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
5
![](/Images/OutliningIndicators/InBlock.gif)
6
![](/Images/OutliningIndicators/InBlock.gif)
7
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
8
![](/Images/OutliningIndicators/InBlock.gif)
9
![](/Images/OutliningIndicators/InBlock.gif)
10
![](/Images/OutliningIndicators/InBlock.gif)
11
![](/Images/OutliningIndicators/InBlock.gif)
12
![](/Images/OutliningIndicators/InBlock.gif)
13
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
14
![](/Images/OutliningIndicators/InBlock.gif)
15
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
16
![](/Images/OutliningIndicators/InBlock.gif)
17
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
18
![](/Images/OutliningIndicators/InBlock.gif)
19
![](/Images/OutliningIndicators/InBlock.gif)
20
![](/Images/OutliningIndicators/InBlock.gif)
21
![](/Images/OutliningIndicators/InBlock.gif)
22
![](/Images/OutliningIndicators/InBlock.gif)
23
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
24
![](/Images/OutliningIndicators/InBlock.gif)
25
![](/Images/OutliningIndicators/InBlock.gif)
26
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
27
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
28
![](/Images/OutliningIndicators/InBlock.gif)
29
![](/Images/OutliningIndicators/InBlock.gif)
30
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
31
![](/Images/OutliningIndicators/InBlock.gif)
32
![](/Images/OutliningIndicators/InBlock.gif)
33
![](/Images/OutliningIndicators/InBlock.gif)
34
![](/Images/OutliningIndicators/InBlock.gif)
35
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
36
![](/Images/OutliningIndicators/InBlock.gif)
37
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
38
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
39
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](https://www.cnblogs.com/images/cnblogs_com/winkingzhang/117454/o_winxp32.jpg)
显然这里没有透下去,但是.NET自带Control都可以透下去!
找了很久也没有找到问题所在,只好祭出Reflector,看MS的内部实现了,从
OnPaintBackground(PaintEventArgs pevent)->
PaintBackground(PaintEventArgs e, Rectangle rectangle)->
PaintBackground(PaintEventArgs e, Rectangle rectangle, Color backColor, Point scrollOffset)->
PaintBackColor(PaintEventArgs e, Rectangle rectangle, Color backColor):
1
private static void PaintBackColor(PaintEventArgs e, Rectangle rectangle, Color backColor) {
2
// Common case of just painting the background. For this, we
3
// use GDI because it is faster for simple things than creating
4
// a graphics object, brush, etc. Also, we may be able to
5
// use a system brush, avoiding the brush create altogether.
6
//
7
Color color = backColor;
8
9
// we use GDI to paint in most cases using WindowsGraphics
10
bool painted = false;
11
if (color.A == 255) {
12
using( WindowsGraphics wg = WindowsGraphics.FromGraphics( e.Graphics ) ) {
13
color = wg.GetNearestColor(color);
14![](/Images/OutliningIndicators/InBlock.gif)
15
using (WindowsBrush brush = new WindowsSolidBrush(wg.DeviceContext, color)) {
16
wg.FillRectangle(brush, rectangle);
17
}
18
}
19![](/Images/OutliningIndicators/InBlock.gif)
20
painted = true;
21
/*
22
if (DisplayInformation.BitsPerPixel > 8) {
23
NativeMethods.RECT r = new NativeMethods.RECT(rectangle.X, rectangle.Y, rectangle.Right, rectangle.Bottom);
24
SafeNativeMethods.FillRect(new HandleRef(e, e.HDC), ref r, new HandleRef(this, BackColorBrush));
25
painted = true;
26
}*/
27
}
28![](/Images/OutliningIndicators/InBlock.gif)
29
if (!painted) {
30
// don't paint anything from 100% transparent background
31
//
32
if (color.A > 0) {
33
// Color has some transparency or we have no HDC, so we must
34
// fall back to using GDI+.
35
//
36
using (Brush brush = new SolidBrush(color)) {
37
e.Graphics.FillRectangle(brush, rectangle);
38
}
39
}
40
}
41
}
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
2
![](/Images/OutliningIndicators/InBlock.gif)
3
![](/Images/OutliningIndicators/InBlock.gif)
4
![](/Images/OutliningIndicators/InBlock.gif)
5
![](/Images/OutliningIndicators/InBlock.gif)
6
![](/Images/OutliningIndicators/InBlock.gif)
7
![](/Images/OutliningIndicators/InBlock.gif)
8
![](/Images/OutliningIndicators/InBlock.gif)
9
![](/Images/OutliningIndicators/InBlock.gif)
10
![](/Images/OutliningIndicators/InBlock.gif)
11
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
12
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
13
![](/Images/OutliningIndicators/InBlock.gif)
14
![](/Images/OutliningIndicators/InBlock.gif)
15
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
16
![](/Images/OutliningIndicators/InBlock.gif)
17
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
18
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
19
![](/Images/OutliningIndicators/InBlock.gif)
20
![](/Images/OutliningIndicators/InBlock.gif)
21
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
22
![](/Images/OutliningIndicators/InBlock.gif)
23
![](/Images/OutliningIndicators/InBlock.gif)
24
![](/Images/OutliningIndicators/InBlock.gif)
25
![](/Images/OutliningIndicators/InBlock.gif)
26
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
27
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
28
![](/Images/OutliningIndicators/InBlock.gif)
29
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
30
![](/Images/OutliningIndicators/InBlock.gif)
31
![](/Images/OutliningIndicators/InBlock.gif)
32
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
33
![](/Images/OutliningIndicators/InBlock.gif)
34
![](/Images/OutliningIndicators/InBlock.gif)
35
![](/Images/OutliningIndicators/InBlock.gif)
36
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
37
![](/Images/OutliningIndicators/InBlock.gif)
38
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
39
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
40
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
41
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
发现MS Code对这里的注释,只说这里使用GDI画的,在12行,这里使用的WindowsGraphics就是对GDI的封装。
所以要想实现和MS Control一样,任何环境都支持TransparentKey,这里的背景只能使用GDI来画,修改MyControl代码如下就可以了:
1
public class MyControl : Control
2
{
3
protected override void OnPaint(PaintEventArgs e)
4
{
5
// Drawing border
6
if (Application.RenderWithVisualStyles)
7
{
8
new VisualStyleRenderer(VisualStyleElement.TextBox.TextEdit.Hot).DrawEdge(e.Graphics,
9
this.ClientRectangle,
10
Edges.Left | Edges.Top | Edges.Right | Edges.Bottom,
11
EdgeStyle.Raised,
12
EdgeEffects.Mono);
13
}
14
else
15
{
16
ControlPaint.DrawBorder3D(e.Graphics, this.ClientRectangle);
17
}
18![](/Images/OutliningIndicators/InBlock.gif)
19
base.OnPaint(e);
20![](/Images/OutliningIndicators/InBlock.gif)
21
// Drawing demo string/
22
using (StringFormat sf = new StringFormat())
23
{
24
sf.Alignment = StringAlignment.Center;
25
e.Graphics.DrawString("This is Test Control", this.Font, Brushes.Black, this.ClientRectangle, sf);
26
}
27
}
28![](/Images/OutliningIndicators/InBlock.gif)
29
protected override void OnPaintBackground(PaintEventArgs pevent)
30
{
31
base.OnPaintBackground(pevent);
32![](/Images/OutliningIndicators/InBlock.gif)
33
//Here I want fill some shape at Background, for example fill ellipse at half-top client.
34
//using (Brush brush = new SolidBrush(Color.Red))
35
//{
36
// pevent.Graphics.FillEllipse(brush, new Rectangle(0, 0, this.Width, this.Height / 2));
37
//}
38
IntPtr hdc = IntPtr.Zero;
39
try
40
{
41
hdc = pevent.Graphics.GetHdc();
42
if (hdc != IntPtr.Zero)
43
{
44
IntPtr hBrush = CreateSolidBrush(ColorTranslator.ToWin32(Color.Red));
45
if (hBrush != IntPtr.Zero)
46
{
47
IntPtr oldBrush = SelectObject(hdc, hBrush);
48
Ellipse(hdc, 0, 0, this.Right, this.Height / 2);
49
SelectObject(hdc, oldBrush);
50![](/Images/OutliningIndicators/InBlock.gif)
51
DeleteObject(hBrush);
52
hBrush = IntPtr.Zero;
53
}
54
}
55
}
56
finally
57
{
58
if (hdc != IntPtr.Zero)
59
{
60
pevent.Graphics.ReleaseHdc(hdc);
61
}
62
}
63
}
64![](/Images/OutliningIndicators/InBlock.gif)
65
[DllImport("gdi32.dll")]
66
[return: MarshalAs(UnmanagedType.Bool)]
67
private static extern bool Ellipse(IntPtr hdc, int leftRect, int topRect, int rightRect, int bottomRect);
68![](/Images/OutliningIndicators/InBlock.gif)
69
[DllImport("gdi32.dll")]
70
private static extern IntPtr SelectObject(IntPtr hDC, IntPtr gdiObject);
71![](/Images/OutliningIndicators/InBlock.gif)
72
[DllImport("gdi32.dll")]
73
private static extern IntPtr CreateSolidBrush(int color);
74![](/Images/OutliningIndicators/InBlock.gif)
75
[DllImport("gdi32.dll")]
76
[return: MarshalAs(UnmanagedType.Bool)]
77
private static extern bool DeleteObject(IntPtr gdiObject);
78
}
![](/Images/OutliningIndicators/None.gif)
2
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
3
![](/Images/OutliningIndicators/InBlock.gif)
4
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
5
![](/Images/OutliningIndicators/InBlock.gif)
6
![](/Images/OutliningIndicators/InBlock.gif)
7
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
8
![](/Images/OutliningIndicators/InBlock.gif)
9
![](/Images/OutliningIndicators/InBlock.gif)
10
![](/Images/OutliningIndicators/InBlock.gif)
11
![](/Images/OutliningIndicators/InBlock.gif)
12
![](/Images/OutliningIndicators/InBlock.gif)
13
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
14
![](/Images/OutliningIndicators/InBlock.gif)
15
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
16
![](/Images/OutliningIndicators/InBlock.gif)
17
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
18
![](/Images/OutliningIndicators/InBlock.gif)
19
![](/Images/OutliningIndicators/InBlock.gif)
20
![](/Images/OutliningIndicators/InBlock.gif)
21
![](/Images/OutliningIndicators/InBlock.gif)
22
![](/Images/OutliningIndicators/InBlock.gif)
23
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
24
![](/Images/OutliningIndicators/InBlock.gif)
25
![](/Images/OutliningIndicators/InBlock.gif)
26
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
27
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
28
![](/Images/OutliningIndicators/InBlock.gif)
29
![](/Images/OutliningIndicators/InBlock.gif)
30
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
31
![](/Images/OutliningIndicators/InBlock.gif)
32
![](/Images/OutliningIndicators/InBlock.gif)
33
![](/Images/OutliningIndicators/InBlock.gif)
34
![](/Images/OutliningIndicators/InBlock.gif)
35
![](/Images/OutliningIndicators/InBlock.gif)
36
![](/Images/OutliningIndicators/InBlock.gif)
37
![](/Images/OutliningIndicators/InBlock.gif)
38
![](/Images/OutliningIndicators/InBlock.gif)
39
![](/Images/OutliningIndicators/InBlock.gif)
40
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
41
![](/Images/OutliningIndicators/InBlock.gif)
42
![](/Images/OutliningIndicators/InBlock.gif)
43
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
44
![](/Images/OutliningIndicators/InBlock.gif)
45
![](/Images/OutliningIndicators/InBlock.gif)
46
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
47
![](/Images/OutliningIndicators/InBlock.gif)
48
![](/Images/OutliningIndicators/InBlock.gif)
49
![](/Images/OutliningIndicators/InBlock.gif)
50
![](/Images/OutliningIndicators/InBlock.gif)
51
![](/Images/OutliningIndicators/InBlock.gif)
52
![](/Images/OutliningIndicators/InBlock.gif)
53
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
54
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
55
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
56
![](/Images/OutliningIndicators/InBlock.gif)
57
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
58
![](/Images/OutliningIndicators/InBlock.gif)
59
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
60
![](/Images/OutliningIndicators/InBlock.gif)
61
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
62
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
63
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
64
![](/Images/OutliningIndicators/InBlock.gif)
65
![](/Images/OutliningIndicators/InBlock.gif)
66
![](/Images/OutliningIndicators/InBlock.gif)
67
![](/Images/OutliningIndicators/InBlock.gif)
68
![](/Images/OutliningIndicators/InBlock.gif)
69
![](/Images/OutliningIndicators/InBlock.gif)
70
![](/Images/OutliningIndicators/InBlock.gif)
71
![](/Images/OutliningIndicators/InBlock.gif)
72
![](/Images/OutliningIndicators/InBlock.gif)
73
![](/Images/OutliningIndicators/InBlock.gif)
74
![](/Images/OutliningIndicators/InBlock.gif)
75
![](/Images/OutliningIndicators/InBlock.gif)
76
![](/Images/OutliningIndicators/InBlock.gif)
77
![](/Images/OutliningIndicators/InBlock.gif)
78
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
To be the apostrophe which changed “Impossible” into “I’m possible”
----------------------------------------------------
WinkingZhang's Blog (http://winkingzhang.cnblogs.com)
GCDN(http://gcdn.grapecity.com/cs)