Click here to Skip to main content
15,868,016 members
Articles / Desktop Programming / MFC
Article

Starting with GDI+

Rate me:
Please Sign up or sign in to vote.
4.80/5 (70 votes)
12 Mar 20035 min read 2M   12K   219   361
Getting started with the new Microsoft Graphics Libraries

Sample Image - StartingGDIPlus.jpg

Introduction

I've been using GDI+ for about a week now, and I must say it is a welcome upgrade. I am working on a paint program, and a lot of things I thought I would have to write myself are now built in, meaning I get them "for free". The upside and the downside are, I guess, the same - things I want my program to do are now a lot easier to accomplish, making it easier both for me, and anyone else wanting to write something similar.

Before I get started, let me thank all the people who helped me get started with GDI+ by letting me know it existed, and where to get it. Parts of the information given here are taken verbatim from the thread where these things were discussed on the CodeProject lounge. Of course, all the cool things are written by me :0)

First things first. You need to get GDI+ installed before you can use it. It is found in the Feb 2001 Microsoft Platform SDK. If you don't download the SDK (or get it on CD) then shame on you. Every release of the SDK includes cool new stuff, such as updates to the WTL. Anyhow, I forgive you if you go to ftp.microsoft.com, and download it NOW. If all you want is GDI+, the files are in psdk-common.11.cab (at least that's what I was told, I downloaded the whole thing).

The files you need are:

  • the dll : gdiplus.dll
  • the library : gdiplus.lib
  • the header files : gdiplus*.h
  • the help files: gdicpp.chm & gdicpp.chi

Don't forget to make sure you set Visual C++ to point to the .h files in the includes, and the .lib file in the directories. Also put gdiplus.lib in your list of libraries by choosing Project/Settings/Link and entering it into the object/library modules area. To set your include and library directories, go to Tools/Options/Directories

To get your application to work with GDI+, do the following:

  • in stdafx.h, add:
    #include <gdiplus.h>
    (at the bottom, before the #endif)
  • in your application class, add the member:
    ULONG_PTR m_gdiplusToken;
    ULONG_PTR is a typedef for unsigned __int64. I usually don't like to use typedefs, but in this case I'll make an exception...
  • in InitInstance, add:
    // Initialize GDI+
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);

    I'd love to tell you how all this works, but I'm afraid Microsoft are not currently shipping the source, just headers and a dll.
     

  • in ExitInstance, add:
    Gdiplus::GdiplusShutdown(m_gdiplusToken);

I'll mention at this point that you have the option of prefacing all your commands with GdiPlus::, or you can simply put

using namespace GdiPlus; 

at the head of your code. The rest of my examples will assume you have included this command first, and will not preface commands as such. So now we have a program that initialises GDI+, this is probably a good place to discuss how GDI+ actually works. As you may be aware, GDI works with the concept of a device context. Typically you would draw a box using GDI like this:

(in your OnPaint handler)

CPaintDC dc(this); // Creates a device context for the client area, which
                   // also erases the area to be drawn.

CPen MyPen, * pOldPen;
CBrush MyBrush, * pOldBrush;<BR>
<BR><BR><BR><BR>// A red pen, one pixel wide
MyPen.Create(1, PS_SOLID, RGB(255,0,0));

// Selecting an object returns the old one
// we need to catch and return it to avoid memory leaks
pOldPen = dc.SelectObject(&MyPen);       
                                          
// A Blue brush                                         
MyBrush.CreateSolidBrush(RGB(0, 0, 255)); 
pOldBrush = dc.SelectObject(&MyBrush);

// Finally, we have our device context set up with our pen and brush and can
// use them to draw. <BR>
<BR><BR>//Draws a rectangle that is red on the outside, filled in blue 
dc.Rectangle(0, 0, 200, 200); 
dc.SelectObject(pOldPen);
dc.SelectObject(pOldBrush);

The main thing to understand is that I select a pen or brush and it remains there until I select another, and that the opportunities to leak memory are many, and not exactly easy to debug. In contrast the GDI+ model revolves around creating a graphics object, like so:

CPaintDC dc(this);
Graphics graphics(dc.hdc); 
Now this object is holding our DC until we destroy or release it, and we use this object to manipulate our device context. All the functions take the pen or brush they use, meaning no memory leaks, and ease of writing code that draws in more than one colour. Before presenting an example, let me point out one more exciting thing about GDI+. In GDI we used COLORREF as a variable that held a colour. It was a typedef for a DWORD, and a COLORREF was built using the RGB macro. Colours could be retrieved using GetRValue, GetGValue and GetBValue. In contrast, GDI+ uses the COLOR class, which takes four values to contruct - the extra being alpha. If you are not familiar with the concept of alpha transparency, imagine you are looking through a stained glass window. The colours of the glass affect what you see behind the glass, but the degree to which they obscure your vision depends on how thick the glass is. Alpha transparency similarly blends the colour you use to draw with the colour of the canvas beneath it. Colors in GDI+ are ARGB, the alpha value is specified first. So to draw a line we can do the following:
Pen MyPen(Color(255, 0, 255, ));  // A green pen, with full alpha
graphics.DrawLine(&pen, 0, 0, 200, 100);

GDI+ also dispenses with the idea of a current position: in GDI we used MoveTo(point), followed by LineTo(point). Now we specify both points at once.

I've provided an example program designed to facilitate experimentation by giving you the necessary framework to play with some code, and also to run and see how alpha works, if you've not seen this before. The drawing code creates a pattern in red and blue, then draws over with green, then magenta, and the alpha value fades first up and down, then from left to right.

The OnPaint method of the example program looks like this:

using namespace Gdiplus;

CPaintDC dc(this);

Graphics graphics(dc.m_hDC);

// Pen can also be constructed using a brush or another
//pen. There is a second parameter - a width which defaults to 1.0f
Pen blue (Color(255, 0, 0, 255));

Pen red (Color(255, 255, 0, 0));
int y = 256;
for (int x = 0; x < 256; x += 5)
{
	graphics.DrawLine(&blue, 0, y, x, 0);
	graphics.DrawLine(&red, 256, x, y, 256);  
	y -= 5;
}		
for (y = 0; y < 256; y++)
{
	Pen pen(Color(y, 0, 255,0));
	// A green pen with shifting alpha 
	graphics.DrawLine(&pen, 0, y, 256, y); 
	// The sleep is to slow it down so you can watch the effect 
	Sleep(20);
}		
for (x = 0; x  < 256;  x++)
{
	Pen pen(Color(x, 255, 0, 255));
	// A green pen with shifting alpha 
	graphics.DrawLine(&pen, x, 100, x, 200);
	// The sleep is to slow it down so you can watch the effect
	Sleep(20); 
}

This marks the end of my first GDI+ tutorial. My aim was simply to get you up and running - to show you how to set up a program to use GDI+ and explain some basic concepts about the way it is set up. My next tutorial will be on using brushes - with GDI+ you can make a brush display a gradient, or even be textured with a bitmap. Stay tuned - the real coolness is about to begin...

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

 
GeneralMy vote of 5 Pin
Chris Favreau9-Sep-16 7:20
Chris Favreau9-Sep-16 7:20 
GeneralMy vote of 2 Pin
Ahmed Han2-Dec-14 11:32
Ahmed Han2-Dec-14 11:32 
GeneralRe: My vote of 2 Pin
Christian Graus2-Dec-14 11:36
protectorChristian Graus2-Dec-14 11:36 
GeneralRe: My vote of 2 Pin
Ahmed Han2-Dec-14 11:42
Ahmed Han2-Dec-14 11:42 
GeneralRe: My vote of 2 Pin
Christian Graus2-Dec-14 11:45
protectorChristian Graus2-Dec-14 11:45 
GeneralResize large image on windows mobile 6 Pin
Mayur Dhamanwala27-Apr-08 2:39
Mayur Dhamanwala27-Apr-08 2:39 
GeneralThanks Pin
Laura4-Dec-07 0:30
Laura4-Dec-07 0:30 
QuestionCapturing screen Pin
abc_nus_student27-Nov-07 23:00
abc_nus_student27-Nov-07 23:00 
GeneralThanks! Pin
Leslie Sanford29-Sep-07 19:07
Leslie Sanford29-Sep-07 19:07 
GeneralFiles needed urgently Pin
HakunaMatada7-Aug-07 0:37
HakunaMatada7-Aug-07 0:37 
QuestionSetPageUnit method Pin
Tulio8-Jul-07 15:25
Tulio8-Jul-07 15:25 
GeneralType mistake Pin
monteiz21-May-07 22:50
monteiz21-May-07 22:50 
Generala Pin
simona_onesti13-Feb-07 23:25
simona_onesti13-Feb-07 23:25 
GeneralRe: a Pin
Christian Graus14-Feb-07 9:28
protectorChristian Graus14-Feb-07 9:28 
GeneralPlease help me : Facing one problem Pin
chandra@codeproject6-Dec-06 19:41
chandra@codeproject6-Dec-06 19:41 
GeneralRe: Please help me : Facing one problem Pin
Christian Graus14-Feb-07 9:29
protectorChristian Graus14-Feb-07 9:29 
GeneralGDI + Pin
an_handsome1-Dec-06 22:47
an_handsome1-Dec-06 22:47 
GeneralRe: GDI + Pin
Christian Graus14-Feb-07 9:29
protectorChristian Graus14-Feb-07 9:29 
QuestionError in compiling this program(VC++ 6.0) Pin
Dhananjayak0212-Aug-06 23:52
Dhananjayak0212-Aug-06 23:52 
AnswerRe: Error in compiling this program(VC++ 6.0) Pin
Christian Graus13-Aug-06 0:50
protectorChristian Graus13-Aug-06 0:50 
GeneralRe: Error in compiling this program(VC++ 6.0) Pin
Dhananjayak0213-Aug-06 5:12
Dhananjayak0213-Aug-06 5:12 
GeneralRe: Error in compiling this program(VC++ 6.0) Pin
Dhananjayak0213-Aug-06 5:40
Dhananjayak0213-Aug-06 5:40 
GeneralRe: Error in compiling this program(VC++ 6.0) Pin
Christian Graus13-Aug-06 11:37
protectorChristian Graus13-Aug-06 11:37 
GeneralRe: Error in compiling this program(VC++ 6.0) Pin
yv312-Nov-08 8:28
yv312-Nov-08 8:28 
QuestionAdding a GIF image in VC++ 6.0 Pin
Dhananjayak0212-Aug-06 4:19
Dhananjayak0212-Aug-06 4:19 

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.