CS-183
C++ Program #5
Inheritance and
Polymorphism
Date Assigned: Monday
October 29, 2001
Date Due: Friday November 9, 2001
In the lecture, we’ve developed a simple set of classes that represent various graphical shapes. The “shapes” abstraction is achieved, in part, by the use of C++’s inheritance and polymorphism mechanisms. The assignment is to implement at least five types of shapes (Lines, Fancy Lines, Circles, Squares, and Rectangles), and provide a simple user program that iterates through a container of various shape objects, drawing each shape in the correct visual manner. Feel free to use the STL container and iterator classes (rather than your own linked list program), if you are not satisfied with your own “templated lists with iterators” implementation.
This project will be done using two-person “extreme programming” teams. Remember, the tenements of extreme programming are to describe the design completely to one another before coding; test each unit as it is being developed (write the test case code before implementing the system features); frequently revisit earlier design/implementation decisions; etc. The team project is to produce a report that describes the design decisions and implementation details of your work, along with well-commented source code that can be rebuilt and run in the Visual Studio C++ environment. Submit the report in either .doc or .pdf format, and submit all files and instructions necessary for me to rebuild your project from scratch.
Initially, concentrate on getting the inheritance and polymorphism working without worrying about how the graphics render themselves. This can be accomplished by having the draw function for each class simply print out a message to the console announcing that it is drawing a circle centered at point (3, 4) with a radius of 2.3 (for instance). Then, having mastered the above, create a Windows application that actually draws the shapes on a graphics screen. The details of how to build a simple Windows program can be found in the “Introduction to MFC” (thin blue paperback) book that accompanies your textbook by Deitel. Also, there’s a brief paper on the course web page that boils down the task of using simple pen graphics. Feel free to browse the MSOE faculty course pages for more resources on Windows, Win32, or MFC programming.
One of my past CS-183 students put together the following short paper to assist other students in programming the simple pen graphics associated with this project. The following pages contain this brief tutorial.
by Ron Beyer
Introduction
This project was created by Ron Beyer, a CS-183 student, to show students that do not have windows programming experience, how to draw simple objects on the screen. This “template” is easily expandable to include polygons, menus, and many other windows type functions. The use of this template is fully explained in this mini tutorial. To use the sample code included with this tutorial, create an empty “Win32 Application” (this project type is just above the “Win32 Console Application” selection) in Visual Studio (i.e. Visual C++ 6.0) and add the attached files (Color.h and Main.cpp) to the project, and make your modifications from there.
Customizing the Win32 Application
The first thing on your mind would probably be to rename the application. The following line changes the title of the window (yes, this is one line of code in your source file!):
if (!(hwnd = CreateWindowEx(NULL,
WINDOW_CLASS_NAME,
"Polymorphism Example",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0,0,
CAPP_WIDTH,CAPP_HEIGHT,
NULL,
NULL,
hinstance,
NULL)))
In this example, “Polymorphism Example” is the title of the window. This can be changed to anything that you want, as long as it is surrounded by double quotes (“ and “). Please make a note of the hwnd variable in the first part of this line; it serves as a variable name for the window, so it can be passed back and forth through functions, which will be used later.
Adding to the code:
There are only certain places where you can enter code so that template will still work correctly. These areas are often denoted by the following remarks:
//Insert code here --------------------------------------------
//Don’t go past here -----------------------------------------
Please insert your code between these comments (the comments can be deleted if you like). The first thing you might notice is the lack of the main( ) function. Windows uses the name “WINAPI WinMain” as its default main function. You must put all of your initialization code (creating of your classes, variables, etc.) right before the main while( ) loop. No code should go inside the while loop (unless you wanted to run your program in a loop).
Drawing the graphics:
There are four types of built-in graphics that you can draw. They are:
· Line
· Rectangle
· Circle
· Text
Line Function:
This function takes 6 parameters, and the prototype is as follows:
void Line(int x1, int y1, int x2, int y2, COLORREF color, HWND hwnd);
This function is pretty self-explanatory, the first four values are the starting and ending coordinates (respectively), and color is of type COLORREF, which could be one of the colors in the header, or one of your own defined as follows:
COLORREF colorname = RGB(red, green, blue);
Where colorname is any variable name that you would like, and red, green, and blue are integer values from 0 to 255 describing intensity. The last parameter, which you might remember, is the window itself. Always leave this parameter as hwnd. Here is an example of a blue line that starts at 100, 100, and ends at 500, 500:
Line(100, 100, 500, 500, Color_Blue, hwnd);
Rect Function:
This function is very similar to the line function and also takes 6 parameters, the prototype is as follows:
void Rect(int x1, int y1, int x2, int y2, COLORREF color, HWND hwnd);
This function works just like the line function, only this draws a rectangle filled with the color that you specify. Here is and example of a green rectangle that starts at 10, 10, and ends at 300, 300:
Rect(10,10,300,300,Color_Green,hwnd);
Circle Function:
This function is also pretty easy to understand, it only takes 5 parameters, and the prototype is as follows:
void Circle(int x, int y, int rad, COLORREF color, HWND hwnd);
Again, the function is mostly self-explanatory, the x and y values specify the center of the circle, the color takes a color, and the last parameter is the window we are working on. Here is an example of a circle centered at 150, 200 with a radius of 50 and color red:
Circle(150, 200, 50, Color_Red, hwnd);
Text Function:
This function is nothing like the cout or printf functions, it can take up to 5 parameters, and the prototype is as follows:
void OutText(COLORREF color, string str, HWND hwnd, int x, int y);
The first three parameters are required, which is the color of the text, the text itself (a string object) and the hwnd handle. The last two parameters can be omitted if you want it to print in a normal line by line style, starting in the top left corner of the screen. If you do specify a position, however, please be mindful of how long your text is, because it will not wrap to the next line. After you specify the position of the text, the next call with the omitted x and y will start underneath the previous text at the left of the screen.
Just a couple other notes:
· The screen is 640x480
· The top left corner is (0, 0)
· The bottom right corner is (639x479)
· The center is (320, 240)
· The screen cannot be resized or minimized, otherwise all the graphics printed at that time will be lost. This is not a bug, but the only way that I can make it easy to draw on the screen. Otherwise the drawing would take place in a windows message loop, and could potentially repeat a lot, or never.
Included Colors:
· Color_Red
· Color_Green
· Color_Blue
· Color_Aqua
· Color_Yellow
· Color_Pink
· Color_Gray
· Color_White
· Color_Black
· Color_RdOrng
· Color_LtBlue
· Color_Orange
· Color_LtBlue2
Programming the project:
If you noticed the last (or next to last) parameter on all of the functions is a variable called hwnd. This is the handle to the window, and must be included in all function calls. Please also note that this variable is NOT a global object, so if you plan on drawing from your draw() functions, you must pass this variable to the function, and it cannot be made a default parameter like the following:
Void draw(HWND hwnd = hwnd);
The variable hwnd is of the HWND type, and it can be included in the function prototype and definition as follows:
functiontype function_name(HWND hwnd);
Experience has shown, however, that it may be better to make the window handle a data member in every shape object, which is initialized by the appropriate constructor for your shape subclass.
Addendum:
There is one thing that I neglected
to add to the documentation. There is
the functionality for the
line function to take another parameter called
linetype. Here is the
updated function prototype:
void Line(int x1, int y1, int x2, int y2, COLORREF color, HWND
hwnd,
int
linetype = PS_SOLID)
This is a default paramter,
so if it is left out, it will draw a normal
solid line. But if you would
like to draw a different kind of line (a.k.a. Fancy Line), you can put in one
of these values:
PS_SOLID This is the default parameter
PS_DASH This is a dashed line
PS_DOT This is a dotted line
PS_DASHDOT This is a line with alternating
dashes and dots
PS_DASHDOTDOT This is a line with alternating dashes
and double dots
These variables are of type
int, in case you want to store them in your
class, you can pass them
from the main function with those names to your
class, and they can be
stored in a integer variable. If you need any help
with implementing this
project, feel free to email me.
-Ron Beyer
beyerr@msoe.edu