I am using the native methods to draw the rectangle in a form. when I using the graphics.DrawRectangle method the rectangle will draw properly. But when using the native method like below code, it always fills the white background inside the rectangle.
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);
}
}
}
Please find the attached image, in that the form was filled by yellow color. The first one rectangle is drawing using the graphics.DrawRectangle method and the second one is using the above native method.
Please anyone suggest how to draw the rectangle without fill white background using the above native method?
Rectangle function will draws a rectangle with the current pen and also fills the interior with current brush.
https://msdn.microsoft.com/en-us/library/aa269219(v=vs.60).aspx
You can change the current brush using SelectObject like below. But setting Color.Transparent will be considered as White Color.
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);
If you don’t want to fill the interior, then you have to use the FrameRect function. But using this function, thickness of line always be 1. We can’t adjust it.
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()));