Dal's Programming Course - Lesson 04

Drawing text with Gdiplus

In this lesson you will learn how to use Gdiplus to draw text. Why devote an entire lesson to drawing text? After all, drawing and printing text is a fundamental job of computers -- it should be easy to do.

Well, it used to be easy, but displaying text can be very complicated. First, you must worry about the "font", and then the size of the characters, their position on the screen. Lots of parameters are involved.

Another complication that has come up in recent years is the multilingual programming. One byte is no longer able to hold all the possible characters, so wide characters have been invented. A wide character consists of two bytes. In Windows, the type for wide character is WCHAR. Gdiplus insists on using wide characters.

You should know that there are lots of ways to represent character sets for non-English languages -- the situation is very complicated, and more than we will tackle in this course.

If you can work through drawing text with Gdiplus then you probably can take on any drawing job.

Materials for this Lesson: Download.
Homework

Item

Time

Description

1 3 Mins All drawing on a window is done by the Paint() routine. Paint() can call other routines to get the job done, but you must have all the information necessary for painting stored somewhere in your object for use at the time of painting. That is, you cannot just draw something on a Window and forget what you drew, because you cannot predict when Windows will need to redraw it again. (What if the window was covered up by another window, and then uncovered?) Therefore, you will have to have a place to store the string you want to draw on the window. Also you will need a way for an external caller to specify what string to draw in the window. Get started on this by creating a method in mcTopLevelWindow called SetText(). Make it accept a normal C-style string as an input argument... (Hint, the prototype should be: SetText(const char* sText)).
2 10 Mins Next, make SetText() store the input string in the object, as a wide string. If you are working in normal English (we are), then you can convert normal strings into wide ones by setting the first byte of the wide character to zero, and the second byte of the wide string to the original byte. (A simple assignment between a WCHAR and a char will do this.)
3 10 Mins Revisit your work in #2 above, and make sure that you set limits on the input length of the string so that you don't overrun any boundaries. If you used the heap to store your string, make sure you initialized your pointer in the class constructor, and that you check to make sure null was not returned when you allocated room. If the pointer was a null, exit the program with an error message.
4 2 Min Once again check your work to make sure the string is initialized in the constructor, no matter what method you are using to store it. After all, if SetText() is never called by an external entity, then you still want your Paint() routine to not mess up.
5 10 Mins Now, you are almost ready to draw the string. Review the following Gdiplus objects and functions.
Fontfamily
Font
StringFormat
Graghics::DrawString()
Note that to draw a string, you will need to create an instance of each of these objects, as well as a SolidBrush.
6 10 Mins Write a function named RenderText(). Its purpose is to draw the stored string in your mcTopLevelWindow class on the window, near the top. Make the text black and about 30 pixels high. The input argument to RenderText() should be a pointer to a Graphics object. Draw the text into the Graphics object. You will need to create a Fontfamily. Use "Arial". Another hint: you can specify a wide string literal with an "L" before the string, as in WCHAR *pS = L"Arial";.
7 5 Mins Modify your Paint() function so that it calls RenderText(). Also, modify your MainApp.cpp so that it calls SetText() with a "Hello" string. Test your program. You should see "Hello" written in the top of one of your windows.