Your homework assignment is to demonstrate an understanding of document/view architecture, as well as file access using MFC. You are going to write a simple draw program that saves and loads free-hand drawn pictures, but also imports and exports the coordinates of the pictures from and to normal text files.
You will need to create/modify the following resources:
You will need to add an Import menu item, under the File main menu.
You will need to add an Export menu item, under the File main menu.
Change the 32x32 and the 16x16 icons, for the document, and the main frame. You will see 2 icons in your project after AppWizard creates it, named IDR_MAINFRAME and IDR_appTYPE. The IDR_MAINFRAME is the application icon, and the IDR_appTYPE is the document icon (displayed by Explorer, in Windows).
In each of these two icons, there is a combo-box that gives the choice of 32x32 and 16x16. This means that in reality, there are 4 icons, not 2. Make sure you change them all.
The actual appearance of the icons, is up to you, but they must be modified (A big red 'D' for the Document icon and a big red 'A' for the application icon is perfectly acceptable for the artistically-challenged).
You must modify the About dialog box, to contain your name, and your program icon.
Normally, when your document is saved or loaded, it will use the standard Serialize functionality, and it will save and load it's coordinate in a space-efficient binary mode. This program however also provides an import and export feature where the coordinates for a drawing may be imported from or exported to a text file.
The format of the text file is the X coordinate for a point, a space, the Y coordinate for a point, and then a carriage return. This is repeated for as many points as needed. A start of line segment is indicated as a coordinate of -1, -1. An example file that would draw a square would look like the following:
The document class has functions that implement the import and export process, and the View class has functions to handle the Import and Export menu choices and choose the filenames.
Your Document class will have the primary responsibility of storing the points for the picture in memory, as well as all file I/O. It will not only implement the Serialize function, but will also have specialized functions called ImportFrom and ExportTo where it will import and export it's coordinates with normal text files.
The document class also has interface functions to allow the view class access to the points collection.
This should be a CArray collection class, that is composed of CPoint objects. It should be a protected data member (the document will provide interface functions as needed). This one array collection class handles all the coordinates for the picture.
Since the picture is made up of separate lines, the array has a special 'flag coordinate' of -1, -1. When this coordinate is found in the array, it doesn't mean a coordinate of -1, -1 but means that the next coordinate is actually the start of a new line segment (instead of the continuation of a line).
void AddPoint( CPoint& point )
Public function, that is used to add point to the Points collection member.
void ExportTo(const char *Filename)
Exports the list of points in the Points collection member to a text file. The filename is specified in the Filename parameter. This function must open the file (create it if needed), and write the points out in text format. See Import/Export for more details.
void GetPoint( CPoint& Dest, int Index )
Retrieves the point specified by Index from the Points collection, and stores it to Dest.
Public function, that returns the number of points in the Points collection.
void ImportFrom(const char *Filename)
Imports a list of points from a text file whose name is specified by the Filename parameter. The previous contents of the Points array are first cleared out, and then the points from the file are loaded. See Import/Export for more details.
bool IsStartSegment( CPoint& Point)
This function determines if Point is a line-segment start coordinate or not. A line segment start coordinate is -1, -1.
void StartSegment( CPoint& Point )
Starts a new line segment, and stores point as the first coordinate of the new line segment. A line segment start is indicated as a point of -1,-1 in the Points collection. (This function should place 2 coordinates into the Points collection, -1,-1 and then point).
Your view class will be a CView-derived class.
This represents the last mouse point drawn to, and is used primarily during the mouse down and mouse move message handlers. It is not used by OnDraw. Protected data member.
A flag that indicates if the left mouse button is down. Set in the mouse down handler, cleared in the mouse up handler, and inspected in the mouse move handler.
Note: All of the Views functions are added via ClassWizard and message maps, except for OnDraw which is already provided.
void OnDraw(CDC* pDC)
This function must draw the picture. It does so by using the document class function to get the number of points, and draw each line from coordinate to coordinate. The document interface functions are used to get the number of points, get each point, and determine if a point is actually the start of a line segment. Drawing a single line segment is a MoveTo followed by several LineTo's, for each coordinate in the segment.
void OnLButtonDown(UINT nFlags, CPoint point)
Handler for the WM_LBUTTONDOWN message. This function sets the mouse-down flag to true, saves point as the last mouse position (m_LastPoint), and also adds point to the document class, as the start of a new line segment.
void OnLButtonUp(UINT nFlags, CPoint point)
Handler for the WM_LBUTTONUP message. Sets the mouse-down flag to false.
void OnMouseMove(UINT nFlags, CPoint point)
Handler for the WM_MOUSEMOVE message. If the mouse-down flag is false, it does nothing. If it's true then this function will store point into the document class, then draw a line from the last mouse position to point, and finally set m_LastPoint equal to point.
In order to draw the line, it must call the CWnd::GetDC() function of the View class to get a CDC*. With this pointer, is does a MoveTo and LineTo, and then finally calls CWnd::ReleaseDC to release the CDC *.
Handler for the Import menu item. This function opens a file-open common dialog using the CFileDialog class. Before doing this, it calls the OnNewDocument function for the document, giving it a chance to save itself if needed. After OnNewDocument returns TRUE, the File Open dialog is invoked.
If the CFileDialog's DoModal function returned true, then the CFileDialog's GetPathName function is called to get the name of the file the user selected. This file name is passed on to the ImportFrom function of the document class.
This function should call InvalidateRect to force the view to re-draw the new document data.
Handler for the Export menu item. This function opens a file-save common dialog using the CFileDialog class. If the CFileDialog::DoModal function returns IDOK then it's filename is taken using the CFileDialog::GetPathName function, and that file name is passed on to the document's ExportTo function.