Most programmers, when developing an application, do not consider what happens when they are done creating the application. If you are working for a company, the finished application is different than if you are planning to sell the application yourself. Putting everything together into one package takes patience, time, imagination, and a little luck. If all goes well, the finished product looks good and works well. This chapter discusses what goes into creating a finished product, some things to think about as you develop the application, how to distribute the application, and whether to sell your application or put it out as shareware.
You may not realize it, but there are three distinct types of applications. If you are just starting out as a developer, this may be a little confusing. An application is an application, right? Wrong! Depending on where you work, the type of application on which you are working, and the final audience of the application, the package you create will be different. The three types of applications that you might create are Personal, Internal, and Retail.
A personal application is one that you create for yourself alone. You probably won't create any Help files or a manual for your own application. In addition, because it is running on your own PC, you won't create any distribution disks. As you can see, a personal application is like having a diary--no one else will ever know about it unless you tell them. When working for a company, any applications that you develop will probably be used by other employees of that company or by clients of that company (for example, home banking software). If the application is a completely internal one, then you don't need to consider any issues that deal with marketing the application. However, you do need to create a Help system and a manual because you are not the one that will be using the application. The users must have some type of documentation to refer to when using the application. If the application is for company clients, then a little marketing and advertising has to be included in the overall process.
If you are creating a retail application, you must consider and deal with everything that has been mentioned so far, plus issues such as trademarks, copyrighting, advertising, customer support, and so forth. There are many factors involved in creating a marketable application that can be overlooked or not done properly. The next section considers the different areas with which you must deal, and for which you must provide answers, before you start selling an application.
Before jumping in and creating your application, you need to decide what function the application will serve. This is not as easy as it may sound. For every idea that someone comes up with, there are ten other people with the same idea. After deciding what type of application you want to create and more importantly, sell, you need to research who would use it and how many people might purchase it. This is called market research. Without doing this research, you may create a great product that nobody wants, or a product that has so many competitors that it gets lost in the crowd. If you find that there are too many other products of the same type already on the market, then you might decide either to select a different type of application or to place the finished product into the realm of shareware, discussed later in this chapter. For instance, you don't want to spend the time creating a word-processing product with products such as Word and WordPerfect already on the market.
In short, you need to select an idea that is new, or at least different, and run with it. You also have to compare the cost of creating the product and advertising it with your available cash and expected sales. However, once you decide on the application, jump in and start the process. You want to get your product to the public as quickly as you can, with the best quality possible.
Packaging an application takes a lot more effort than just putting it on a disk and mailing it to someone. The concept of packaging should start right at the beginning with the application design and forms layout, and finish with the final deliverable product. Many programmers do not think about the process in this way. However, if you want to produce a high quality product, you must consider every element. You may think you have the greatest product in the world, but if it doesn't work well, install easily, have attractive packaging, and effective advertising, you will not sell very many copies.
Before beginning to develop your application, you should do research. Look at other companies, products, and technical support services to create a list of what works, what doesn't, and more importantly, how you think you can improve on any of them. Of course, this doesn't include the research and design of the actual product you are creating.
When you start thinking about a new application, deciding what it will do and how its activities should be done is the most difficult part of creating it. The time spent designing an application should be considered the most important part of creating it. Unfortunately, most programmers do not spend as much time designing their applications as they should. They would rather jump right in and start building the application. When building your application, consider how you want the application to look, what the database should be, and how the report formats should be set up. When starting your design, put the functionality of the application into words. This representation of the program is called psuedocode. By writing this description, to will have an easier time focusing on what you want to create and how to go about creating it.
Because a Windows application is a collection of related forms that enable a user to interact with the data, you should take care when you design your forms for the application. An application should look good and be easy to use. No matter how much you try to stay within design guidelines, the forms that you create will, to some extent, reflect your personality. The form is the most important piece of any application. If the interface is difficult or just doesn't look good, nobody will want to use it. The GUI interface offers a wide variety of ways to make the user feel comfortable with the application. When designing the forms, you need to take into account the skill level of those who will be using the application. Keep in mind the following design concepts:
See "Implementing a User-Centered Software Development Process," Chapter 19
See "Making a Well-Designed Form," Chapter 19
In conjunction with designing the forms, you need to design and create the database. Depending on the database design, the forms will have different controls on them to interact with the database. To design the database, follow the same steps that you follow when designing the application. A good design lets you build a database that provides faster, more accurate answers. The difference between designing the database and designing the application generally is determined by the type of application you are creating. Some applications have nothing to do with databases, and others are more concerned with the user interface.
See "Using Crystal Reports to Create a Report," Chapter 16
See "Creating Consistent and Effective Graphical Interfaces," Chapter 19
See "Designing a Database," Chapter 28
The Help system appears as part of your final application and is not easy to create. Many programmers make the mistake of waiting until the application is completed to start designing and building the Help system. In the days of DOS programming, that might have worked. However, when working in a Windows environment that allows things like Help buttons on every form and context-sensitive help, you must think about the Help system during the entire process. Because the Help system is integrated into the application, you must know what types of Help you want to provide to the user at every point in the application. For example, when an error message is displayed to the users, will they have the option of hitting the F1 key or a Help button to get a more detailed description of the error?
If you decide to wait to design the Help system, you will only delay the final application because you will have to go back into the application code and add every reference to the Help system that you create. As you already know, if you make any code or form changes to the application, you must retest the entire application. Then you will have to re-create the distribution disks and test them again. As you can see from this discussion, you should design the Help system as you design the application, working on both at the same time.
See "Creating a Help System," Chapter 21
Producing a good printed manual for your application is a complicated procedure. Not only do you have to decide what topics go into the manual, but you have to select images from the application to place into the manual. The starting point of coming up with any manual design is to assume that the user will not be at the computer when reading the manual for the first time. You will need to balance the text in the manual, having users look at pictures in the manual, and at the application on the computer. A good manual usually contains the following sections:
These different sections give the user enough information to get started, figure out some of the simpler questions, and know how to contact you for technical support.
Again, look through other product manuals and see which features you like and which features you don't like. If your manual is well-written, then, in conjunction with the online Help file, the amount of support calls should be fairly low. Another way of producing a good manual, but not incurring the cost of printing, is to use a product such as Acrobat. Acrobat and products like it let you create your manual in an electronic format which you can include on your distribution disks. You should include the product's viewer program with it as well. This lets the user view the manual or print it.
NOTE: An online manual is not the same as the online Help file. The manual can be read and searched, but there are no jumps, pop-ups, or hot spots to use in the viewer.
The Help system is often an afterthought when building applications, but the reports and the reporting process of an application usually falls even lower in priority for most programmers. The reports tend to evolve as the application is put together. The programmer generally doesn't know exactly which reports will be needed until after the application is done. Then, when the programmer starts testing it, the types of information that must be retrieved from the application are determined. Of course, this is not always the case. In some types of applications, most reporting needs are known before the application is created. These reports can be built and added to the application as the development progresses. However, reports are like weeds--new ones keep popping up just when you thought you were finished with them.
Everyone has his/her own ideas of what a good report should look like. If you create reports that are easy to read and that present the data in a logical layout, then you have done a good job. With Visual Basic, you get a reporting tool that you can incorporate into your applications. (Crystal Reports is a good tool for creating professional looking reports and having them displayed or printed directly from your application.)
See "Using Crystal Reports to Create a Report," Chapter 16
Because of the way Windows works, the size of an application affects its performance. As an application gets more complex, its size increases. This causes the amount of memory required and the speed at which it executes to become more important issues to the programmer. You always want your application to run as fast and as efficiently as possible. Before the advent of Windows, a program was contained in one executable file, and if that file became too large, the program would not work very well. It relied on the programmers' skill to create compact code that would execute quickly.
Once Windows programming became commonplace, it was easier to control the size of an application. Applications now can be broken into smaller pieces that are executed only when needed. If you have been using Visual Basic for any length of time, you know that controls (.ocx) are one way of breaking the application into smaller pieces. With Visual Basic version 5, you have the capability to create not only your own custom controls, but also your own Dynamic Link Libraries (.dll) for your application to use. In addition to these methods for enhancing the performance of your application, there are some features of Visual Basic that you can use to minimize memory usage or to maximize the speed at which the program executes. As you probably know already, performance is very subjective. If the user thinks there is a problem in the application, then there is a problem, even if one doesn't exist.
When discussing performance, most people think of cars, not computers. However, in today's world of Pentium Pro processors and MMX technology, the computer's processing speed is closing in on the 300MHz range. This means that the users will expect better performance out of every application they install on their computers. However, as computers get faster, applications get larger in an effort to take advantage of the additional speed, so the overall performance doesn't necessarily change. To make your application as quick as possible requires some tuning or optimizing. One of the problems with tuning your application is that the changes you make may not always benefit you in the long run. Changes that you make to the application to improve its performance can cause the code to become more difficult to maintain or to change in the future. Sometimes a change can actually decrease an application's performance.
The user's first impression of your application is very important. This impression begins to form when the user first starts the application. If the application runs for a while before anything is displayed, the user starts to become impatient and assumes that the application does not perform well. The larger and more complex the first form is, the longer it will take to load and display. One of the simplest things that you can add to your application to give the impression of increased performance at startup time is the Splash dialog. If you use the Application Wizard that comes with Visual Basic 5, you will receive the option to include a Splash dialog in your application. If you did not use the Application Wizard, you can always add the Splash dialog later. A Splash dialog is nothing more than a small form that is displayed to the user while the more complex work is being done in the background. A good example of this is Visual Basic itself. When you start Visual Basic, first you see the Splash dialog and then you see the development environment. A example of a Splash dialog is shown in Figure 22.1.
In addition to using the Splash dialog to give the user a good first impression, you can improve your application by using more efficient calculations, variable types, and variable usage. When performing calculations, every data type that is available has its own drawbacks. If you use the Variant data type in your application, be aware that even though it is very useful, it is also the slowest data type for the computer to process. Each time you reference a Variant data type, the computer must check the data in the variable and create a temporary variable with the correct data type for the data used in the calculation. By using the correct data types for the data you will be accessing in the application, you will increase the performance of the application.
FIG. 22.1
Visual Basic displays this Splash dialog while it initializes the development
environment.
The Professional or Enterprise edition of Visual Basic 5 now comes with a method of enhancing the application's performance that was never before available. You now can choose to compile your code either in standard Visual Basic p-code format or in native code format.
P-code, or pseudocode, is an intermediate step between the high-level instructions in your Basic program and the low-level native code your computer's processor executes. At run time, Visual Basic translates each p-code statement into native code. This takes some time when running an application. However, by compiling the application directly into native code format, you eliminate the intermediate p-code step and runtime compile. If you want more information about optimizing your application, check out the section "Designing for Performance and Compatibility," which can be found in Visual Basic Books Online that comes with the Visual Basic 5 product CD-ROM.
In a perfect world, the applications you create would not need any error handling at all. Unfortunately, you live in an imperfect world where users make mistakes, files are sometimes accidentally deleted, and disk drives run out of space. When designing and creating your application, you need to anticipate the types of errors that might occur in your application and how you can deal with them. If you create your application with no error handling in it, then you are giving Visual Basic the job of trapping any errors that occur and dealing with them on its own.
However, Visual Basic is not very forgiving when it comes to errors. If an application error occurs, Visual Basic displays the default message for that error and then closes the application. This usually occurs after the user has spent a large amount of time entering data but hasn't saved it yet. If the error is not one that Visual Basic can detect, then the application might continue without any messages being displayed and with unpredictable results.
To prevent this from happening, consider the issue of error handling and design it into your application from the beginning. This will also help you test the application because if something doesn't work and an error occurs, you will get messages from the application instead of Visual Basic closing the application.
Error handling is not limited to program and logic type errors. Error handling is needed when databases are accessed to prevent unwanted results. However, data-access errors are corrected in a different way than normal program errors. When you access the database, the method for handling any errors that might occur is different because these errors are caused by some problem with the database itself or the data being manipulated within the database. Because of this difference, data can be damaged if the error is handled incorrectly. You have to decide what action you want to perform when the error occurs. The action you choose depends on what was being done on the database when the error occurred. You might only need to tell the users that the data they are inputting is incorrect, or you might need to reverse an entire group of modifications done to the database.
If you have designed the application correctly and considered every error or problem that might occur, then you have done a good job. However, as someone once said a long time ago, "There will always be one more bug." This is why you need to supply technical support to users of your application.
See "Working with Procedures," Chapter 17
See "Database Access," Chapter 18
When you call a software company for support, do you like the service you get? What would make it better? Providing customer support has to be one of the hardest things in the world to do. No matter how hard you try, you will never satisfy everyone. Most users will not call unless they have problems they cannot resolve on their own. Unfortunately, by that time they are annoyed with the product and you are starting behind the eight ball with an unhappy customer.
There is more to the support issue than just answering phones. You must consider the following issues and have a definite plan in place before distributing your application:
You need to plan for each of these issues when you decide how to provide support. If you plan correctly, then your product will be well-received by the people who use it.
Ease of Contact When you consider the issue of contact, think of the different means users have available to contact you for help. Some companies make it difficult for the user to get help by limiting the support to certain times of day. Decide how much or how little you want to support the application that you intend to sell. The following are the available options for providing customer support:
Each of these options has its own unique problems and expenses. The best way to offer support is over the phone. However, unless you plan to be available 24 hours a day, 7 days a week to answer the phone, you will need to either hire someone to answer the phone or use an answering machine. The first option is expensive to maintain, and many people have difficulty talking to an answering machine. Another way to handle customer support is to allow the user to fax in questions or problems. In both the phone and the fax options, you need to determine how long the response time will be to return a call or a fax. In my experience, if you try to get back to the user within 24 hours, then the user perceives that your support and your efforts to solve their problems are good.
The newest and hottest way to supply support is to make use of the World Wide Web. Many companies are creating Web sites that not only tell users about the company and its products, but also allow users to send questions and report problems to the company. Additionally, the Web makes it very easy for the user to download fixes to problems they might have.
Deciding which way you want to support your application is up to you and your budget. However, you must pick one or more of these options and then implement them before you start selling the application.
Questions/Problems ow that you have users calling, faxing, or e-mailing problems and questions to you, how are you going to handle them? You should develop a good way of tracking both the users who are calling and their questions or problems. This not only helps you keep track of who your users are, but it also helps you pinpoint the questions that are being repeated. This will help you update the application with better technical support or with new features that enhance the application's functionality. In addition, if you have a Web site, you can create a Frequently Asked Questions (FAQ) page. Dealing with problems is a little different than dealing with questions. You can usually answer questions that deal with how your application works easily enough. However, you need to obtain more information to resolve a specific problem. When you take a problem report, ask the user for every shred of information that you might need to figure out the problem. The following list contains some of the information you should request from a user reporting a problem:
Of all these items, the last one is the most difficult--getting enough specificity from the user. You often will hear that the user started the application and then it "blew up." Now, this is not very descriptive of what really happened. You need to know what the user typed, which function keys the user pressed, or which command buttons the user clicked. These bits of information are very important when trying to narrow down the possible problem(s).
Sometimes, when a problem is very hard to figure out, you can come up with a way around the problem. This is called a workaround--it doesn't fix the problem, but the user can continue working with the application while you attempt to solve the problem. Workarounds are important because there will be times that a problem takes a long time to fix or cannot be fixed without major changes to the application. You then need to decide if you want to start on the next version of the application or the same version that includes the fixes.
Upgrades After you decide to create a new version of the application, you have to figure out how the current users of the application can upgrade to this version. If you design the next version without taking this into consideration, users of your current version will be annoyed if you ask them to start from scratch with a new release of the product. Think of how you would feel if you had an application that you spent months learning and entering information into, only to receive a new release that provides no way of moving your preexisting data into it. Keep this in mind or you will soon start losing customers to other products that support this type of upgrade. Another thing to consider with upgrades is how they will be distributed. Has everything in the application changed or just a few things? You need to have two separate sets of distribution disks--one for new users and the other for current users who are upgrading to the new release. Generally, upgrades should contain fixes to problems that have popped up, as well as any new features and functions. This gives the current users a reason to buy the upgrade and new users a reason to try out the application.
Putting all of the components together takes some time. After you have designed, built, and tested your application, you need to bring it all together into a complete package. There are two main areas that you need to deal with when pulling the package together. The easier of the two areas is the actual creation of the distribution disks for the product. The other area is dealing with all of the legal issues that protect you and your software from theft and liability.
Dealing with legal issues might sound intimidating; however, legal issues are not all that mysterious. The different issues that must be considered are:
Product registration and software theft involve two sides of the same issue. There is no inexpensive way to prevent someone from copying your distribution disks after you send them to a user. However, if you have your users register when they purchase the product, you can track who the legal owners of your software are. The incentive to register a new product is the availability of support and the receipt of notification for any upgrades or new versions. By assigning a serial number to each copy of your software, you can keep an accurate record of which user has which copy. When providing support to a user, one of the first questions that you should ask is, "What is the serial number of the product?" Then, if the name of the user does not match your records, you have caught someone using your software without paying for it. If you do catch someone doing this, you need to decide the course of action you will take.
You need to protect yourself from the possible theft of your idea, design, or the implementation of your product. By copyrighting your software, you protect your software from unauthorized copying.
NOTE: The amount of protection provided by a copyright is proportionate to your desire to take legal action against someone who has used your idea.
CAUTION: Although you can copyright the source code, Help files, and manual for your application, you cannot copyright the actual idea or screen design. If you intend to copyright your software, you should do it before you start selling the application. For information about how to apply for a copyright, call or write to:
Publications
Section LM-455
Copyright Office
Library of Congress
Washington D.C. 20559
(202) 707-3000
NOTE: A copyright registration is considered effective on the date the copyright office receives all of the required elements in an acceptable format. You should use some type of return receipt to know when it gets to the copyright office.
Whether to trademark the name you choose for your application is the next decision you need to make. Having a trademark for your product prevents someone else from legally using the name. For example, Microsoft would sue another company who tried to use the name Windows for its PC operating system. However, trademarks take time and money. Some developers choose not to spend the time or money and instead take their chances on the name that they choose. Unfortunately, if someone else trademarks the name that they are using, developers without the trademark have to change the name of their product at their own expense. A copyright costs about $50 and a trademark submission costs approximately $200.
CAUTION: If your trademark is rejected, you do not get a refund of your application fee.
There are many other rules and regulations concerning the submission and acceptance of a trademark. You should get the information from the Trademark Office as soon as you can. It can take from 3-9 months to get a trademark approved. If you choose a name and create the documentation before the trademark is approved, you stand the risk of having to redo everything if the name is denied. For more information about trademarks, call or write to:
U.S. Department of Commerce Patent and Trademark Office Washington D.C. 20231 (703) 308-4357
The Setup Wizard program helps you create a professional-looking installation program for your application. In addition to the standard install process, the Setup Wizard includes the files and programs needed by the users to uninstall your application if they want. Visual Basic also comes with the source code that is used to create the setup program. This Toolkit can be used to add additional code that displays customized forms to the user. An example of a custom form can be seen when installing Visual Basic 5 (see Figure 22.2).
FIG. 22.2
Example Options form displayed during the setup process.
The Setup Wizard takes you through several steps that prompt you for the information needed to create the final setup program. Following are the steps you have to follow to create the final setup program:
The Setup Wizard then compresses all of the selected files. Depending on which installation setup option you choose, the Setup Wizard asks for disks or simply copies the files to the specified hard drive directory. The Setup Wizard will display several dialog boxes that ask you to either enter required information or confirm the information the Setup Wizard has found. When you start the Application Setup Wizard, you will see an introduction form display. Then, when you click Next, you are prompted to enter the path and file name for your application's project .VBP file (see Figure 22.3).
FIG. 22.3
The Setup Wizard form showing the Project File and Action Options Selection.
Besides the obvious information that is needed on the first dialog box, you will need to select which type of installation program you want to create. The default action is to create a setup program. This is what you normally choose for a standard Visual Basic application. However, if you are creating an ActiveX control for use on the Internet, you select the second action option. Finally, you can choose to create a dependency file along with the setup program, or by itself.
NOTE: A dependency file is used by the Setup Wizard to determine the files that are required by any object of an .ocx, .dll, or .exe ActiveX component, or a project that can be used as a component in other projects.
If you are using components that you have created, you should run the Setup Wizard for those components to create a dependency file for each of them. Setup Wizard looks for these files and uses them to include any other related files that are needed for these components to work. The Setup Wizard displays a list of components for which it can't find the associated dependency files. For any components listed, you should go back and create the needed dependency file before continuing the Setup Wizard process for your application.
After you select the correct options, you will be asked how you want to distribute your application (see Figure 22.4).
FIG. 22.4
Selecting the distribution method for your application.
The following are the three distribution method choices:
Depending on the distribution method you select, one of three different dialog boxes will be displayed. The first dialog box lets you specify the floppy drive and disk size that you are using for the installation disks. The second dialog box allows you to select a hard drive and directory path to copy the installation files into. The third dialog box lets you specify the hard drive and directory path. In addition, this dialog box lets you specify the disk size to be used to simulate the disk image as it copies the installation files into the appropriate subdirectories.
TIP: You should delete all of the subdirectories and files in the target directory or disks before continuing. The Setup Wizard will not do this for you.
CAUTION: You cannot choose the root directory of a network or local drive unless it is a floppy drive.
If the directory path you specify does not exist, you will be asked whether it is okay to create the directory path. Also, if your application uses Data Access Objects (DAO), then Setup Wizard lets you select any ISAM database format(s) you may be using in your application. You can also specify the type of workspace you will be using in the application: Jet or ODBCDirect.
The differences between these workspaces are as follows:
NOTE: You cannot clear both of these options. You must have one or both of them selected to proceed to the next step.
In the next several dialog boxes in the setup build process, you can add any of the following items that you might need for your application:
After making sure that all of the files and options you need for your application are specified, you can complete the process and create the installation program. The final dialog box lets you save all of the information you have entered for this setup as a template (see Figure 22.5). This enables you to re-create the setup for your application by using the template instead of re-entering all of the information.
FIG. 22.5
Saving the template before completing the setup creation.
Setup Wizard compresses the files and copies them to the specified target directories or disks. Remember, if you choose floppy disks as the distribution method, have enough blank disks ready to use.
After you have finished the creation process for the setup program, you should test it. The reason for testing the setup is to ensure that all of the files required by your application have been installed properly on the user's PC. Testing the setup program on your development PC will not result in an accurate test. Using a PC that does not have Visual Basic 5 or your application installed on it to perform the testing will enable you to find any problems that may exist with the setup program. This actually tests your application and setup program to make sure that all of the required files and setup parameters have been installed properly on the user's PC.
NOTE: Before retesting the setup program, you should run the uninstall process to remove all files that your application installed. This allows you to recheck your setup program to ensure that all of the correct files are being installed on the PC.
Testing the setup program to make sure it works correctly prevents users from getting frustrated when problems appear during the installation process.
When you distribute your application, you probably will be including custom controls, dynamic link libraries, or complete applications with your product. To do this, you must have the legal right to redistribute these components. There actually are two types of licensing: design-time licensing and run time licensing. The type of licensing you are required to get depends on the type of application you create and how you plan to distribute it.
See "Using the Property Pages Wizard," Chapter 24
If you are creating controls, you need to include in the design the capability to implement licensing for both design time and run time users.
When you are deciding how to sell your product, you have three primary choices: to sell your product on your own, to sell it with the help of another company, or to distribute your product into the world of shareware. Shareware is a very different way to sell your product. Shareware products are not sold through the use of advertising, direct mail, or catalogs--shareware products generally are sold by word of mouth. If the product is good, users will tell others your software is good, and so on until many users are interested in it. There is one drawback to a shareware product. The users can't be made to pay for the copies of the product that they receive. To encourage people to pay for the shareware product if they decide to keep it, most shareware products use either of two methods.
The first method is called a ag dialog box. Every time the shareware product is started, the user is presented with a Nag dialog reminding them that the product is not free and that they should pay the specified amount to get a registered copy and upgrades from the company. The second method is to build in a Kill switch, which, after a preset number of days or uses, causes the product to stop working.
Many of the online services available today, such as CompuServe and America Online, have areas for the posting of shareware products. In addition, catalogs of shareware products have popped up over the years. Of course, the best part of selling your product as shareware is the small amount of money required to do so.
By comparison, the retail world is more costly and more confusing. Retailing your product often concerns everything but programming. You can advertise your product through the following media:
Each of these options has its own associated costs and concerns. You should also investigate paying a catalog to advertise your product for you. For those who have a small budget, this is probably one of the best methods of selling a product. The catalog company does all of the advertising and order-processing for you--at a price. Generally, the catalog takes a percentage of the sale price for its services.
This chapter has briefly covered what it takes to create an application package to sell. You have seen that the application itself is only a small portion of the entire package. In addition, this chapter has covered some of the legal issues that you need to deal with when creating an application. Now that you have a good understanding of a standard Visual Basic application, you should look into some of the following options available to you from the Visual Basic environment:
© Copyright, Macmillan Computer Publishing. All rights reserved.