Visual C++ doesn't just compile code, it generates code. When you first start to build your project, AppWizard makes you a "starter app" with all the Windows boilerplates you want. Later, as you add menu items and dialog boxes, ClassWizard adds the code you need to connect those interface items to functions that handle them. Windows programming means using Windows messages, and ClassWizard makes that simple.
AppWizard can make many different kinds of applications, but what most people want, at least at first, is an executable (.exe) program. Most people also want AppWizard to produce boiler-plate code-the classes, objects, and functions that have to be in every program. To create a program like this, Choose File, New and then choose Project Workspace from the list box in the New dialog box and click OK. This brings up the New Project Workspace dialog box shown in Figure 3.1.
Choose MFC AppWizard (EXE) from the list box on the left, fill in a project name, and click Create. AppWizard then works through a number of steps. At each step, you make a decision about what kind of application you want, and click Next. At any time, you can click Back to return to a previous decision, Cancel to abandon the whole process, Help for more details, or Finish to skip to the end and create the application without answering any more questions (not recommended before the last step). Each step is covered in the subsections that follow.
The first decision to communicate to AppWizard, as shown in Figure 3.2, is whether your application should be MDI, SDI, or dialog-based. AppWizard generates different code and classes for each of these application types.
The three application types to choose among are:
As you change the radio button selection, the picture on the left of the screen changes to remind you of what the application looks like if you choose this type of application.
NOTE |
Dialog-based applications are quite different from MDI or SDI applications. Many of the steps listed in the remainder of this section ask less questions or are skipped entirely for dialog-based applications, because they cannot, for example, be an OLE container or server, or access databases, because they have no menus or documents. |
Lower on the screen is a drop-down box to select the language for your resources. If you have set your system language to anything other than the default US English, make sure you set your resources to that language too. If you don't, you will encounter unexpected behavior from ClassWizard later. (Of course, if your application is for users who will have their language set to US English, you might not have a choice. This is discussed in Chapter 32, "Additional Advanced Topics.") Click Next when you have made your choices.
The second step in running AppWizard to create an executable Windows program is to choose the level of database support, as shown in Figure 3.3.
There are four choices for database support:
Chapter 14, "Database Access," clarifies these choices and demonstrates database programming with MFC. If you choose to have a database view, you must specify a data source now. Click the Data Source button to set this up.
As you select different radio buttons, the picture on the left changes to show you the consequences of your choice. Click Next to move to the next step.
The third step in running AppWizard to create an executable Windows program is to decide on the amount of OLE support you wish to include, as shown in Figure 3.4. OLE, Object Linking and Embedding, has been officially renamed ActiveX to clarify the recent technology shifts, most of which are hidden from you by MFC. The AppWizard dialog boxes still refer to it as OLE, so that is the terminology used in this chapter
There are five choices for database support:
If you choose to support OLE, you can also support compound files. Compound files contain one or more OLE objects; one of the objects can be changed without rewriting the whole file. This can save a great deal of time if you need it. Use the radio buttons in the middle of this Step 3 dialog box to say Yes, Please or No, thank you to compound files.
If you want your application to surrender control to other applications through OLE automation, check the OLE Automation checkbox. If you want your application to use OLE controls, check the OLE Controls checkbox. Click Next to move to the next step.
NOTE |
If you want your application to be an OLE control, you do not create a typical .exe application as described in this section. Creating OLE controls with OLE ControlWizard is covered in the "Creating DLLs, Console Applications, and More" section, later in this chapter. |
The fourth step in running AppWizard to create an executable Windows program, as shown in Figure 3.5, is to determine some of the interface appearance options for your application. This Step 4 dialog box contains a number of independent checkboxes; check them if you want a feature, leave them unchecked if you do not.
The following are the options that affect your interface appearance:
You can also set how many files you would like to appear on the recent file list for this application. Four is the standard number; change it only if you have good reason to do so.
Clicking the Advanced button at the bottom of this Step 4 dialog box brings up the Advanced Options dialog box, which has two tabs. The Document Template Strings tab is shown in Figure 3.6. AppWizard builds many names and prompts from the name of your application, and sometimes it needs to abbreviate your application name. While it can certainly be argued that Chapter3 isn't a very good application name, if that is the name, certainly Chap3 is a better abbreviation for it than Chapte, which AppWizard suggests as the default. Until you are familiar with the names AppWizard builds, you should check them on this Document Template Strings dialog box and adjust them if necessary. You can also change the main frame caption, which appears in the title bar of your application. The file extension, if you choose one, will be incorporated into file names saved by your application and will restrict the files initially displayed when the user chooses File, Open.
The Window Styles tab is shown in Figure 3.7. Here you can change the appearance of your application quite dramatically. The first checkbox, Use Split Window, adds all the code needed to implement splitter windows like those in the code editor of Developer Studio. The remainder of the Window Styles dialog box sets the appearance of your main frame and, for an MDI application, of your MDI child frames. Frames hold windows; the system menu, title bar, minimize and maximize boxes, and window edges are all frame properties. The main frame holds your entire application. An MDI application has a number of MDI child frames, one for each document window, inside the main frame.
The following are the properties you can set for frames:
When you made your selections, click Close to return to Step 4 and Next to move on to the next step.
The fifth step in running AppWizard to create an executable Windows program, shown in Figure 3.8, asks the leftover questions that are not related to menus, OLE, database access, or appearance. Do you want comments inserted in your code? You certainly do. That one is easy.
The next question is not so straightforward. Do you want the MFC library as a shared DLL, or statically linked? A DLL is a collection of functions used by many different applications. Using a DLL makes your programs smaller, but makes the installation a little more complex. Have you ever moved an executable only to find it won't run any more because it's missing DLLs? If you statically link the MFC library into your application, it is larger but it is easier to move and copy around.
If your users are likely to be developers themselves, to own at least one other application that uses the MFC DLL, or aren't intimidated by needing to install DLLs as well as the program itself, choose the shared DLL option. The smaller executable is convenient for all of you. If your users are not developers, choose the statically linked option. It reduces the technical support issues you have to face with inexperienced users. If you write a good install program, you can feel more confident about using shared DLLs.
The final step in running AppWizard to create an executable Windows program is to confirm the class names and the filenames that AppWizard creates for you, as shown in Figure 3.9. You should not need to change these names unless you know your application will be used in an environment that only supports short file names. If your application includes a view class, you can change the class it inherits from; the default is CView but many developers prefer to use another view, such as CScrollView or CEditView. The eight view classes are discussed in Chapter 6 "The Document/View Paradigm." Click Finish when this Step 6 dialog box is complete.
After you click Finish, AppWizard shows you what is going to be created in a dialog box, like that shown in Figure 3.10. If anything here is wrong, click Cancel and then work your way back through AppWizard with the Back buttons until you reach the dialog box you need to change. Move forward with Next, Finish, review this dialog box again, and then click OK to actually create the application. This takes a few minutes, which is hardly surprising since hundreds of lines of code, menus, dialog boxes, help text, and bitmaps are being generated for you in as many as 20 files. Let it work.
If you want, you can build and run this application. Choose Build, Build and then, when it finishes, choose Build, Execute. You then have a real, working Windows application. It has an icon, it can be resized, it has menus you can bring up (and some of them even work-for example, File, Exit closes the application), it has a toolbar and a status bar-in short, it has all the things that every Windows application has. All that remains is for you to add the things that make it unique.
Although most people use AppWizard to create an executable program, it can make many other kinds of projects. You choose File, New and then Project workspace as discussed at the start of the "Creating a Windows Application" section, but choose a different wizard from the list on the left of the New Project Workspace dialog box, shown in Figure 3.1. The following are some of the other projects AppWizard can create:
If you want to collect a number of functions into a DLL, and these functions use MFC classes, choose this wizard. AppWizard generates code for you to get you started. Figure 3.11 shows the only step in this process.
Figure 3.11 : AppWizard can build a DLL and generate starter code after you answer a few questions.
The first question you need to answer is how the MFC functions your application calls should be linked. You must select one of the three radio buttons in the top half of this Step 1 dialog box:
If the applications that call your DLL are likely to be installed on systems that do not have the MFC DLL installed, you can choose to statically link the MFC DLL into yours. This makes your DLL larger, but easier to install. If you don't mind shipping multiple DLLs, or are confident the MFC DLL is available to any application that will use your DLL, choose shared MFC DLL. If you are sure that every application that calls your DLL is an MFC application, choose MFC extension DLL for even more efficiency. C and C++ programs that do not use MFC cannot use your DLL if you choose this option.
The second question concerns extra features your DLL may use-OLE automation, discussed in Chapter 25, "ActiveX Automation," and sockets, discussed in Chapter 13, "Sockets, MAPI, and the Internet." The final question is, "Do you want comments?" Of course, you want comments to be generated for you that explain what code has been generated and what work remains to be done. Who wouldn't?
AppWizard shows you what it is going to do and then creates nine files for you to build into a DLL. Like the typical application discussed earlier in this chapter, your DLL doesn't actually do anything, but it's ready for you to build on.
An OLE control, commonly called an OCX, is a control you write that can be included in dialog boxes and forms. After Visual C++ 4.2 was released, Microsoft renamed the technology ActiveX, but the AppWizard dialog boxes still call them OLE controls, so that's the terminology used in this chapter. These controls are a 32-bit replacement for the VBX controls many developers have been using to achieve intuitive interfaces or to save reinventing the wheel on every project. Figure 3.12 shows the first step in creating an OCX with AppWizard, reached from the New Project Workspace dialog box by choosing OLE Control Wizard from the list on the left, filling in a project name and folder, and clicking Create.
The meaning of these questions, and what you do after the starter control is built, are discussed in more detail in Chapter 26, "Building an ActiveX Control." The first question, how many controls you want, is simple: most people build their controls one to a project. Runtime licensing prevents a user who buys an application with your control in it from incorporating the control into other applications. You want comments, of course. And if your control is complex enough to need documentation, you arrange that here too. As usual, the picture on the left changes to show what you have chosen. When it's right, click Next.
Clicking Next on the Step 1 dialog box brings you to Step 2, shown in Figure 3.13. Here you set the behavior of your control.
Figure 3.13 : The second step in building a DLL is to set up the control's behavior.
The following are the checkboxes on this Step 2 dialog box:
Click Finish and AppWizard summarizes your choices for you just as it does when creating other types of applications. Click OK and a do-nothing starter control is created for you, with roughly the same number of files as a full-blown executable application.
There are times when you want to create an application in Visual C++ that does not use MFC and does not start with the boilerplate code that AppWizard produces for you. To create an Application rather than an MFC AppWizard (exe) choose Application from the left-hand list in the New Project Workspace dialog box, fill in the name and folder for your project, and click Create. You are not asked any questions; AppWizard simply creates a project file for you and opens it. You have to create all your code from scratch and insert the files into the project.
If you plan to build a DLL that does not use MFC and does not need any boilerplate, choose this option rather than MFC AppWizard (DLL). Again, you get an empty project created right away with no questions.
A console application looks very much like a DOS application, though it runs in a resizable window. It has a strictly character-based interface with cursor keys rather than mouse movement. You use the Console API and character-based I/O functions like printf() and scanf() to interact with the user. As with the previous two application types, no boilerplate is generated, just an empty project.
While most code you reuse is gathered into a DLL, you may prefer to use a static library, since that means you do not have to distribute the DLL with your application. Choose this wizard from the left-hand list in the New Project Workspace dialog box to create a project file into which you can add object files to be linked into a static library, which is then linked into your applications.
If you want to create a project that is used with a different "make" utility than Developer Studio, choose this wizard from the left-hand list in the New Project Workspace dialog box. No code is generated. If you don't know what a make utility is, don't worry: This wizard is for those who prefer to use a stand-alone tool to replace one portion of Developer Studio.
Perhaps you work in a large programming shop that builds a lot of applications. Although AppWizard saves a lot of time, your programmers may spend a day or two at the start of each project pasting in your own boilerplate, material that is the same in every one of your projects. You may find it well worth your time to build a Custom AppWizard, a wizard of your very own that puts your boilerplate in as well as the standard MFC material. Once you have done this, your application type is added to the list box on the left of the New Project Workspace dialog box shown in Figure 3.1. Creating and using Custom AppWizards is discussed in Chapter 29, "Power-User Features in Developer Studio."
ISAPI stands for Internet Server API, and refers to functions you can call to interact with a running copy of Microsoft Internet Information Server, a World Wide Web server program that serves out Web pages in response to client requests. You can use this API to write DLLs that can be used by programs that go far beyond browsing the Web to automating information retrieval. This process is discussed in Chapter 13, "Sockets, MAPI, and the Internet."
Running AppWizard is a one-time thing. Assuming you are making a typical application, you choose File, New, Project Workspace, go through the six steps, create the application starter files and then never touch AppWizard again. But what if you choose, for example, not to have online Help, and then later realize you should have included it?
AppWizard, despite the name, is not really magic. It pastes in bits and pieces of code you need, and you can paste in those very same bits yourself. Here's how to find out what you need to paste in.
First, create a project with the same options you used in creating this project, and don't add any code to it. Second, in a different folder create a project with the same name, and all settings the same except the one thing you want to change (context sensitive Help in this example). Now, compare the files using WinDiff, which comes with Visual C++. Now you know what bits and pieces you need to add to your full-of-code project to implement the feature you forgot to ask AppWizard for.
Some developers, if they discover their mistake soon enough, find it quicker to create a new project with the desired features and then paste their own functions and resources from the partially-built project into the new empty one. It's only a matter of taste, but after you've gone through either process for changing your mind, I assure you that you will move a little more slowly through those AppWizard dialog boxes.
Once your application is built, you are finished with AppWizard but you are likely to spend a great deal of time with ClassWizard. It handles a number of tasks that Windows programmers need to perform repeatedly, from something as simple as creating a new class to catching Windows messages or incorporating ActiveX technology into your application. In this section, you will learn more about one of the first tasks a new programmer approaches with ClassWizard: connecting the menus in your application to code. Adding a menu item to an application is discussed, with examples, in Chapter 17, "Building Menus and Dialogs." This section gives a brief overview to help you understand what ClassWizard does.
The first step, not shown here, is to edit your menu resource to include the new menu item. Part of this process gives the menu item a name, a resource ID. It's a convention that the resource ID for a menu item is built from the name of the menu and the item. For example, when a user chooses Edit Copy, the resource ID involved is ID_EDIT_COPY. If you add a Foo menu with a Mumble item on it, the resource ID is ID_FOO_MUMBLE. As discussed in Chapter 5 "Messages and Commands," when the user chooses a menu item or clicks a toolbar button, a Windows command is sent with this resource ID as a parameter. Your next step is to arrange for your program to "catch" this command. You make those arrangements with ClassWizard.
Figure 3.14 shows the ClassWizard Message Maps tab for an application called Qsend, and its application class called CQSendApp. To see this dialog box yourself, open a project and choose View, ClassWizard then click the Message Maps tab. The details on your dialog box will be slightly different for a different application. The list box on the left lists messages and commands that this application class might catch, including ID_APP_ABOUT, the ID associated with the menu item Help About. (This resource ID is a rare exception to the naming convention discussed above.) The list box on the left lists the messages that might carry this resource ID; the COMMAND message is sent when the menu item is chosen. The list across the bottom of the dialog box lists the functions that have already been added to this class and what commands and messages they are associated with, as well as virtual functions in this derived class. OnAppAbout is highlighted because it is connected to the two highlighted choices in the upper list boxes. When a COMMAND message is sent with the resource ID ID_APP_ABOUT, the function CQSendApp::OnAppAbout() is called.
Message maps are probably the feature that sets Visual C++ and MFC apart from other approaches to Windows programming. They make it conceptually simple to arrange for one of your functions to be called when a user chooses a menu item. You will use ClassWizard over and over again as you add menu items or change the code in the functions that are connected to those menu items.
Just as ClassWizard can simplify the connection of menus to code, it can make implementing a dialog box a much simpler task as well. This procedure is covered in detail in Chapter 17, "Building Menus and Dialogs," and this section provides an illustration of the way that ClassWizard reduces your workload.
When you add a dialog box to your application, you need to do three things. First, you build the dialog box in the Resource View. Then, you build a C++ class to represent the dialog box in memory, with member variables that correspond to controls on the dialog box. Then, whenever your program wants to display the dialog box, it declares an object that is an instance of the class, sets the member variables, and displays the dialog box on-screen by calling a member function of the object.
ClassWizard makes this easier than it could be. After you build the new dialog box, you bring up ClassWizard while still looking at the dialog in Resource View, and ClassWizard offers to build a class for the dialog, as shown in Figure 3.15. Creating the class is as simple as filling in the Create New Class dialog shown in Figure 3.16.
Once the class is created, you connect controls to member variables of that class with the Member Variable tab of the ClassWizard dialog box, shown in Figure 3.17. The edit control with the resource ID IDC_SELECTED_HOST is connected to the member variable m_selected_host of the class SelectHost. The two buttons on this dialog, with resource IDs ID_OK and ID_CANCEL, are not connected to member variables.
The connection between IDC_SELECTED_HOST works in two directions. Just before the dialog is shown on the screen, the edit control is filled with the value in m_selected_host. That makes it easy for you to put defaults onto a dialog box. After the user clicks OK, the value from the edit control is put into the member variable for your code to use. All of this, including creating a dialog class and using a dialog is discussed in more detail in Chapter 17, "Building Menus and Dialogs."
Perhaps you can imagine the structure of your application now; when the user chooses a menu item or clicks a toolbar button to tell your program to do something, one of your functions is called. That function typically initializes and displays a dialog box, then does something with the values that the user entered in the dialog box. You set up both parts of this with ClassWizard.
Because ClassWizard is such a useful tool, Visual C++ features a Wizard Bar for the editor window of every source file, like the one shown in Figure 3.18. The drop-down box that contains ID_APP_ABOUT is equivalent to the left list box in Figure 3.14, and the drop-down box that contains COMMAND is equivalent to the right list box in Figure 3.14. The Wizard bar scrolls the source window to CQsendApp::OnAppAbout and highlights it when this combination is selected from the drop-down boxes.
Figure 3.18 : The Wizard bar presents the same information as ClassWizard's Message Maps tab.
The Wizard bar is primarily used to see what function handles a message, but if you choose a message that is not handled, you are given a chance to add a function to handle it. That makes the Wizard bar a compact replacement for the Message Maps tab of ClassWizard. Most new users need a little experience with the larger dialog box before switching to the Wizard bar.
This chapter explains the two biggest non-compiler portions of Developer Studio and Visual C++: AppWizard and ClassWizard. You will see a lot of more of these two tools and what they do throughout this book. For more information on these, check out the following chapters:
There's one more part of Developer Studio and Visual C++ for you to meet: MFC, the Microsoft Foundation Classes. These 216 C++ classes make your life as a programmer much, much easier. You'll get to know them starting in the very next chapter.