Click here to Skip to main content
15,885,032 members
Articles / Multimedia / GDI+
Article

GDI+ RoundedRect

Rate me:
Please Sign up or sign in to vote.
3.80/5 (9 votes)
15 Feb 20022 min read 102.8K   1.5K   33   10
Providing a RoundedRect function for GDI+

Sample Image - Screenshot.jpg

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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
Australia Australia
Programming computers ( self taught ) since about 1984 when I bought my first Apple ][. Was working on a GUI library to interface Win32 to Python, and writing graphics filters in my spare time, and then building n-tiered apps using asp, atl and asp.net in my job at Dytech. After 4 years there, I've started working from home, at first for Code Project and now for a vet telemedicine company. I owned part of a company that sells client education software in the vet market, but we sold that and I worked for the owners for five years before leaving to get away from the travel, and spend more time with my family. I now work for a company here in Hobart, doing all sorts of Microsoft based stuff in C++ and C#, with a lot of T-SQL in the mix.

Comments and Discussions

 
GeneralSmall fix Pin
TonyTop1-Apr-05 10:17
TonyTop1-Apr-05 10:17 
Generalconfining image to area... Pin
M i s t e r L i s t e r20-Sep-03 18:03
M i s t e r L i s t e r20-Sep-03 18:03 
QuestionHow to use "new" keyword in VC++6.0 Pin
Ende27-Oct-02 19:05
Ende27-Oct-02 19:05 
AnswerRe: How to use "new" keyword in VC++6.0 Pin
Christian Graus27-Oct-02 19:09
protectorChristian Graus27-Oct-02 19:09 
GeneralRe: How to use "new" keyword in VC++6.0 Pin
27-Oct-02 20:31
suss27-Oct-02 20:31 
GeneralRe: How to use &quot;new&quot; keyword in VC++6.0 Pin
Davide Calabro12-Jun-03 4:29
Davide Calabro12-Jun-03 4:29 
GeneralLast Line Pokes Out Pin
Swinefeaster2-Aug-02 22:14
Swinefeaster2-Aug-02 22:14 
GeneralAvoid returning a pointer Pin
Swinefeaster2-Aug-02 1:26
Swinefeaster2-Aug-02 1:26 
GeneralRe: Avoid returning a pointer Pin
Christian Graus2-Aug-02 1:43
protectorChristian Graus2-Aug-02 1:43 
GeneralRe: Avoid returning a pointer Pin
Swinefeaster2-Aug-02 1:46
Swinefeaster2-Aug-02 1:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.