CIS Logo SVC Logo

   Computing & Information Systems
   Department

 

Schoology Facebook        Search CIS Site      Tutorials

Software Design Using C++



Single Document Interface with Visual C++ 6.0



Drawing Simple Graphics



1) Overview


These directions apply to Visual C++ 6.0 specifically. The task is to write a Windows app that draws simple graphics. We will use the AppWizard's single document interface. We will place an additional button on the toolbar for the user to click on to add a new drawing on the screen.

2) Using AppWizard


Begin by making a new project of type "MFC AppWizard (exe)". Use this screenshot as a guide. Name the project Drawings. Be sure to choose the single document interface. Use the default values for all of the other AppWizard items. (Note that as discussed under the Dialog-based Interface section, you might want to choose the Statically Linked option instead of the "Shared DLL" option, particularly if you want to use your .exe file under various versions of Windows. See this picture of the choice.)

3) Change the About Box and Copyright


Click on the Resource View tab and expand the Dialog folder for the Drawings project. Double click on IDD_ABOUTBOX and then click on the Copyright line. Right click and select Properties. Change the caption to one word: Freeware. You can then close the window used for editing the About Box by clicking on the x close button just below the main x close button for Visual Studio itself.

In Resource View expand the Version folder and double click on VS_VERSION_INFO. Double click on Copyright (C) followed by the year. This should let you modify this item to also say Freeware. Do File, Save All. Close the window used to edit the version information.

4) Changing the Menu


Expand the Menu folder in Resource View if necessary. Double click on IDR_MAINFRAME. In the menu editor click on File. We want to delete each item on the File menu except for Exit. Click on each such item and press the Delete key. Even delete the separator bars between menu items, but do not try to delete the blank menu item below Exit. Click on the Edit menu and press Delete in order to remove the entire Edit menu. Leave the View and Help menus alone. Do File, Save All, and close the window used to edit the menu bar.

5) Modifying the Toolbar


In Resource View, expand the Toolbar folder if need be. Double click on IDR_MAINFRAME. You should see the standard toolbar. Then drag off of the toolbar every button except the print button, the about button (with the question mark on it), and the blank button. Click on this blank button. Then use the drawing tools to draw a blue rightward pointing arrow on the large grid picture of the blank button. (Just click on the blue color and then click on a square in the grid to color that square blue.) This will be your button for displaying the next drawing. While this button is still selected, click on View, Properties, and change the ID to ID_BUTTON_NEXT. Also fill in the following as the prompt:


Display the next drawing\nNext

See this screenshot of the revised Toolbar Button Properties. This change will allow the user to place the mouse pointer over the button to get information about it. The word Next will be shown near the button when this happens, and "Display the next drawing" will be shown on the status bar at the bottom of the window. You can view the properties of each of the other buttons by clicking on them one at a time and using View, Properties to see what data is recorded. Finally, drag your new blue arrow button to the leftmost position on the toolbar. Do not worry about the fact that there is a new blank button on the toolbar as it will not show up in the completed application. Do File, Save All. Close the window used to edit the toolbar.

6) Add a Message Map


Use this screenshot as a guide in the first part of this paragraph. Next, add a message map (function) to handle things when the user clicks on your new button. Use View, ClassWizard and click on the Message Maps tab if necessary. Check that CDrawingsView is the class name selected. Under Object IDs select ID_BUTTON_NEXT, the ID for the button that you just created. Under Messages click on COMMAND. Click on Add Function. The default name of the function should be fine, so click OK. Then click on Edit Code and fill in the following code for your new function:


Count++;
InvalidateRect(NULL, TRUE);
if (Count >= 4)
   AfxMessageBox("End of sequence of drawings"); 

We need to add the Count variable to the CDrawingsView class. Do this by editing the DrawingsView.h file and add an integer Count as a private field of CDrawingsView. (You can find the DrawingsView.h file by double clicking on it in the Header Files section under the File View tab.) Note that you will have to add the keyword private, as there are probably public and protected sections in this class, but no private one.

This Count variable will keep track of what drawing(s) we are to display. When Count is 0 we will display only the initial drawing. When Count is 1 we will display the first 2 drawings. When Count is 2 we will show the first 3 drawings. When Count is 3 we will display all 4 drawings. Finally, if Count is 4 (or greater), the above code pops up a message box that tells us that there are no more drawings. The InvalidateRect function call above causes the OnDraw function to redisplay the window. Do File, Save All.

7) Drawing Graphics


Speaking of the OnDraw function, find the outline for this function in the DrawingsView.cpp file. (If need be, double click this file in the Source Files section of Files View.) Change the code for this function to the following:


CDrawingsDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);

CPen NewPen;
CPen * OldPenPtr;
CBrush NewBrush;
CBrush * OldBrushPtr;

NewPen.CreatePen(PS_SOLID, 1, RGB(0, 180, 180));  // aqua color
OldPenPtr = pDC->SelectObject(&NewPen);

if (Count >= 0)
   {
   // Place a message in a rectangle:
   pDC->TextOut(150, 50, "This is a test", 14);
   pDC->MoveTo(100, 10);
   pDC->LineTo(100, 110);
   pDC->LineTo(300, 110);
   pDC->LineTo(300, 10);
   pDC->LineTo(100, 10);
   }
   
if (Count >= 1)
   {
   // Draw a circle:
   NewBrush.CreateSolidBrush(RGB(0, 255, 0));  // to fill with green
   OldBrushPtr = pDC->SelectObject(&NewBrush);
   pDC->Ellipse(350, 10, 550, 210);
   pDC->SetTextColor(RGB(0, 0, 255));  // blue text
   pDC->SetBkMode(TRANSPARENT);
   pDC->SetBkColor(RGB(0, 255, 0));   // green background color
   pDC->TextOut(400, 90, "Circle", 6);
   // Switch back to normal values:
   pDC->SetTextColor(RGB(0, 0, 0));   // black
   pDC->SetBkMode(OPAQUE);
   pDC->SetBkColor(RGB(255, 255, 255));   // white
   pDC->SelectObject(&NewBrush);
   NewBrush.DeleteObject();
   }

// Deselect pen:
pDC->SelectObject(&NewPen);
NewPen.DeleteObject();

if (Count >= 2)
   {
   // Draw a polygon:
   POINT PointArray[6];
   PointArray[0].x = 100;
   PointArray[0].y = 160;
   PointArray[1].x =  50;
   PointArray[1].y = 210;
   PointArray[2].x = 160;
   PointArray[2].y = 260;
   PointArray[3].x = 200;
   PointArray[3].y = 310;
   PointArray[4].x = 300;
   PointArray[4].y = 200;
   PointArray[5].x = 100;
   PointArray[5].y = 160;

   NewPen.CreatePen(PS_SOLID, 2, RGB(255, 0, 0));  // red, double width
   OldPenPtr = pDC->SelectObject(&NewPen);
   NewBrush.CreateSolidBrush(RGB(10, 200, 70));   // a greenish color
   OldBrushPtr = pDC->SelectObject(&NewBrush);
   pDC->Polygon(PointArray, 6);

   pDC->SelectObject(&NewPen);
   NewPen.DeleteObject();
   pDC->SelectObject(&NewBrush);
   NewBrush.DeleteObject();
   }

if (Count >= 3)
   {
   // Draw a smiley face:
   NewPen.CreatePen(PS_SOLID, 1, RGB(0, 0, 255));  // blue
   OldPenPtr = pDC->SelectObject(&NewPen);
   NewBrush.CreateSolidBrush(RGB(255, 255, 0));  // to fill with yellow
   OldBrushPtr = pDC->SelectObject(&NewBrush);
   pDC->Ellipse(360, 240, 480, 310);
   pDC->SetPixel(400, 260, RGB(0, 0, 255));   // draw one pixel
   pDC->SetPixel(440, 260, RGB(0, 0, 255));
   pDC->SetPixel(420, 270, RGB(0, 0, 255));
   pDC->Arc(380, 260, 460, 290, 380, 275, 460, 275);
   pDC->SelectObject(&NewPen);
   NewPen.DeleteObject();
   }

The comments in the code above and the obvious names of many of the functions will give you a good idea of what the code does. Use Help, Search to look up any details that you need on a particular function. It would help to know that for drawing on the screen the upper left corner has coordinates (0, 0) and that the x coordinate increases as you go horizontally across the screen to the right, while the y coordinate increases as you go downward on the screen.

In the same DrawingsView.cpp file find the CDrawingsView constructor and put the following one line of code in it to initialize Count:


Count = 0;

Do File, Save All. Do Build, Build Drawings.exe and fix any minor errors that are noted. Then run your application by clicking on the ! button on the toolbar. When it first starts you should see a rectangle with the first little drawing in it. Clicking on the right arrow button should then add the second drawing, etc. Compare what you get with this picture of the results.

8) For Further Practice (Optional)


You might want to modify the above program to draw something of interest to you. You can look up the list of drawing commands by using Help, Search and looking for CDC (the device context class). Double click on the item that says "CDC class members". If you know the name of the particular function, such as Ellipse, that you want to look up, you can of course look it up directly.

Related Item


Single Document Interface with Visual C++ .NET

Back to the main page for Software Design Using C++

Author: Br. David Carlson with contributions by Br. Isidore Minerd
Last updated: August 27, 2009
Disclaimer