Introduction
Although
GDI+ is a very exciting extension to GDI, for some reason, the RoundedRect
function is not provided. Although
it is obviously possible to use GDI functions with GDI+, this does not give us
the ability to use new features such as texturing and alpha transparency with
our rounded rectangles. Luckily,
GDI+ offers the GraphicsPath
class, which we can use to create any shape and
then draw using any brush. I've
provided a function which can be added to any project, and used as shown to
draw a rounded rect, and provided a demo application that allows setting the
rounding percentage via a slider.
It's quick and dirty ( it's late here ), but it is adequate to show off
what the function does. The
function is as follows:
GraphicsPath* MakeRoundRect(Point topLeft, Point bottomRight, INT percentageRounded)
{
ASSERT (percentageRounded >= 1 && percentageRounded <= 100);
INT left = min(topLeft.X, bottomRight.X);
INT right = max(topLeft.X, bottomRight.X);
INT top = min(topLeft.Y, bottomRight.Y);
INT bottom = max(topLeft.Y, bottomRight.Y);
INT offsetX = (right-left)*percentageRounded/100;
INT offsetY = (bottom-top)*percentageRounded/100;
GraphicsPath pt;
GraphicsPath * path = pt.Clone();
path->AddArc(right-offsetX, top, offsetX, offsetY, 270, 90);
path->AddArc(right-offsetX, bottom-offsetY, offsetX, offsetY, 0, 90);
path->AddArc(left, bottom - offsetY, offsetX, offsetY, 90, 90);
path->AddArc(left, top, offsetX, offsetY, 180, 90);
path->AddLine(left + offsetX, top, right - offsetX/2, top);
return path;
}
The interesting thing to note is that since I first wrote this code, the
ability to call new
for GraphicsPath
has been removed in some cunning manner (
try it and see ). Instead I must
make a local object, and call it's 'Clone
' method. It's entirely possible I am just missing something at this
late hour, but it seems in line with other classes in GDI+, that you need to
create new objects via pointers using GDI+ methods instead of new, and I
presume this is because the other .NET languages do not offer pointers.
That's about all there is to it.
This code has one flaw - it is poor design that the function creates an
object, and the caller must delete it.
However, GDI+ kindly does not allow us to return the path as an object,
only as a pointer. I'm guessing
this has something to do with GDI+ returning every class as a reference, but I
am not sure. For some fun, I
recommend you play with other things you can add to this path – the Warp
method
looks like it could especially be a lot of fun.