Teach Yourself Visual C++ 5 in 21 Days

Chapter 2: Controls, Properties and Events


The second chapter in the text introduces you to a design specification, creating a prototype, adding controls, variables and code to the project. The objectives important to this chapter are:

  • creating a new project
  • adding and using text
  • adding and using an edit box
  • adding and using a check box
  • adding and using buttons
  • adding variables associated with screen objects
  • adding functions that affect the above objects

Chapter 2 begins with a clearer picture of the two stages of program creation: design and coding. On page 52, you see a screen that is described on the next two pages. Imagine that you did not have the visual aid. (Not too hard, as I'm not going to reproduce it here.)

A real project begins with a reason to create a program, and a user who describes what is needed to a designer who creates a prototype to meet the user's needs. The bullets on pages 52 and 53 are better descriptions of user needs than you will often have at the very beginning of a project. These needs are also called requirements or specifications. A successful developer will spend a great deal of time interviewing the user, in order to get these requirements into an understandable, mutually agreed upon form. It is like a contract for the project, that you rely upon in order to produce a quality product.

The designer using a visual development tool like Visual C++ has an advantage over someone using older tools. The screen described on these pages can be constructed in Visual C++ in minutes. Working with a good user, a good designer can rough out an actual program screen this way in far less time than it would take the old way to describe it, draw it, program it and finally show printouts to the user, who would inevitably ask you to change it due to some misunderstanding or second thoughts. The visual environment is faster to use, and easy to modify.

Following the instructions on the next few pages, you should be able to create the objects that comprise this application. Don't worry about the code yet, just do it as though you were doing a prototype to show a user.

When you get to page 60, you will note some details are being added that may be new to you. As you change the captions on the buttons you create, the text asks you to place an ampersand (&) before certain letters in the caption. The rather hideous font used on page 61 left me in doubt that the author wanted an ampersand at first, but trust me that's what he is asking for. For example, the button that will be used to exit the application has the caption Exit. The underline appears in the caption because you type the caption as E&xit.

Why do you want to do such a silly thing? It is not just to get an underline, it is to enable a hot key. It gives you keyboard control of the button when the program runs. A user who wishes to "click" that button from the keyboard merely presses the Alt key in conjunction with the letter underlined (preceded with the ampersand). Note: you should not enable the same hot key for any two buttons on the same screen. You will not like the result, and neither will your user. For those who need further reason to create hot keys: you may have to comply with standards that say all controls on the screen must be keyboard accessible. Yes, really. A question in the back of the room: how does it work? Magic. A feature of the class we are using? All right, Microsoft precoded the class to work this way. (It works in Visual Basic, too.)

The next new concept is on page 62, creating variables and associating them with controls. Follow the steps:

  1. Open the View menu and click Class Wizard
  2. Make sure you are on the Member Variables screen, as on page 62
  3. Verify the contents of the Project box and the Class name box (the screen we are working on)
  4. In the list of Control IDs, click the object you are going to add a variable to
  5. Click the Add Variable... button
  6. Set the values for the Name, Category and Type for the variable you are creating
  7. Click OK

You will note that Category and Variable Type are dependent on each other. In the first example, you are adding a variable of type CString, that will hold a Value. In the second, you are adding a BOOL (Boolean) variable that will hold a different Value (TRUE or FALSE).

Finally, on page 64, you begin writing the code to do something. You need to know that it is standard to write code for a Windows application that specifies how a screen should look when it opens. On page 65, you are told to select the object called CTestDlg (the dialog box you created) and select the message (event) called WM_INITDIALOG. This is the initialization event for a dialog box, which occurs when it is drawn on the screen (initialized). You will see that there is already a function (code) associated with this event. You know this because a line in the functions box is automatically highlighted when you select the two objects as directed. Great, you don't have to make it from scratch. You click the Edit Code button and do just that.

Following the model on page 66, you add some remarks to the program. These typically show your name, the date of the change, and the reason for the change. In the example, there are only three lines added that execute, the rest are remarks. The two Boolean variables associated with the check boxes you drew are set to TRUE. Unlike Visual Basic, this does not automatically make the actual check boxes checked. The third executable line in this section does. The line is:


This is a function you can call, included in the existing code for this application. (Thank you, Mr. Gates.) The function has two purposes. If you pass the argument TRUE to the UpdateData() function, it assumes that controls on the screen have changed and saves their current states in associated variables. On the other hand, if you pass the argument FALSE to the UpdateData() function (as above), it assumes that variables contain the desired states for controls, and changes the screen controls to match the current states of associated variables.

Bottom line: you set the variables to TRUE, which indicates "checked" for check boxes. You then told the UpdateData() function that things were FALSE, which told it to set the screen to match the variables. And it all happens in the microseconds that it takes to draw the screen on your monitor, when the dialog box first appears.

Next, you attach code to the buttons you drew. (You have drawn them, right?) Same basic idea: select the object, select the event/message, and... oh dear, this time there is no function associated with the event. No trouble, just click Add Function, name the function and then click Edit Code (while the new function is highlighted). The author starts out easy: you add code to the Exit button. Remember how to exit an application that is a dialog box? Just call the OnOK() function.

Code is added to the remaining buttons in the same way. You are creating a new function in each case that is called when the user clicks on the associated button. You may be surprised by the code on page 71 that assigns a string to a variable with just an equal sign. You cheated when you made the variable a CString type, making it unnecessary to use the strcpy() function. Bill Gates' magic, again. Note that you had to call the UpdateData() function, to update the screen. Quick quiz: did you pass the function a TRUE or a FALSE to update the screen? Think about it this way:

Question: Update Data? Answer: TRUE (Updates the variables, which hold data)
Question: Update Data? Answer: FALSE (Like, not even. Updates the screen)

The code for the action taken by the check boxes needs a little explanation. On page 74, you see five lines that will execute. The first says to take the current state of controls and save them in the associated variables. Makes sense, we just clicked the check box. The other four lines are a standard if-else construction. The test is "Is the Visible Check box variable set to TRUE?" If so, you call the GetDlgItem() function, passing it the ID of the Edit box you drew. This function returns a pointer to the object you pass to it. The next thing that happens, on the same line, is that you are calling a member function of the Edit box. Since you are using a pointer to access the member function, you use the arrow notation instead of the dot notation. The function called is the ShowWindow() function, and you pass it an argument that either makes the object visible (SW_SHOW) or invisible (SW_HIDE). In fact the two outcomes of your test are exactly the same, except for the argument passed to the ShowWindow() function. Personally, I find this a bit verbose, but this is code using standard functions and standard constants. Constants, you will recall are noted by all capital letters. It works.

The code for the Enabled check box is almost identical. Note on page 77, that to enable an object, you call its EnableWindow() member function, passing it TRUE to enable and FALSE to disable. Enabled objects can be used, and disabled objects can't be used, but this attribute does not affect whether it can be seen.

The trickiest code is the last function in the chapter. The code on page 80 is associated with the Edit box. The event you are associating with is the change event. In other words, this code is triggered whenever the contents of the Edit box change. In order to minimize the number of tests you must use, the code first creates a new variable of type CString, called UpperValue. You assign the value of the Edit box variable to the new variable, AFTER first updating the value of that associated variable. Then you call the MakeUpper() member function of the UpperValue variable. You didn't know it had such a function? Just thank Mr. Gates and accept that it does. This function changes the contents of our new variable to all upper case. (Why didn't we do that with the original variable? We did not want to have to update the screen or confuse the user.) The program then carries out some tests, and if the user has typed the name of either of the two specified programs, the code calls the correct executable by passing its name to the system() function. Not too bad.

Remember to save and test every time the author says to do so (or even more often) and correct mistakes in typing as you go.