This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes. I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.
Sudoku – love it or hate it, your choice. We are going to make a small application that you can use to assist you in solving sudoku puzzles, or just to solve them yourself and share with others if you wish. We will need some sort of form (We will only be concerned with the regular 3x3 grid of 3x3 squares, odd shaped groupings, diagonals… will not be covered, at least not in the planned articles, maybe later). Owner drawing of controls on the form and organisation by code will be demonstrated.
We will need options to save and load a game (that is not yet finished). A database to allow you to play random games would be nice. With the database storage it would be nice to be able to import and export multiple games for sharing. How about the option to undo the last action – wait why just the last action? Why not a listing of the last changes made and be able to undo lots of changes. To help you play we will be implementing visual assists – different levels of assistance no less.
Using Visual Studio – We will be using Visual Studio 2005 for this project and the uploaded files and description of steps here will be based on that. Database storage will be with Microsoft Access 2000. Please note that for those of you with the express
editions of Visual Studio the MFC classes are NOT natively supported.
In this first article we will be making modifications using the new project wizard to generate the skeleton application required, then using the resource editor to get the functionality we desire.
Sudoku is played on a grid so a form sort of display would be required. Having both a menu and toolbar buttons for the options makes it easier for the user to perform actions. A dialog based app could be a possibility but that doesn’t have the document/view architecture (re save/load) and it also doesn’t support a menu or toolbar nicely – that means we would have to code some functionality ourselves. This leaves us the SDI (or MDI) style. SDI (single document interface) makes sense – after all we can run it a number of times if we did want to play a number of games simultaneously! The form like display – well we can use a CFormView to make it look like a dialog.
Start Visual Studio and from the File menu choose New then Project. Now from the Project Types we need a Visual C++, MFC type of project (tree view at left) then from the pane at the right choose MFC Application. At the base of the form enter a name (Sudoku for example) and choose a location for the project. Click the OK button.
You are now presented with the MFC Application Wizard with an overview of the options selected by default. Here is what we want to change.
– select Single document (default is Multiple documents), leave the Use Unicode libraries option checked (actually I don’t want UNICODE, I’ll show how this ‘mistake’ is corrected in a later article).
Document Template Strings – for the File Extension enter sdk (or other file extension if you prefer, it ought to be one not in common usage)
– leave that as none! (We will be doing that ourselves later)
User Interface Features
– Uncheck the following Thick Frame, Maximize box. (Thick frame allows resizing with the mouse/keyboard)
– Uncheck the following Printing and print , ActiveX controls (not going to use any).
– select in the Generated Classes list CSudokuView, now from the combobox called Base Class we need to select CFormView.
Now click the Finish button. Confirm with yes the message about no printing with CFormView (odd – we didn’t select printing as a requirement, apparently a tiny bug in Visual Studio) and we should now be back into Visual Studio and ready to go. We can even press the F5 key and the application should compile and run, doesn’t do a lot (sudoku like) at this point though does it?
The entry boxes for the digits in sudoku grid. What control can we use for that? An edit control sounds useful but an edit control supports lots of things, We are going to choose a button instead. Buttons are designed to support owner drawing – something we will want for our hinting. Edit controls also have some built in functionality (copy, cut, paste) that we do not require and the owner drawing is also more complex.
In Visual Studio open the resource view, expand the tree items Sudoku, Sudoku.rc, Dialog, select IDD_SUDOKU_FORM and double click (or press enter key) and we see the form in design mode. If we look at the bottom right of the status bar we should see something like 0,0 and 320 x 200. The 0,0 means the top, left co-ordinates (in the design editor – this is not an onscreen setting for when the app is running) and the 320 x 200 are a width and height in dialog units (again not pixels for on screen). There is functionality to convert between pixels and dialog units and vice versa but it is something we do not require to use in the resource editor.
Using the mouse we resize the form until it is 495 x 400. The piece of text “TODO: Place form controls on this dialog” is not needed so select it with a mouse click. (This is actually a static control, I see 24,42 and 280 x 8 as is location and size parameters). Now delete the text control with the delete key. From the toolbox select button with a mouse click then on the form with a mouse click insert a button control, it will display Button1 as text. Modify the size and location so this button is something like 11,12 and 49 x 38. We are not too bothered about being exact – making things look nice will be done soon.
This stage is very important. Do not add any other controls from the toolbox until you have generated all 81 buttons, not even add then delete (I will explain why later). Now click on the toolbar copy then paste buttons. The second button will overlay the first – so drag it a bit to the right of the first button (I have 61, 14). Repeat this step to add a third button. (Note the arrow keys can be used to move controls around on the resource editor. Pressing the shift key along with an arrow button allows resizing.) We should have something like the following:
Now select all three buttons (keep shift key depressed as we drag the mouse over all three buttons) and repeat the copy / paste / move to make a crude row of nine buttons. Now select all nine buttons and repeat until we have nine rows, each of nine buttons. Now from the toolbox select picture control and add this to the form. Position and resize it to give 8, 8 and 477 x 387 (sometimes one has to try different sizes to get nice looking border spacing). This is not just to make things pretty – this has a function in the code. Select the rectangle and display the properties – The Type should be as Frame and change the ID to IDC_STATIC_BOUNDARY (from IDC_STATIC – this is a generic resource ID which can be used many times on one dialog, normally an ID is unique – only one control on the dialog can have that ID).
The dialog part of the interface is now completed. Other UI (user interface) components are still in their defaults. Some of these we require, some not and we also require some new options in menus and toolbars.
From the resource editor view open the menu branch of the tree and double click on IDR_MAINFRAME to display the menu in the resource editor. It appears in a similar fashion to what we see when the app would be run.
Click on File and we see: New, open, Save, Save As, Recent File and Exit. The underline is a visual hint for a key shortcut eg. Ctrl key + N will act as if the ‘New’ option was pressed. We want to add a play option – this will bring a random sudoku puzzle from the database for us to solve. At the bottom (below the Exit option) there is a pale grey ‘Type Here’ – Type in Play Random then press return. Now with the mouse click on this new menu item, keep the left mouse button depressed and drag it between the ‘New’ and ‘Open’ menu points. (That is how we can reorder menu points to our liking.) Right click the mouse on the ‘Play’ menu point and choose properties. In the caption field add an & sign before the capital R – on the menu you should now see the R of random underlined, now after the m enter \t then Ctrl+ R and press return. You should see the menu with the mnemonic (Ctrl+ R) right adjusted in the display. In the field labelled Prompt enter a hint eg. Play a random game from the database. This text should appear in the status bar when this menu item is selected.
For completeness if you right click the mouse on Play you should see a context menu with one option being to insert a separator, we don’t require one – but that is how one can group items on a menu.
Now click the menu item at the top labelled Edit – select and use the delete key to remove the separator and Cut, Copy and Paste options. Leave the menu point Undo – we want that later.
We are missing options for Lock, Solve, Delete and Maintenance. (I’ll explain those when they are needed). So add them to the Edit menu after the Undo and use a separator to group them separate from the Undo option. Use a mnemonic Ctrl+ L (with & for the underline) for the Lock option, the Solve just add the underline to the S but don’t enter anything for a mnemonic. Now add a separator then options called Delete and finally Database Maintenance. Add something to the prompts for each of these new options eg. ‘Lock a game’, ‘Solve a game’, ‘Delete a game’, ‘Organise games in the database’.
From the resource view open the Accelerator and double click the IDR_MAINFRAME. This is where the keyboard shortcuts can be organised. (We have added hints to the menu points, that is not the same as the actual keyboard support – don’t confuse the two.)
Copy, Cut and paste are not supported – so select the IDC_EDIT_COPY, IDC_EDIT_CUT and IDC_EDIT_PASTE options and delete them. (Note three ID’s but six entries – one ID can have more than one key combination as a shortcut
.) The ID_NEXT_PANE and ID_PREV_PANE can go as well.
Click on the line at the bottom (below ID_FILE_SAVE) – this is how to add a new key shortcut. From the combo select ID_FILE_PLAYRANDOM, leave the modifier column (Ctrl) entry alone and enter an R in the Key column. Remember our menu specifies Ctrl+ R for playing a random game. We also need a shortcut for Lock (Ctrl+ L, ID_EDIT_LOCK) menu options.
Now we go to resource view then open the Toolbar and double click on IDR_MAINFRAME to view the toolbar. Click the ‘cut’ symbol and drag off the row then release the mouse button – the cut has been removed. Do the same for ‘Copy’, ‘Paste’ and 'Print'. Now you should have buttons for new, open and save and about (question mark). There is also a blank box to the far right of the row – this is for new buttons. We would like to add options for a random game, lock and solve as well as an undo option. Click this blank button and start drawing in it – there is a toolbar that gives you lines, shapes and other options. I suggest you play with that yourself. To organise you can drag and drop buttons on the bar, a drag a little to the right will introduce a spacer. Here are some suggestions for the buttons I have done myself.
Now click on a button (eg. The die – second from left) then look at the properties. Change the ID to ID_FILE_PLAYRANDOM. You should see the Prompt comes with that we entered with the menu item. Assign the other new buttons ID_EDIT_UNDO, ID_EDIT_LOCK and the exclamation mark to ID_EDIT_SOLVE. Now perform a Save All to save our changes.
From the Edit menu of the resource editor there should be a point ‘ID= Resource Symbols’, click on this – this gives a listing of all resource ID’s in the app, we can delete unused ones here (should there be any by eg. adding a button to a dialog form then later deleting it).
Finally from resource view open the Version then double click on VS_VERSION_INFO. Here is information displayed in the windows explorer when one looks at the properties of a file. We’ll leave everything here as is at present.
A quick compile and run (F5 key) should show the app – note our new menu items and buttons are greyed out – this is the expected behaviour as we have no code for them yet.
We have decided how the application should look and behave before we even started using Visual Studio - planning is very important and a major key to success.
We have used the project wizard to create the basic classes and resources for an application.
We have used the resource editor to modify some of those resources that were automatically generated for us.
Click here for the source code for this article
Next article in the series is here: Sudoku in MFC: Part 2
In that we will be looking at dynamically positioning controls on a window from code. We will also be using the windows registry for storing information about the application.
Two points to bear in mind.
You may use the code but you are not allowed to distribute the resulting application either for free or for a reward (monetary or otherwise). At least not without my express permission.
I will perform some things to demonstrate a point – it is not to be taken as that meaning it is a ‘best’ practice, in fact an alternative might be simpler and suitable. Some points in the code would even be called poor design and a possible source of errors.