2017-07-18 105 views
1

我正在使用本机方法在表单中绘制矩形。当我使用graphics.DrawRectangle方法时,矩形将正确绘制。但是当使用像下面的代码这样的本地方法时,它总是填充矩形内的白色背景。使用本机方法绘制矩形填充白色背景

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
     this.BackColor = Color.Yellow; 
    } 

protected override void OnPaint(PaintEventArgs e) 
{ 
    Rectangle rect = new Rectangle(20,20,100,30); 
    e.Graphics.DrawRectangle(new Pen(Color.Red, 1), rect); 
    IntPtr hdc = e.Graphics.GetHdc(); 
    DrawRectangle(hdc, Pens.Red, new Rectangle(25, 60, 100, 30)); 
    e.Graphics.ReleaseHdc(); 
    base.OnPaint(e); 
} 

public void DrawRectangle(IntPtr hdc, Pen pen, Rectangle rect) 
{ 
    IntPtr hpen = IntPtr.Zero; 
    try 
    { 
     hpen = CreatePen((int)pen.DashStyle, (int)pen.Width, (int)new RGB(pen.Color).ToInt32()); 
     SelectObject(hdc, hpen); 
     RectangleCE(hdc, rect.Left, rect.Top, rect.Right, rect.Bottom); 
    } 
    finally 
    { 
     if (hpen != IntPtr.Zero) 
      DeleteObject(hpen); 
    } 
} 

[DllImport("gdi32")] 
public static extern IntPtr CreatePen(int penStyle, int width, int color); 


[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] 
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr obj); 

[DllImport("gdi32.dll", EntryPoint = "Rectangle", SetLastError = true)] 
public static extern uint RectangleCE(IntPtr hdc, int leftRect, int topRect, int rightRect, int bottomRect); 

[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] 
public static extern int DeleteObject(IntPtr hObject); 

/// <summary> 
/// Selects a red, green, blue (RGB) color based on the arguments supplied and the color capabilities of the output device 
/// </summary> 
[StructLayout(LayoutKind.Sequential)] 
public struct RGB 
{ 
    /// <summary> 
    /// The reserved fields. 
    /// </summary> 
    private byte r, g, b, reserved; 

    /// <summary> 
    /// Initializes a new instance of the <see cref="RGB"/> struct. 
    /// </summary> 
    /// <param name="colorIn">The color value.</param> 
    public RGB(Color colorIn) 
    { 
     r = colorIn.R; 
     g = colorIn.G; 
     b = colorIn.B; 
     reserved = 0; 
    } 

    /// <summary> 
    /// Convert the RGB color value to integer value. 
    /// </summary> 
    /// <returns>Returns the converted value.</returns> 
    public int ToInt32() 
    { 
     var colors = new byte[4]; 
     colors[0] = r; 
     colors[1] = g; 
     colors[2] = b; 
     colors[3] = reserved; 
     return BitConverter.ToInt32(colors, 0); 
    } 
} 

}

请参考附件图像,在该形态是黄色填充。第一个矩形使用graphics.DrawRectangle方法绘制,第二个矩形使用上述本地方法。

enter image description here

请任何人建议如何绘制矩形填充无白色背景使用上述本地方法?

+0

我想你应该创建一个透明刷:) –

回答

1

矩形函数将绘制一个矩形与当前的笔,也用当前画笔填充内部。

https://msdn.microsoft.com/en-us/library/aa269219(v=vs.60).aspx

您可以更改使用选择对象像下面的当前画笔。但是将Color.Transparent设置为白色。

var yColor = (uint) new RGB(Color.Yellow).ToInt32(); 
SelectObject(hdc, CreateSolidBrush(yColor)); 
hpen = CreatePen((int)pen.DashStyle, (int)pen.Width, (uint)new RGB(pen.Color).ToInt32()); 
SelectObject(hdc, hpen); 
RectangleCE(hdc, rect.Left, rect.Top, rect.Right, rect.Bottom); 

如果你不想填内部,那么你必须使用FrameRect功能。但使用此功能,线条的粗细始终为1.我们无法调整它。

https://msdn.microsoft.com/en-us/library/dd144838(v=vs.85).aspx

var rect2 = new RECT(rect); 
FrameRect(hdc, ref rect2, CreateSolidBrush((uint)new RGB(Color.Red).ToInt32()));