| Introduction | xv |
| PART I DESIGN | |
| 1 Creating Object and Project Templates | 3 |
| Using Object Templates | 3 |
| Using Project Templates | 5 |
| Creating Custom Project Templates | 5 |
| Directives | 9 |
| 1.1 Never hard-code application-specific or component-specific values in object templates. | 9 |
| 1.2 Provide extensive comments and tasks in object templates, particularly where modifications are required. | 11 |
| 2 Designing Modules and Procedures | 13 |
| Create Modules That Have Strong Cohesion | 14 |
| Create Loosely Coupled, Highly Specialized Procedures | 16 |
| Make All Procedures Perform Specialized Functions | 16 |
| Make Procedures as Self-Contained as Possible | 18 |
| Minimize Fan-In and Fan-Out | 19 |
| Attempt to Alphabetize Procedures Within a Module | 20 |
| Directives | 21 |
| 2.1 Give procedures and modules descriptive names. | 21 |
| 2.2 Give every procedure a single exit point. | 23 |
| 2.3 Give every procedure a clearly defined scope. | 24 |
| 2.4 Use parameters to pass data between procedures. | 26 |
| 2.5 Call procedures in a consistent and self-documenting manner. | 29 |
| 2.6 Return values from a function by using the Return statement. | 31 |
| 2.7 Use a scratch variable within complex functions. | 31 |
| PART II CONVENTIONS | |
| 3 Naming Conventions | 35 |
| Hungarian Notation | 36 |
| When Not to Use Hungarian Notation | 38 |
| Denoting a Variable's Data Type | 39 |
| Denoting a Variable's Scope | 41 |
| Other Object Prefixes | 41 |
| 4 Using Constants and Enumerations | 45 |
| Using Constants | 45 |
| Magic Numbers Are Prone to Data-Entry Problems | 46 |
| Magic Numbers Are Difficult to Update | 46 |
| Constants Make Code Easier to Read | 47 |
| Using Enumerations | 47 |
| Creating Custom Enumerations | 49 |
| Using a Custom Enumeration | 49 |
| Directives | 51 |
| 4.1 Prefix all constants with c_ and a scope designator. | 51 |
| 4.2 Use constants in place of magic numbers, regardless of scope. | 53 |
| 4.3 Use enumerations whenever they are available. | 54 |
| 4.4 Use an enumeration whenever a parameter accepts a limited number of values. | 55 |
| 4.5 Validate values that are passed as enumerated types. | 56 |
| 5 Variables | 59 |
| Directives | 60 |
| 5.1 Define focused variables. | 60 |
| 5.2 Give variables descriptive names. | 63 |
| 5.3 Use mixed case in variable names. | 67 |
| 5.4 Abbreviate only frequently used or long terms. | 67 |
| 5.5 Use qualifiers consistently. | 68 |
| 5.6 Use the positive form in Boolean variables. | 69 |
| 5.7 Explicitly declare variables. | 71 |
| 5.8 Declare variables with carefully chosen data types. | 73 |
| 5.9 Use the Object data type only when absolutely necessary. | 77 |
| 5.10 Use Option Strict to enforce strict typing. | 80 |
| 5.11 Minimize variable scope. | 82 |
| 5.12 Use initializers whenever possible. | 85 |
| 5.13 Concatenate strings by using an ampersand. | 85 |
| 5.14 Use a string's length property to determine whether it's empty. | 86 |
| PART III CODING CONSTRUCTS | |
| 6 Formatting Code | 89 |
| Directives | 93 |
| 6.1 Do not place multiple statements on a single line. | 93 |
| 6.2 Use the line continuation character. | 94 |
| 6.3 Indent continuation lines. | 99 |
| 6.4 Use indentation to show organizational structure. | 103 |
| 6.5 Indent code within the Declarations section of a module to show subordination. | 110 |
| 6.6 Use white space to group related statements. | 111 |
| 6.7 Create collapsible code regions to create more manageable code. | 118 |
| 7 Commenting Code | 121 |
| Directives | 122 |
| 7.1 Document the purpose of the code. | 122 |
| 7.2 If you need to violate good programming style, explain why. | 123 |
| 7.3 Comment before writing code. | 124 |
| 7.4 Use solid-character comment lines only for major comments. | 125 |
| 7.5 Avoid creating comment boxes. | 127 |
| 7.6 Use an apostrophe to denote comments. | 128 |
| 7.7 Make your comments readable. | 130 |
| 7.8 Indent comments to align them with the statements that follow. | 132 |
| 7.9 Give each procedure a comment header. | 132 |
| 7.10 Document code processes by using inline comments. | 136 |
| 7.11 Use end-of-line comments to document variable declarations. | 141 |
| 8 Looping Structures | 143 |
| Directives | 144 |
| 8.1 Use For.Next to loop a specific number of times. | 144 |
| 8.2 Use Do.Loop to loop an undetermined number of times. | 152 |
| 8.3 Use Do.Loop in place of While.EndWhile. | 158 |
| 8.4 Use For Each.Next to loop through all members of a collection. | 158 |
| 9 Controlling Code Flow | 163 |
| Directives | 164 |
| 9.1 Use If.Then.Else when the decision is based on one condition being True or False. | 164 |
| 9.2 Use Select Case when comparing a non-Boolean expression to a variety of possible values. | 167 |
| 9.3 Use end-of-line comments to add clarity to nested decision structures. | 172 |
| 9.4 Format expressions for accurate evaluation and ease of understanding. | 174 |
| 9.5 Use GoTo only when no other alternatives exist. | 176 |
| 10 Exception Handling | 179 |
| The Exception Object | 180 |
| Types of Exception Handlers | 181 |
| Writing an Exception Handler by Using Try...Catch...Finally | 182 |
| Catching Exceptions | 184 |
| Exception Handlers and the Call Stack | 187 |
| Central Exception Handlers | 190 |
| Logging Exceptions to a Text File | 193 |
| Directives | 196 |
| 10.1 Use Try.Catch.Finally to handle unexpected as well as anticipated exceptions. | 196 |
| 10.2 Use a consistent format when dealing with unanticipated exceptions. | 197 |
| 10.3 Never blame the user. | 198 |
| PART IV ADVANCED PROGRAMMING | |
| 11 Programming Objects | 203 |
| What Is an Object? | 203 |
| Garbage Collection | 204 |
| Directives | 206 |
| 11.1 Early bind objects whenever possible. | 206 |
| 11.2 Use .NET objects rather than API calls whenever possible. | 209 |
| 11.3 Expose public properties, not public variables. | 211 |
| 11.4 Always close what you open. | 212 |
| 11.5 Use Overloads to create a property or method with the same name as another property or method but with a different argument list. | 213 |
| 11.6 Create Dispose methods for all of your objects. | 214 |
| 11.7 Create constructors for a class whenever possible. | 217 |
| 11.8 Add a finalizer to a class only when necessary. | 221 |
| 11.9 Force garbage collection only when necessary. | 223 |
| 11.10 Use With.End With to increase performance and make code more readable. | 223 |
| 12 File Operations | 225 |
| System.IO | 225 |
| System.IO.File and System.IO.Directory | 226 |
| System.IO.Path | 229 |
| System.Environment | 231 |
| Directives | 232 |
| 12.1 Save all temporary files in the user's Temp folder. | 232 |
| 12.2 Save temporary files with a system-assigned temporary file name. | 234 |
| 12.3 Close all files that you open as soon as you no longer need access to them. | 235 |
| 12.4 Never hard-code a path in an application. | 237 |
| 12.5 Use System.IO.Path to manipulate file paths. | 237 |
| 12.6 Default saving files in the user's My Documents folder. | 238 |
| 12.7 Add files to a user's Recent Documents list | 239 |
| 12.8 Ask for confirmation before deleting an important file. | 240 |
| 13 Debugging | 243 |
| Visual Basic 6 to Visual Basic .NET | 244 |
| Viewing Expression Values by Using Data Tips | 244 |
| Defining Assertions by Using Debug.Assert | 246 |
| Conditional Compilation | 248 |
| Writing Conditionally Compiled Code | 248 |
| Setting Compiler Constants by Using the Property Pages Dialog Box | 250 |
| Setting Compiler Constants by Using the Command Line | 251 |
| Breakpoints | 252 |
| Creating and Removing Breakpoints | 253 |
| Entering Break Mode | 254 |
| Managing Breakpoints by Using the Breakpoints Window | 255 |
| Entering Break Mode with the Stop Statement | 259 |
| The Visual Basic .NET Debugging Windows | 259 |
| Autos Window | 260 |
| Locals Window | 262 |
| Me Window | 263 |
| Watch Window | 263 |
| QuickWatch Window | 264 |
| Command Window | 265 |
| Output Window | 267 |
| Task List Window | 268 |
| Modules Window | 271 |
| Memory Window | 271 |
| Call Stack Window | 272 |
| Directives | 274 |
| 13.1 Start a project without debugging rather than remove or disable debug code. | 274 |
| 13.2 Don't create an expression that modifies data when calling Debug.Assert. | 274 |
| 13.3 Specify custom assertion text when the purpose of the assertion isn't obvious. | 275 |
| 13.4 Use Option Strict whenever possible. | 275 |
| 13.5 Add exception handling to all of your procedures | 275 |
| 13.6 Use the inherent DEBUG constant for conditionally compiled debug code. | 276 |
| 13.7 Use breakpoints to ensure that all parts of a complicated procedure have been executed. | 276 |
| 13.8 When possible, use a breakpoint instead of a Stop statement. | 276 |
| 13.9 Create TODO tasks for things that still need to be addressed. | 277 |
| PART V USER INTERACTION | |
| 14 Interface Design | 281 |
| The Necessity of Consistent Interface Design | 281 |
| Directives | 284 |
| 14.1 Give forms a consistent appearance and behavior. | 284 |
| 14.2 Present controls with a standard appearance. | 301 |
| 14.3 Use the best interface component for a given situation. | 308 |
| 14.4 Provide comprehensive and sensible menus. | 315 |
| 14.5 Use system colors wherever possible. | 323 |
| 15 User Input and Notification | 327 |
| User Input | 328 |
| Notifications | 329 |
| Directives | 330 |
| 15.1 Ensure thorough keyboard navigation and interaction. | 330 |
| 15.2 Provide consistent and intuitive mouse interaction. | 337 |
| 15.3 Create thoughtful and functional message boxes. | 346 |
| 15.4 If your application lets a user open and save a lot of files, make your application remember the user's chosen paths. | 353 |
| 16 Distributing Solutions | 355 |
| Preparing Your Project for Distribution | 355 |
| Creating a Custom Setup Program | 356 |
| Adding the Output of a Project | 358 |
| Specifying the Build Options of a Project's Output | 362 |
| Adding a File to the Installer | 363 |
| File Properties | 364 |
| Changing the Default Location of the Application Folder | 365 |
| Working with Folders on the Target Machine | 368 |
| Changing the Folder in Which a File Is Installed | 371 |
| Creating Shortcuts | 371 |
| Modifying the Registry on Installation | 371 |
| Modifying the User Interface of Your Custom Setup Program | 373 |
| Specifying Configuration Details | 376 |
| Specifying Uninstall Information | 377 |
| Building the Custom Setup Program | 379 |
| Directives | 380 |
| 16.1 Spell-check your interface. | 380 |
| 16.2 Adjust the alignment of controls on all forms. | 380 |
| 16.3 Test the tab order of all forms. | 381 |
| 16.4 Check for duplicate access keys. | 381 |
| 16.5 Check all dialog boxes for accept and cancel buttons. | 381 |
| 16.6 Check the format of your message boxes. | 382 |
| 16.7 Ensure that every procedure has an exception handler. | 382 |
| 16.8 Verify that you are using the proper versions of third-party components. | 382 |
| 16.9 Assign a logical root namespace to all distributed programs. | 382 |
| 16.10 Thoroughly test and debug your program. | 383 |
| 16.11 Check your conditional compilation constants. | 383 |
| 16.12 Avoid installing files to the user's desktop. | 383 |
| 16.13 Don't place shortcuts directly in the Program Files folder. | 384 |
| 16.14 Include a bootstrapper unless you are certain all target machines have the appropriate Windows Installer technology installed. | 384 |
| 16.15 Name your setup projects ProgramName Installer. | 384 |
| 16.16 Set the version number of your project appropriately. | 384 |
| 16.17 Give every installed component a meaningful icon. | 385 |
| 16.18 Always use the path [ProgramFilesFolder][Manufacturer]\[ProductName] as the default Application Folder. | 385 |
| 16.19 Create all custom folders under your Application Folder unless you have a specific reason to do otherwise. | 385 |
| 16.20 Include debug information only if you intend to use it. | 385 |
| 16.21 Set the SharedLegacy property of all COM files to True. | 386 |
| 16.22 Set the Vital property of critical files to True. | 386 |
| 16.23 Set the build order appropriately for the setup project. | 386 |
| 16.24 Set all custom-created registry keys to DeleteAtUninstall unless you have a specific reason to do otherwise. | 388 |
| PART VI TEAM PROJECTS | |
| 17 Version Control | 391 |
| Understanding Assemblies | 392 |
| Directives | 397 |
| 17.1 Increment the version number each time you compile a program. | 397 |
| 17.2 Display a program's version number in the About dialog box. | 398 |
| 17.3 Install a component in the same folder as the client using the component. | 399 |
| 17.4 Preserve compatibility when rolling out a new version of a component. | 400 |
| 17.5 Document changes in a Readme file. | 403 |
| 17.6 Back up your files. | 404 |
| 17.7 Use Microsoft Visual SourceSafe to maintain versions of source code. | 404 |
| 18 Source Code Control | 405 |
| Identifying the Challenges of Team Development | 406 |
| Understanding Visual SourceSafe | 407 |
| Setting Up Visual SourceSafe | 408 |
| Creating a Visual SourceSafe Database | 409 |
| Opening a Visual SourceSafe Database | 410 |
| Adding Users to a Visual SourceSafe Database | 412 |
| Placing a Visual Basic Project Under Visual SourceSafe Control | 413 |
| Visual Basic Projects and Visual SourceSafe | 416 |
| Designating a Working Folder | 417 |
| Creating a Working Copy of the Project | 419 |
| Checking Out Files by Using Visual SourceSafe Explorer | 420 |
| Checking Files In and Out from the Visual Basic IDE | 422 |
| Adding New Files to a Project Under Source Code Control | 425 |
| Getting the Latest Version of Files | 426 |
| Comparing Revisions | 427 |
| APPENDIX | 431 |
| INDEX | 443 |