We create our brush with the CreatePatternBrush function instead of CreateSolidBrush as we did in my previous article on How to draw a rounded rectangle in .NETCF. We will mostly use P/Invoke for creating and releasing GDI objects.
const int PS_SOLID = 0;
const int PS_DASH = 1;
[DllImport("coredll.dll")]
static extern IntPtr CreatePen(int fnPenStyle, int nWidth, uint crColor);
[DllImport("coredll.dll")]
static extern int SetBrushOrgEx(IntPtr hdc, int nXOrg, int nYOrg, ref Point lppt);
[DllImport("coredll.dll")]
static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobject);
[DllImport("coredll.dll")]
static extern bool DeleteObject(IntPtr hObject);
[DllImport("coredll.dll")]
static extern IntPtr CreatePatternBrush(IntPtr hbmp);
[DllImport("coredll.dll")]
static extern bool RoundRect(
IntPtr hdc,
int nLeftRect,
int nTopRect,
int nRightRect,
int nBottomRect,
int nWidth,
int nHeight);
static uint GetColorRef(Color value)
{
return 0x00000000 | ((uint)value.B << 16) | ((uint)value.G << 8) | (uint)value.R;
}
Now we have our P/Invoke definitions in place we can neatly wrap all P/Invoke operations in a single function and let's call that FillRoundedTexturedRectangle()
public static void FillRoundedTexturedRectangle(
this Graphics graphics,
Pen border,
Bitmap texture,
Rectangle rectangle,
Size ellipseSize)
{
var lppt = new Point();
var hdc = graphics.GetHdc();
var style = border.DashStyle == DashStyle.Solid ? PS_SOLID : PS_DASH;
var hpen = CreatePen(style, (int)border.Width, GetColorRef(border.Color));
var hbrush = CreatePatternBrush(texture.GetHbitmap());
try
{
SetBrushOrgEx(hdc, rectangle.Left, rectangle.Top, ref lppt);
SelectObject(hdc, hpen);
SelectObject(hdc, hbrush);
RoundRect(hdc,
rectangle.Left,
rectangle.Top,
rectangle.Right,
rectangle.Bottom,
ellipseSize.Width,
ellipseSize.Height);
}
finally
{
SetBrushOrgEx(hdc, lppt.Y, lppt.X, ref lppt);
DeleteObject(hpen);
DeleteObject(hbrush);
graphics.ReleaseHdc(hdc);
}
}
To use this extension method you need to create a Bitmap and a Pen. The pen will be used to draw the rounded border, and the Bitmap will be used as a fill (tiled). Here's an example where "e" is an instance of PaintEventArgs
using (var pen = new Pen(SystemColors.Highlight, 5))
using (var texture = new Bitmap(@"\windows\msn.gif"))
e.Graphics.FillRoundedTexturedRectangle(pen,
texture,
ClientRectangle,
new Size(8, 8));
I hope you found this useful. If you're interested in the full source code then you can grab it here
2 comments:
Great, now how about anti aliasing the rounded rectangle? ;)
Thank you, saved me heaps of time trying to do it from scratch !
Post a Comment