A WinApp HowTo



A WinApp HowTo

In this section there will be a walk through of a simple template program that implements a WinApp using a Smalltalk style Model-View-Controller (MVC) framework. The App consists of a resisable window with a scalable and scrollable drawing area and a printable 'page'.

What this does then is basically to emulate the functionality of the program that is initially produced when you first run AppWizard, and so may act as the basis of an SDI WinApp.

It don't do much, but it still does a bit more than a pure generic template should, since there is some code included to allow the rescaling of the scalable area either with a dialog box or by clicking and dragging with the mouse in the are itself. These will probably be taken out before any other coding starts and so maybe shouldn't be there in the irst place, but they are, so there.

This code should be fairly readily understandable by most people with a good grounding in C++ although of course the details of the Classes will need explanation.

The Model-View-Controller

The Model-View-Controller framework comes origionaly from the smalltalk OO language and is essentially a way of dividing up the work of GUI Apps into logical sections.

The Model class will contain everything concerned with data and data processing. For example, in the case of a wordprocessor these will be dealing with the document itself and will include things such as loading and saving from disk, arranging the document in memory and retreiving, setting or altering parts of the document.

The View class will contain the bulk of the functionality connected with the GUI. This means essentially drawing the contents of the window and also handling events such as key presses and mouse clicks and drags. There may be more than one view to allow the data to be looked at in different way i.e. in the case of a spreadsheet as a table or a graph. There may also be some dialog boxes connected with the App, these may be thought of a sub-views (see also about the Resource File below).

Finally, bringing everything together is the Controller. Classicaly it's a single class which sets up and runs the App and then acts as the interface between the OS and all the various other parts of the program. However, due to the nature of MS-Windows, these two things are carried out by different classes, and so there is no Controller class as such, but instead, all of the various bits are stuck in the Controller module.

The way in which the Controller acts as the OS-to-program interface is as follows: WinApps are event driven. That means that for a lot of the time they may be sitting there doing nothing, but every so often the WinOs will send a message to notify them that something has happened (an Event) to which they must respond.

These Windows messages are normally defined as WM_SOMEMESSAGE and may be things like WM_KEYPRESSED, WM_MOUSEDRAGGED, etc. The Controller then will need to be able to intercept all of these various Windows messages that get sent by the OS and then it must decide what to do i.e., which particular function should be called to handle what. This is done by the Message Map which simply maps one Window Message to one function (see the Controller section below for more on this.)

Finally there will need to be some other miscellaneous items, such as a Windows Resource (*.RC) file to include information on things like dialog boxes, icons and menus, and also all the various other modules and classes which may be utilised by any or all of of the MVCs.

In figure 1 this interaction is shown diagramatically.

			  ________ 
 __________              |        |
| c:\      |             | dialog |           _________
|          |             | boxes  |          |         |
|          |             |________|      ----|  model  | 
|__________|   ____     _____|______    /    |_________| 
   _|__|_     |    |   |            |---          | 
  |______|----| OS |---| controller |             |
 __________   |____|   |____________|---      ____|____ 
| :::::::: |    |                       \    |         | 
|__________|    -----------------------------|  view   |
					     |_________| 

FIG. 1 The interaction between the Controller, Model View and OS.




The microsoft bastardised approach

It should be noted that MS do sort of follow this methodolgy even though they don't actually admit to it. They claim to use a "Document/View" system (c.f. Model/View) with the work of the Controller split between the remaining parts. This claim has a few problems though.

[i] First of all it's not even stricly true. If you create program called 'draw' with AppWizard, as well as the drawdoc.cpp and drawview.cpp there is also a draw.cpp which does in fact do a lot of the usual controller functions.

[ii] Secondly, the message map is spilt into two parts, one in drawdoc.cpp and one drawview.cpp, and this is quite simply, an increadibly stupid thing to do. The message map is the true core of the Controller. It takes the raw messages from the Windows OS and decides which function in which class should handle them. Even in something as simple as the Scribble App outlined in the MSVC Welcome Guide they come across problems with this, when they realise that one of their messages does not neatly go into either.

An MVC example

Getting back to the MVC, here is a talked through example of how it all might work together. Consider the chain of events that will occur if, whilst in the middle of typing with a wordprocessor, you decide to select a line of text and cut it.

[i] First of all the OS will send message to the Controller that a click and drag with the mouse is occuring.

[ii] The Controller will have to call the View to tell it to handle this click and drag.

[iii] The View will need to redraw the Window with the selected text marked out somehow (noramlly in inverse video.)

[iv] Everytime the mouse is moved a little bit, [ii] and [iii] will be repeated.

[v] Once the button is released the Controller will be informed and will need to call the View in order to find out which text has been selected.

[vi] When the selected text is cut Controller must first tell the Model to remove the text from the document and then tell the View to redraw the screen using this updated document.

Main Parts of the WinApp

This will just take the three main parts, the Model, the View and the Controller, plus the Dialog boxes, and consider then one at a a time. As can be seen from the previous section however, the working of the program does require a lot of interaction between each of these.

The Model

This then is the core data handling part of the program, and as befits a template program demonstrating GUI handling, it is in this example extremelly small. What is going on here is pure standard C++ programing, the only exceptional part being the way in which it will fit in with the rest of the framework.

See here for a walk through of part of the Model code.

The View

This is where the bulk of the screen handling is done (with the exception of dialog boxes - see below!). It's job is to (when told by the Controller) retrieve any information it may need from the Model or elsewhere, and then draw what is required on the screen.

I've tried to make the drawing as generic as possible. Figure 2a shows the three main screen areas and Fig. 2b attempts to demonstrate how the scrollabel window looks at these one segment at a time.

 ____________________________     ____________________________
|                            |   |  ========================  |
|  table                     |   | |=======================|| |
|     __________________     |   | ||  __________________  || |
|    |                  |    |   | || |                  | || |
|    |  page            |    |   | || |                  | || |
|    |                  |    |   | || |                  | || |
|    |  _____________   |    |   | || |  _____________   | || |
|    | |             |  |    |   | || | |             |  | || |
|    | |    frame    |  |    |   | || | |             |  | || |
|    | |             |  |    |   | || | |             |  | || |
|    | |             |  |    |   |  ========================  |
|    | |_____________|  |    |   |    | |_____________|  |    |
|    |                  |    |   |    |                  |    |
|    |                  |    |   |    |                  |    |
|    |                  |    |   |    |                  |    |
|    |__________________|    |   |    |__________________|    |
|                            |   |                            |
|                            |   |                            |
|____________________________|   |____________________________|

Figure 2a: The three main         Figure 2b: A scrollable 
parts of the screen               Window overlaying the screen

There are three main regions to the viewable area are the 'table' 'page' and 'frame'.

i. The page is the main drawing area. What goes on here is what gets printed, which is after all normally the end result of everything. The units are in 0.1mms and the origin is the top LH corner with the y-axis positive pointing down.

ii. The purpose of the table is to set the page neatly on the screen and to help setting the scrolling area of the window. It has the same units as the page and the origin is simply that of the page with an added offset.

ii. Finally, the frame gives a scalable drawing area, that allows the axes to be set to any value, direction e.t.c. This same thing could have been implemented by using various windows commands to the make the Window itself all scaled, but this then stops a lot of other commands working, for example, setting the origin at the bottom LH corner means that any region commands (such as IsPointInRegion()) no longer work.

See here for a walk through of part of the View code.

The Controller

This is the routine that links everything together. Windows Messages that are sent by the OS are intercepted by the Controller which routes them to the apporpriate function.

In MFC this is done by a derived CWindow class, which is separate to the main application class, CApp. However, they are both put in the Controller module since they both most logically seem to fit here.

See here for a walk through of part of the Controller code.

Dialog Boxes

Uh Oh?!?! What are these and why are they here when this is supposed to be an MVC framework?? Surely not another naff MS add-on designed to spoil everthing!!!

Well, actually no, as they do in fact sort of fit in correctly to the framework. They can be thought of as mini self-contained views that do their own little jobs and also possibly exchange data with either one of the Model, View or Controller. As an example, a File Open dialog box will pass back the name and path of the file to be opened, allowing the actual file opening to be be carried out by the Model.

This idea of multiple views is in fact completely kosher and is fundamental to the MVC way of thinking. Most large WinApps will have a single Model class, but several View classes to allow the data to be examined in different ways. For example a spreadsheet will have the grid View for typing in and modifying data but then also several other Views to represent the same data as graphs of varying types (pie, block, line etc.) By separating the Model and View we have a convenient way of eliminating code overlap.

Each dialog box has it's own class and of course Window set up. The Windows are not drawn so much as defined in the Resource (*.RC) file using a sort of pseudo code. The good news though is that almost every Windows compiler comes with a nice little App which allows these to be created graphically, usually by dragging elements (buttons, list boxes, etc) into place and giving them an ID. Once back in the code you simply call the required MFC function with the element's ID as a parameter and off you go manipulating data at will. This all leads to a relativly straight forward way of getting it done. A bit like Visual Basic really!

The full Template Code

Here as promised is the full code.

click here to download a ZIP of the WinApp Template code.

It should compile on any version of MSVC from 1.52 (the most up to date 16 bit version) upwards to whatever it's at now (5.0, 6.0??). This code will however be most stable on any 32 bit version, most of the work I've done has been on MSVC 2.0 for no reason other than I happen to have a full registered copy of it.

Adding more functionality

Going on from here to write a useful App means a lot of delving into the depths of MFC. The only way to do this really is to get coding yourself, and that means really having to look at lots of examples (check out the JCPlot Homepage for a bigger program written using this method, plus the MFC examples and of course the internet ad infinitum) sorting out suitable text books, or if all else fails by reading the MS manuals and help files.


return to main page
Hosted by www.Geocities.ws

1