One of the best—and worst—features of Visual C++ are its many code-generation wizards. (See Figure 4-3.) Wizards help developers kick-start new projects, components, and classes by providing ready-to-compile starter code. The "new project" wizards generate fully functional projects complete with source files, resource files, and a makefile containing various build configurations that specify appropriate default compiler and linker settings. The downside to the wizards is that they lull novice developers into a false sense of security. Wizards provide an adequate starting point, but they don't supply information about how to get to the finish line. Developers who don't understand the generated code and how it works will find themselves in trouble as soon as the requirements of their application diverge from the educated guesses made by the wizards.
Figure 4-3. The Visual C++ "new project" wizards.
Although we recommend the ATL COM AppWizard to developers of all skill levels, we think it's a good idea to create an ATL project from scratch at least once, if only to force yourself to recognize that the wizard makes a number of design decisions for you, including apartment model, marshaler, type library name, build configurations, compiler settings, and preprocessor symbols.
The ATL COM AppWizard is no exception. Because the ATL syntax and semantics are sophisticated, with an abundance of complex templates and tricky macros, the ATL COM AppWizard is essentially a required starting point for new ATL projects. But without a solid understanding of COM, you'll have a hard time even answering the questions the wizard poses, let alone developing effective COM-based applications. For example, Step 1 of the ATL COM AppWizard expects you to know about proxies and stubs and whether or not they should be merged into the component you're developing. (See Figure 4-4.) Online help provides some insights, but it's certainly not a replacement for a basic comprehension of COM. Clearly, wizards aren't much help unless you understand the implications of the choices they offer. For that reason, we've dedicated an entire chapter (Chapter 9) to an explanation of the various ATL wizard options and their implications for your components.
Figure 4-4. A potentially confusing check box in the ATL COM AppWizard and its online help.
As you can see in Figure 4-3 and Figure 4-4, we accepted the default ATL COM AppWizard choices to create an empty DLL-based (in-process) COM server named TipServer.DLL. We might have instead chosen an EXE server or a Microsoft Windows NT service, but we felt that an in-process server was better suited for use in conjunction with Microsoft Internet Information Server (IIS) and eventual use within the Microsoft Transaction Server (known as Microsoft Component Services in Windows 2000) environment. Table 4-1 explains the reasons you might choose one server option over another.
Table 4-1. The Three Types of COM Server.
|In-process DLL||This type offers the best performance of any server type because an object running inside the same apartment as its clients requires no marshaling overhead. Microsoft ActiveX controls must be housed in in-process servers. In-process servers currently offer the best potential for throughput; the version of Microsoft Component Services available at the time of this writing supports only in-process servers.|
|Out-of-process EXE||This type has reduced performance compared to in-process servers because all method calls require method remoting. The strengths of out-of-process servers are that they offer increased fault isolation, separate security credentials, and the benefit of distributed computation.|
|Out-of-process Windows NT service||This type is similar to an out-of-process server, but a Windows NT service can execute using the built-in System account.*|
* It is our experience that most developers choose the Windows NT service option in the ATL COM AppWizard for two reasons: as a way of ensuring that a COM server remains running even when no objects are active, and as a means of providing a standard way for administrators to shut down or restart the server when something goes wrong. Only the second reason carries any weight, since the preferred way to keep a server running is simply to keep its lock count above zero.
Recall from the COM overview in Chapter 2 that a COM server is a binary module that houses one or more COM classes. The ATL COM AppWizard generates all the code necessary to compile and register a COM server, but it doesn't actually add any coclasses to the server. That addition is the responsibility of the ATL Object Wizard, as we'll describe later in this chapter. Figure 4-5 shows the wizard-generated TipServer workspace along with its accompanying project files.
Figure 4-5. The wizard-generated TipServer project.