Ivor Horton’s Beginning Visual C++ 2005 (Programmer to Programmer) 9780764571978

内容简介 · · · · · · Popular author Ivor Horton uses his trademark approachable writing style to provide novice programmers

414 63 18MB

English Pages 1226 Year 2006

Report DMCA / Copyright

DOWNLOAD FILE

Polecaj historie

Ivor Horton’s Beginning Visual C++ 2005 (Programmer to Programmer)
 9780764571978

Table of contents :
Contents......Page 16
C++/CLI Specific: Fundamental Data Types......Page 141
C++/CLI Output to the Command Line......Page 146
C++/CLI Input from the Keyboard......Page 149
Using safe_cast......Page 150
C++/CLI Enumerations......Page 151
Chapter 3 - C++/CLI Programming......Page 192
The for each Loop......Page 195
Chapter 4 - C++/CLI Programming......Page 240
Tracking Handles......Page 241
CLR Arrays......Page 242
Strings......Page 258
Interior Pointers......Page 267
Chapter 5 - C++/CLI Programming......Page 307
Functions Accepting a Variable Number of Arguments......Page 308
Arguments to main()......Page 309
Chapter 6 - C++/CLI Programming......Page 350
Understanding Generic Functions......Page 351
A Calculator Program for the CLR......Page 357
Chapter 7 - C++/CLI Programming......Page 414
Defining Value Class Types......Page 415
The ToString() Function in a Class......Page 418
Literal Fields......Page 419
Defining Reference Class Types......Page 420
Class Properties......Page 423
initonly Fields......Page 436
Static Constructors......Page 438
Overloading Operators in Value Classes......Page 503
Overloading Operators in Reference Classes......Page 509
Inheritance in C++/CLI Classes......Page 562
Interface Classes......Page 568
Defining Interface Classes......Page 569
Classes and Assemblies......Page 573
Delegates and Events......Page 578
Destructors and Finalizers in Reference Classes......Page 591
Generic Classes......Page 593
Using the Debug and Trace Classes......Page 644

Citation preview

Ivor Horton’s

Beginning Visual C++® 2005 Ivor Horton

Ivor Horton’s

Beginning Visual C++® 2005

Ivor Horton’s

Beginning Visual C++® 2005 Ivor Horton

Ivor Horton’s Beginning Visual C++® 2005 Published by Wiley Publishing, Inc. 10475 Crosspoint Boulevard Indianapolis, IN 46256 www.wiley.com Copyright © 2006 by Ivor Horton Published by Wiley Publishing, Inc., Indianapolis, Indiana Published simultaneously in Canada ISBN-13: 978-0-7645-7197-8 ISBN-10: 0-7645-7197-4 Manufactured in the United States of America 10 9 8 7 6 5 4 3 2 1 1B/QY/QS/QW/IN Library of Congress Cataloging-in-Publication Data: Horton, Ivor. Ivor Horton’s Beginning Visual C++ 2005 / Ivor Horton. p. cm. Includes index. ISBN-13: 978-0-7645-7197-8 (paper/website) ISBN-10: 0-7645-7197-4 (paper/website) 1. C++ (Computer program language) 2. Microsoft Visual C++. I. Title: Beginning Visual C++ 2005. II. Title. QA76.73.C15I6694 2006 005.13’3—dc22 2005032051 No part of this publication may be reproduced, stored in a retrieval system or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, scanning or otherwise, except as permitted under Sections 107 or 108 of the 1976 United States Copyright Act, without either the prior written permission of the Publisher, or authorization through payment of the appropriate per-copy fee to the Copyright Clearance Center, 222 Rosewood Drive, Danvers, MA 01923, (978) 750-8400, fax (978) 646-8600. Requests to the Publisher for permission should be addressed to the Legal Department, Wiley Publishing, Inc., 10475 Crosspoint Blvd., Indianapolis, IN 46256, (317) 572-3447, fax (317) 572-4355, or online at http://www.wiley.com/go/permissions. LIMIT OF LIABILITY/DISCLAIMER OF WARRANTY: THE PUBLISHER AND THE AUTHOR MAKE NO REPRESENTATIONS OR WARRANTIES WITH RESPECT TO THE ACCURACY OR COMPLETENESS OF THE CONTENTS OF THIS WORK AND SPECIFICALLY DISCLAIM ALL WARRANTIES, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE. NO WARRANTY MAY BE CREATED OR EXTENDED BY SALES OR PROMOTIONAL MATERIALS. THE ADVICE AND STRATEGIES CONTAINED HEREIN MAY NOT BE SUITABLE FOR EVERY SITUATION. THIS WORK IS SOLD WITH THE UNDERSTANDING THAT THE PUBLISHER IS NOT ENGAGED IN RENDERING LEGAL, ACCOUNTING, OR OTHER PROFESSIONAL SERVICES. IF PROFESSIONAL ASSISTANCE IS REQUIRED, THE SERVICES OF A COMPETENT PROFESSIONAL PERSON SHOULD BE SOUGHT. NEITHER THE PUBLISHER NOR THE AUTHOR SHALL BE LIABLE FOR DAMAGES ARISING HEREFROM. THE FACT THAT AN ORGANIZATION OR WEBSITE IS REFERRED TO IN THIS WORK AS A CITATION AND/OR A POTENTIAL SOURCE OF FURTHER INFORMATION DOES NOT MEAN THAT THE AUTHOR OR THE PUBLISHER ENDORSES THE INFORMATION THE ORGANIZATION OR WEBSITE MAY PROVIDE OR RECOMMENDATIONS IT MAY MAKE. FURTHER, READERS SHOULD BE AWARE THAT INTERNET WEBSITES LISTED IN THIS WORK MAY HAVE CHANGED OR DISAPPEARED BETWEEN WHEN THIS WORK WAS WRITTEN AND WHEN IT IS READ. For general information on our other products and services please contact our Customer Care Department within the United States at (800) 762-2974, outside the United States at (317) 572-3993 or fax (317) 572-4002. Trademarks: Wiley, the Wiley logo, Wrox, the Wrox logo, Programmer to Programmer, and related trade dress are trademarks or registered trademarks of John Wiley & Sons, Inc. and/or its affiliates, in the United States and other countries, and may not be used without written permission. Visual C++ is a registered trademark of Microsoft Corporation in the United States and/or other countries. All other trademarks are the property of their respective owners. Wiley Publishing, Inc., is not associated with any product or vendor mentioned in this book. Wiley also publishes its books in a variety of electronic formats. Some content that appears in print may not be available in electronic books.

Credits Executive Editor

Vice President and Executive Publisher

Bob Elliott

Joseph B. Wikert

Senior Development Editor

Project Coordinator

Kevin Kent

Development Editor Howard Jones

Technical Editor John Mueller

Production Editor Pamela Hanley

Copy Editor Susan Hobbs

Editorial Manager Mary Beth Wakefield

Production Manager Tim Tate

Ryan Steffen

Graphics and Production Specialists Brian Drumm Lauren Goddard Brooke Graczyk Denny Hager Joyce Haughey Jennifer Heleine Stephanie D. Jumper Barry Offringa Alicia South Erin Zeltner

Quality Control Technicians Laura Albert John Greenough Leeann Harney

Proofreading TECHBOOKS Production Services

Vice President and Executive Group Publisher

Indexing

Richard Swadley

Infodex Indexing Services Inc.

About the Author Ivor Horton graduated as a mathematician and was lured into information technology by promises of great rewards for very little work. In spite of the reality being usually a great deal of work for relatively modest rewards, he has continued to work with computers to the present day. He has been engaged at various times in programming, systems design, consultancy, and the management of the implementation of projects of considerable complexity. Horton has many years of experience in the design and implementation of computer systems applied to engineering design and to manufacturing operations in a variety of industries. He also has considerable experience in developing occasionally useful applications in a wide variety of programming languages, and of teaching primarily scientists and engineers to do likewise. He has written books on programming for more than 10 years; his currently published works include tutorials on C, C++, and Java. At the present time, when he is not writing programming books or providing advice to others, he spends his time fishing, travelling, and trying to speak better French.

This book is dedicated to Alexander Gilbey. I look forward to his comments, but I’ll probably have to wait a while.

Acknowledgments I’d like to acknowledge the efforts and support of the John Wiley & Sons, and Wrox Press editorial and production team in the production of this book, especially Senior Development Editor Kevin Kent who has been there from way back at the beginning and has stayed through to the end. I’d also like to thank Technical Editor John Mueller for going through the text to find hopefully most of my mistakes, for checking out all the examples in the book, and for his many constructive comments that helped make the book a better tutorial. Finally, I would like to thank my wife, Eve, for her patience, cheerfulness, and support throughout the long gestation period of this book. As I have said on many previous occasions, I could not have done it without her.

Contents Acknowledgments

Chapter 1: Programming with Visual C++ 2005 The .NET Framework The Common Language Runtime (CLR) Writing C++ Applications Learning Windows Programming Learning C++ The C++ Standards Console Applications Windows Programming Concepts

What Is the Integrated Development Environment? Components of the System The The The The

Editor Compiler Linker Libraries

Using the IDE Toolbar Options Dockable Toolbars Documentation Projects and Solutions

xi

1 2 2 3 4 5 5 6 6

8 9 9 9 9 9

10 10 12 12 13

Defining a Project Debug and Release Versions of Your Program Dealing with Errors

13 19 23

Setting Options in Visual C++ 2005 Creating and Executing Windows Applications

27 28

Creating an MFC Application Building and Executing the MFC Application

28 30

Creating a Windows Forms Application

Summary

31

35

xiii

Contents Chapter 2: Data, Variables, and Calculations The Structure of a C++ Program Program Comments The #include Directive — Header Files Namespaces and the Using Declaration

The main() Function Program Statements Whitespace Statement Blocks Automatically Generated Console Programs

37 38 44 45 46

46 47 49 49 50

Defining Variables

51

Naming Variables

51

Keywords in C++

Declaring Variables Initial Values for Variables

52

52 53

Fundamental Data Types

54

Integer Variables Character Data Types Integer Type Modifiers The Boolean Type Floating-Point Types

54 55 56 57 57

Fundamental Types in ISO/ANSI C++

Literals Defining Synonyms for Data Types Variables with Specific Sets of Values Specifying the Type for Enumeration Constants

58

59 60 60 62

Basic Input/Output Operations

62

Input from the Keyboard Output to the Command Line Formatting the Output Escape Sequences

62 63 64 65

Calculating in C++ The Assignment Statement Understanding Lvalues and Rvalues

Arithmetic Operations

xiv

67 67 68

68

The const Modifier Constant Expressions Program Input Calculating the Result Displaying the Result

70 70 71 71 73

Calculating a Remainder

73

Contents Modifying a Variable The Increment and Decrement Operators The Sequence of Calculation

73 74 77

Operator Precedence

77

Variable Types and Casting

78

Rules for Casting Operands Casts in Assignment Statements Explicit Casts Old-Style Casts The Bitwise Operators The The The The The

Bitwise Bitwise Bitwise Bitwise Bitwise

AND OR Exclusive OR NOT Shift Operators

Understanding Storage Duration and Scope Automatic Variables Positioning Variable Declarations Global Variables Static Variables

Namespaces Declaring a Namespace Multiple Namespaces

C++/CLI Programming

78 79 80 81 81 82 84 85 86 86

88 88 91 91 94

95 96 98

99

C++/CLI Specific: Fundamental Data Types C++/CLI Output to the Command Line C++/CLI Specific — Formatting the Output C++/CLI Input from the Keyboard Using safe_cast C++/CLI Enumerations

99 104 104 107 108 109

Specifying a Type for Enumeration Constants Specifying Values for Enumeration Constants

111 111

Summary Exercises

Chapter 3: Decisions and Loops Comparing Values The if Statement Nested if Statements The Extended if Statement Nested if-else Statements

112 113

115 115 117 118 120 122

xv

Contents Logical Operators and Expressions Logical AND Logical OR Logical NOT

The Conditional Operator The switch Statement Unconditional Branching

Repeating a Block of Statements What Is a Loop? Variations on the for Loop Using the continue Statement Floating-Point Loop Counters

The while Loop The do-while Loop Nested Loops

C++/CLI Programming The for each Loop

Summary Exercises

Chapter 4: Arrays, Strings, and Pointers Handling Multiple Data Values of the Same Type Arrays Declaring Arrays Initializing Arrays Character Arrays and String Handling String Input

Multidimensional Arrays Initializing Multidimensional Arrays

124 125 125 126

127 129 132

132 132 135 139 143

143 146 147

150 153

156 157

159 160 160 161 164 166 167

169 170

Indirect Data Access

172

What Is a Pointer? Declaring Pointers

172 173

The Address-Of Operator

Using Pointers The Indirection Operator Why Use Pointers?

Initializing Pointers Pointers to char

The sizeof Operator Constant Pointers and Pointers to Constants

xvi

173

174 174 174

176 177

181 183

Contents Pointers and Arrays Pointer Arithmetic Using Pointers with Multidimensional Arrays Pointer Notation with Multidimensional Arrays

Dynamic Memory Allocation The Free Store, Alias the Heap The new and delete Operators Allocating Memory Dynamically for Arrays Dynamic Allocation of Multidimensional Arrays

Using References What Is a Reference? Declaring and Initializing References

C++/CLI Programming Tracking Handles Declaring Tracking Handles

CLR Arrays Sorting One-Dimensional Arrays Searching One-Dimensional Arrays Multidimensional Arrays Arrays of Arrays

Strings Joining Strings Modifying Strings Searching Strings

Tracking References Interior Pointers

Summary Exercises

Chapter 5: Introducing Structure into Your Programs Understanding Functions Why Do You Need Functions? Structure of a Function The Function Header The Function Body The return Statement

Using a Function Function Prototypes

Passing Arguments to a Function The Pass-by-value Mechanism Pointers as Arguments to a Function

185 185 190 191

192 192 193 194 196

197 197 197

198 199 199

200 205 206 209 213

216 217 220 222

225 225

228 230

231 232 233 233 233 234 235

235 235

239 240 241

xvii

Contents Passing Arrays to a Function Passing Multi-Dimensional Arrays to a Function

References as Arguments to a Function Use of the const Modifier Arguments to main() Accepting a Variable Number of Function Arguments

Returning Values from a Function Returning a Pointer A Cast Iron Rule for Returning Addresses

Returning a Reference A Teflon-Coated Rule: Returning References

Static Variables in a Function

Recursive Function Calls Using Recursion

C++/CLI Programming Functions Accepting a Variable Number of Arguments Arguments to main()

Summary Exercises

Chapter 6: More about Program Structure Pointers to Functions Declaring Pointers to Functions A Pointer to a Function as an Argument Arrays of Pointers to Functions

243 245

247 249 250 252

254 254 256

258 260

260

262 264

265 266 267

268 269

271 271 272 275 277

Initializing Function Parameters Exceptions

277 279

Throwing Exceptions Catching Exceptions Exception Handling in the MFC

281 282 283

Handling Memory Allocation Errors Function Overloading What Is Function Overloading? When to Overload Functions

Function Templates

284 285 286 288

288

Using a Function Template

289

An Example Using Functions

291

Implementing a Calculator

291

Analyzing the Problem

292

Eliminating Blanks from a String Evaluating an Expression

xviii

294 295

Contents Getting the Value of a Term Analyzing a Number Putting the Program Together Extending the Program Extracting a Substring Running the Modified Program

C++/CLI Programming Understanding Generic Functions Defining Generic Functions Using Generic Functions

A Calculator Program for the CLR Removing Spaces from the Input String Evaluating an Arithmetic Expression Obtaining the Value of a Term Evaluating a Number Extracting a Parenthesized Substring

Summary Exercises

Chapter 7: Defining Your Own Data Types The struct in C++ What Is a struct? Defining a struct Initializing a struct Accessing the Members of a struct Intellisense Assistance with Structures The struct RECT Using Pointers with a struct Accessing Structure Members through a Pointer The Indirect Member Selection Operator

Data Types, Objects, Classes and Instances

298 299 302 304 305 307

308 309 309 310

315 316 316 318 318 319

320 321

323 324 324 324 325 325 329 330 330 332 332

332

First Class Operations on Classes Terminology

334 334 335

Understanding Classes

335

Defining a Class Access Control in a Class

Declaring Objects of a Class Accessing the Data Members of a Class Member Functions of a Class

336 336

336 337 339

xix

Contents Positioning a Member Function Definition Inline Functions

Class Constructors What Is a Constructor? The Default Constructor Assigning Default Parameter Values in a Class Using an Initialization List in a Constructor

Private Members of a Class Accessing private Class Members The friend Functions of a Class Placing friend Function Definitions Inside the Class

The Default Copy Constructor

The Pointer this const Objects of a Class const Member Functions of a Class Member Function Definitions Outside the Class

Arrays of Objects of a Class Static Members of a Class Static Data Members of a Class Static Function Members of a Class

Pointers and References to Class Objects Pointers to Class Objects References to Class Objects Implementing a Copy Constructor

C++/CLI Programming Defining Value Class Types The ToString() Function in a Class Literal Fields

Defining Reference Class Types Class Properties Defining Scalar Properties Trivial Scalar Properties Defining Indexed Properties More Complex Indexed Properties Static Properties Reserved Property Names

initonly Fields Static Constructors

Summary Exercises

xx

341 342

343 343 345 347 350

350 353 354 356

356

358 360 361 362

363 364 365 367

368 368 371 371

372 373 376 377

378 381 382 384 388 392 393 394

394 396

396 397

Contents Chapter 8: More on Classes Class Destructors What Is a Destructor? The Default Destructor Destructors and Dynamic Memory Allocation

399 399 399 400 402

Implementing a Copy Constructor Sharing Memory Between Variables

405 407

Defining Unions Anonymous Unions Unions in Classes and Structures

408 409 410

Operator Overloading Implementing an Overloaded Operator Implementing Full Support for an Operator Overloading the Assignment Operator Fixing the Problem

Overloading the Addition Operator Overloading the Increment and Decrement Operators

Class Templates Defining a Class Template Template Member Functions

Creating Objects from a Class Template Class Templates with Multiple Parameters

Using Classes The Idea of a Class Interface Defining the Problem Implementing the CBox Class Comparing CBox Objects Combining CBox Objects Analyzing CBox Objects

Defining the CBox Class Adding Data Members Defining the Constructor Adding Function Members Adding Global Functions

Using Our CBox Class

Organizing Your Program Code Naming Program Files

C++/CLI Programming Overloading Operators in Value Classes Overloading the Increment and Decrement Operators Overloading Operators in Reference Classes

Summary Exercises

410 411 414 418 418

423 426

427 428 430

431 434

436 436 436 437 438 439 441

445 446 447 448 453

455

458 460

461 461 467 467

470 471

xxi

Contents Chapter 9: Class Inheritance and Virtual Functions Basic Ideas of OOP Inheritance in Classes

473 473 475

What Is a Base Class? Deriving Classes from a Base Class

475 476

Access Control Under Inheritance

479

Constructor Operation in a Derived Class Declaring Class Members to be Protected The Access Level of Inherited Class Members

The Copy Constructor in a Derived Class Class Members as Friends Friend Classes Limitations on Class Friendship

Virtual Functions What Is a Virtual Function? Using Pointers to Class Objects Using References With Virtual Functions Incomplete Class Definitions

Pure Virtual Functions Abstract Classes Indirect Base Classes Virtual Destructors

Casting Between Class Types Nested Classes C++/CLI Programming Inheritance in C++/CLI Classes Interface Classes Defining Interface Classes Classes and Assemblies Visibility Specifiers for Classes and Interfaces Access Specifiers for Class and Interface Members

Functions Specified as new Delegates and Events Declaring Delegates Creating Delegates Unbound Delegates Creating Events

Destructors and Finalizers in Reference Classes Generic Classes Generic Interface Classes Generic Collection Classes

Summary Exercises

xxii

482 486 489

490 495 496 496

497 499 501 503 504

505 505 508 511

516 516 520 520 526 527 531 531 531

536 536 537 537 541 545

549 551 554 555

561 562

Contents Chapter 10: Debugging Techniques Understanding Debugging Program Bugs Common Bugs

Basic Debugging Operations Setting Breakpoints Advanced Breakpoints

Setting Tracepoints Starting Debugging Inspecting Variable Values Viewing Variables in the Edit Window

Changing the Value of a Variable

Adding Debugging Code Using Assertions Adding Your Own Debugging Code

565 565 567 567

568 570 572

572 573 576 577

577

578 578 580

Debugging a Program

585

The Call Stack Step Over to the Error

585 587

Testing the Extended Class Finding the Next Bug

Debugging Dynamic Memory Functions Checking the Free Store Controlling Free Store Debug Operations Free Store Debugging Output

Debugging C++/CLI Programs Using the Debug and Trace Classes Generating Output Setting the Output Destination Indenting the Output Controlling Output Assertions

Summary

Chapter 11: Windows Programming Concepts Windows Programming Basics Elements of a Window Windows Programs and the Operating System Event-Driven Programs Windows Messages The Windows API Windows Data Types Notation in Windows Programs

591 593

593 594 595 596

602 602 603 604 604 605 607

611

613 614 614 616 617 617 617 618 619

xxiii

Contents The Structure of a Windows Program The WinMain() Function Specifying a Program Window Creating a Program Window Initializing the Program Window Dealing with Windows Messages A Complete WinMain() Function

Message Processing Functions The WindowProc() Function Decoding a Windows Message Ending the Program A Complete WindowProc() Function

A Simple Windows Program

620 621 623 625 627 627 631

632 633 633 636 636

637

Windows Program Organization The Microsoft Foundation Classes

638 640

MFC Notation How an MFC Program Is Structured

640 640

The Application Class The Window Class Completing the Program The Finished Product

Using Windows Forms Summary

Chapter 12: Windows Programming with the Microsoft Foundation Classes The Document/View Concept in MFC What Is a Document? Document Interfaces What Is a View? Linking a Document and Its Views Document Templates Document Template Classes

641 642 642 643

645 647

649 650 650 650 651 652 652 653

Your Application and MFC

653

Creating MFC Applications

655

Creating an SDI Application The Output from the MFC Application Wizard Viewing Project Files Viewing Classes The Class Definitions Creating an Executable Module

xxiv

657 660 662 663 664 667

Contents Running the Program How the Program Works

668 669

Creating an MDI Application

671

Running the Program

Summary Exercises

Chapter 13: Working with Menus and Toolbars Communicating with Windows

672

674 674

677 677

Understanding Message Maps

678

Message Handler Definitions

679

Message Categories Handling Messages in Your Program How Command Messages Are Processed

Extending the Sketcher Program Elements of a Menu

681 682 682

683 684

Creating and Editing Menu Resources

684

Adding a Menu Item to the Menu Bar Adding Items to the Element Menu Modifying Existing Menu Items Completing the Menu

684 686 687 687

Adding Handlers for Menu Messages Choosing a Class to Handle Menu Messages Creating Menu Message Functions Coding Menu Message Functions Adding Members to Store Color and Element Mode Initializing the New Class Data Members Running the Extended Example

Adding Message Handlers to Update the User Interface Coding a Command Update Handler Exercising the Update Handlers

Adding Toolbar Buttons Editing Toolbar Button Properties Exercising the Toolbar Buttons Adding Tooltips

Summary Exercises

688 690 690 692 692 694 696

697 697 699

700 701 703 703

704 705

xxv

Contents Chapter 14: Drawing in a Window

707

Basics of Drawing in a Window

707

The Window Client Area The Windows Graphical Device Interface What Is a Device Context? Mapping Modes

The Drawing Mechanism in Visual C++ The View Class in Your Application The OnDraw() Member Function

The CDC Class Displaying Graphics Drawing in Color

708 709 709 709

711 711 711

712 713 717

Drawing Graphics in Practice Programming the Mouse

721 725

Messages from the Mouse

725

WM_LBUTTONDOWN WM_MOUSEMOVE WM_LBUTTONUP

Mouse Message Handlers Drawing Using the Mouse Getting the Client Area Redrawn Defining Classes for Elements The CElement Class The CLine Class Calculating the Enclosing Rectangle for a Line The CRectangle Class The CCircle Class The CCurve Class Completing the Mouse Message Handlers

Exercising Sketcher Running the Example Capturing Mouse Messages

Summary Exercises

Chapter 15: Creating the Document and Improving the View What Are Collection Classes? Types of Collection The Type-Safe Collection Classes

xxvi

726 726 727

727 729 731 732 736 737 742 742 744 746 747

753 754 755

756 757

759 759 760 761

Contents Collections of Objects

761

The CArray Template Class Helper Functions The CList Template Class The CMap Template Class

761 763 763 768

The Typed Pointer Collections

771

The CTypedPtrList Template Class CTypePtrList Operations

771 771

Using the CList Template Class

773

Drawing a Curve Defining the CCurve Class Implementing the CCurve Class Exercising the CCurve Class

Creating the Document Using a CTypedPtrList Template Implementing the Document Destructor Drawing the Document Adding an Element to the Document Exercising the Document

Improving the View Updating Multiple Views Scrolling Views Logical Coordinates and Client Coordinates Dealing with Client Coordinates

Using MM_LOENGLISH Mapping Mode

Deleting and Moving Shapes Implementing a Context Menu Associating a Menu with a Class Choosing a Context Menu Identifying a Selected Element Exercising the Pop-Ups Checking the Context Menu Items

Highlighting Elements Drawing Highlighted Elements Exercising the Highlights

Servicing the Menu Messages Deleting an Element Moving an Element Getting the Elements to Move Themselves Exercising the Application

Dealing with Masked Elements Summary Exercises

774 775 777 778

779 779 780 781 783 784

785 785 787 789 790

792

793 794 795 797 798 800 800

802 806 807

807 807 808 811 814

814 815 816

xxvii

Contents Using a List Box Removing the Scale Dialog Creating a List Box Control Creating the Dialog Class Displaying the Dialog

Using an Edit Box Control Creating an Edit Box Resource Creating the Dialog Class The CString Class

Adding the Text Menu Item Defining a Text Element Implementing the CText Class The CText Constructor Drawing a CText Object Moving a CText Object

Creating a Text Element

Summary Exercises

Chapter 17: Storing and Printing Documents Understanding Serialization Serializing a Document Serialization in the Document Class Definition Serialization in the Document Class Implementation The Serialize() Function The CArchive Class

Functionality of CObject-Based Classes The Macros Adding Serialization to a Class

How Serialization Works How to Implement Serialization for a Class

Applying Serialization Recording Document Changes Serializing the Document Serializing the Element Classes The Serialize() Functions for the Shape Classes

852 852 853 854 855

856 856 858 858

859 860 861 861 862 862

863

864 865

867 867 868 868 869 870 870

872 872

873 874

874 874 876 877 879

Exercising Serialization Moving Text Printing a Document

881 882 884

The Printing Process

885

The CPrintInfo Class

886

xxix

Contents Chapter 16: Working with Dialogs and Controls Understanding Dialogs Understanding Controls Common Controls

Creating a Dialog Resource Adding Controls to a Dialog Box Testing the Dialog

Programming for a Dialog

817 817 818 820

820 820 822

822

Adding a Dialog Class Modal and Modeless Dialogs Displaying a Dialog

823 824 824

Code to Display the Dialog Code to Close the Dialog

826 827

Supporting the Dialog Controls

828

Initializing the Controls Handling Radio Button Messages

Completing Dialog Operations Adding Pen Widths to the Document Adding Pen Widths to the Elements Creating Elements in the View Exercising the Dialog

Using a Spin Button Control Adding the Scale Menu Item and Toolbar Button Creating the Spin Button The Controls’ Tab Sequence

Generating the Scale Dialog Class Dialog Data Exchange and Validation Initializing the Dialog

Displaying the Spin Button

Using the Scale Factor Scaleable Mapping Modes Setting the Document Size Setting the Mapping Mode Implementing Scrolling with Scaling Setting Up the Scrollbars

Working with Status Bars

828 830

831 832 832 833 834

835 835 835 838

838 840 840

841

842 842 844 844 846 847

848

Adding a Status Bar to a Frame

848

Defining the Status Bar Parts Updating the Status Bar

850 851

xxviii

Contents Implementing Multipage Printing

888

Getting the Overall Document Size Storing Print Data Preparing to Print Cleaning Up After Printing Preparing the Device Context Printing the Document Getting a Printout of the Document

889 890 891 892 893 894 898

Summary Exercises

Chapter 18: Writing Your Own DLLs Understanding DLLs How DLLs Work Run-Time Dynamic Linking

Contents of a DLL The DLL Interface The DllMain() Function

DLL Varieties MFC Extension DLL Regular DLL — Statically Linked to MFC Regular DLL — Dynamically Linked to MFC

Deciding What to Put in a DLL Writing DLLs Writing and Using an Extension DLL Understanding DllMain() Adding Classes to the Extension DLL Exporting Classes from the Extension DLL Building a DLL Using the Extension DLL in Sketcher Files Required to Use a DLL

Exporting Variables and Functions from a DLL Importing Symbols into a Program Implementing the Export of Symbols from a DLL Using Exported Symbols

Summary Exercises

xxx

898 899

901 901 903 904

906 906 906

906 906 907 907

907 908 908 910 911 912 913 914 915

916 917 917 918

920 920

Contents Chapter 19: Connecting to Data Sources Database Basics A Little SQL Retrieving Data Using SQL Choosing Records

921 921 924 924 925

Joining Tables Using SQL Sorting Records

926 929

Database Support in MFC

929

MFC Classes Supporting ODBC

930

Creating a Database Application

931

Registering an ODBC Database Generating an MFC ODBC Program

931 933

Snapshot versus Dynaset Recordsets

935

Understanding the Program Structure

936

Understanding Recordsets Understanding the Record View Creating the View Dialog Linking the Controls to the Recordset

Exercising the Example

Sorting a Recordset Modifying the Window Caption

Using a Second Recordset Object Adding a Recordset Class Adding a View Class for the Recordset Creating the Dialog Resource Creating the Record View Class

Customizing the Recordset

937 941 943 946

948

948 949

950 950 954 954 955

957

Adding a Filter to the Recordset Defining the Filter Parameter Initializing the Record View

958 958 960

Accessing Multiple Table Views

961

Switching Views Enabling the Switching Operation Handling View Activation

Viewing Orders for a Product

Viewing Customer Details Adding the Customer Recordset Creating the Customer Dialog Resource Creating the Customer View Class Adding a Filter Implementing the Filter Parameter

961 963 965

966

967 967 968 968 970 972

xxxi

Contents Linking the Order Dialog to the Customer Dialog Exercising the Database Viewer

Summary Exercises

Chapter 20: Updating Data Sources Update Operations CRecordset Update Operations Checking that Operations are Legal Record Locking

Transactions CDatabase Transaction Operations

A Simple Update Example

973 976

976 977

979 979 980 981 982

982 983

984

Customizing the Application

986

Managing the Update Process

988

Implementing Update Mode

990

Enabling and Disabling Edit Controls Changing the Button Label Controlling the Visibility of the Cancel Button Disabling the Record Menu Expediting the Update Implementing the Cancel Operation

Adding Rows to a Table The Order Entry Process Creating the Resources Creating the Recordsets Creating the Recordset Views Adding Controls to the Dialog Resources Implementing Dialog Switching Creating an Order ID Storing the New Order ID Creating the New Order ID Initiating ID Creation

Storing the Order Data Setting Dates

Selecting Products for an Order Adding a New Order

Summary Exercises

xxxii

991 992 993 994 996 997

999 1000 1001 1002 1002 1006 1010 1014 1014 1015 1017

1019 1020

1021 1023

1028 1029

Contents Chapter 21: Applications Using Windows Forms Understanding Windows Forms Understanding Windows Forms Applications Modifying the Properties of a Form How the Application Starts

Customizing the Application GUI Adding Controls to a Form Adding Menus Adding Submenus

Adding a Tab Control Using GroupBox Controls Using Button Controls Using the WebBrowser Control Operation of the Winning Application Adding a Context Menu Creating Event Handlers Event Handlers for Menu Items Adding Members to the Form1 Class Handling the Play Menu Event

Handling Events for the Limits Menu Creating a Dialog Box Adding a List to a ListBox Handling the Dialog Button Events Controlling the State of the ListBox Objects Creating the Dialog Object

Using the Dialog Box Validating the Input Handler the Reset Menu Item Event

Adding the Second Dialog

1031 1031 1032 1034 1035

1035 1036 1037 1038

1040 1042 1044 1047 1048 1049 1049 1050 1050 1052

1056 1056 1058 1060 1061 1061

1062 1063 1067

1068

Getting the Data from the Dialog Controls Disabling Input Controls Updating the Limits Menu Item Handlers

1070 1073 1074

Implementing the Help | About Menu Item Handling a Button Click Responding to the Context Menu

1075 1076 1079

The Logic for Dealing with the Choose Menu Item Creating the Dialog Form Developing the Dialog Class Handling the Click Event for the ChooseMenu

Summary Exercises

1080 1080 1081 1083

1086 1087

xxxiii

Contents Chapter 22: Accessing Data Sources in a Windows Forms Application Working with Data Sources Accessing and Displaying Data Using a DataGridView Control Using a DataGridView Control in Unbound Mode Customizing a DataGridView Control Customizing Header Cells Customizing Non-Header Cells Setting Up the Data Setting Up the Control Setting Up the Column Headers Formatting a Column Customizing Alternate Rows

Dynamically Setting Cell Styles

Using Bound Mode The BindingSource Component Using the BindingNavigator Control Binding to Individual Controls Working with Multiple Tables Summary Exercises

1089 1089 1090 1091 1093 1099 1101 1101 1102 1103 1105 1106 1108

1108

1114 1115 1120 1123 1127 1129 1129

Appendix A: C++ Keywords

1131

Appendix B: ASCII Codes

1133

Index

xxxiv

1139

Introduction Welcome to Beginning Visual C++ 2005. With this book you can become an effective C++ programmer. The latest development system from Microsoft, Visual Studio 2005, supports two distinct but closely related flavors of the C++ language; it fully supports the original ISO/ANSI standard C++, and you also get support for a new version of C++ called C++/CLI that was developed by Microsoft but is now an ECMA standard. These two versions of C++ are complementary and fulfill different roles. ISO/ANSI C++ is there for the development of high-performance applications that run natively on your computer whereas C++/CLI has been developed specifically for the .NET Framework. This book will teach you the essentials of programming applications in both versions of C++. You get quite a lot of assistance from automatically generated code when writing ISO/ANSI C++ programs, but you still need to write a lot of C++ yourself. You need a solid understanding of object-oriented programming techniques, as well as a good appreciation of what’s involved in programming for Windows. Although C++/CLI targets the .NET Framework, it also is the vehicle for the development of Windows Forms applications that you can develop with little or in some cases no, explicit code writing. Of course, when you do have to add code to a Windows Forms application, even though it may be a very small proportion of the total, you still need an in-depth knowledge of the C++/CLI language. ISO/ANSI C++ remains the language of choice for many professionals, but the speed of development that C++/CLI and Windows Forms applications bring to the table make that essential, too. For this reason I decided to cover the essentials of both flavors of C++ in this book.

Who This Book Is For This book is aimed at teaching you how to write C++ applications for the Microsoft Windows operating system using Visual C++ 2005 or any edition of Visual Studio 2005. I make no assumptions about prior knowledge of any particular programming language. This tutorial is for you if: ❑

You have a little experience of programming in some other language, such as BASIC or Pascal, for example, and you are keen to learn C++ and develop practical Microsoft Windows programming skills.



You have some experience in C or C++, but not in a Microsoft Windows context and want to extend your skills to program for the Windows environment using the latest tools and technologies.



You are a newcomer to programming and sufficiently keen to jump in and the deep end with C++. To be successful you need to have at least a rough idea of how your computer works, including the way in which the memory is organized and how data and instructions are stored.

Introduction

What This Book Covers My objective with this book is to teach you the essentials of C++ programming using both of the technologies supported by Visual C++ 2005. The book provides a detailed tutorial on both flavors of the C++ language, on native ISO/ANSI C++ Windows application development using the Microsoft Foundation Classes (MFC) and on the development of C++/CLI Windows applications using Windows Forms. Because of the importance and pervasiveness of database technology today, the book also includes introductions to the techniques you can use for accessing data sources in both MFC and Windows Forms applications. MFC applications are relatively coding-intensive compared to Windows Forms applications. This is because you create the latter using a highly developed design capability in Visual C++ 2005 that enables you to assemble the entire graphical user interface (GUI) for an application graphically and have all the code generated automatically. For this reason, there are more pages in the book devoted to MFC programming than to Windows Forms programming.

How This Book Is Structured The contents of the book are structured as follows:

xxxvi



Chapter 1 introduces you to the basic concepts you need to understand for programming in C++ for native applications and for .NET Framework applications, together with the main ideas embodied in the Visual C++ 2005 development environment. It describes how you use the capabilities of Visual C++ 2005 for creating the various kinds of C++ applications you learn about in the rest of the book.



Chapters 2 to 10 are dedicated to teaching you both versions of the C++ language, plus the basic ideas and techniques involved in debugging. The content of each of the Chapters 2 to 10 is structured in a similar way; the first half of each chapter deals with ISO/ANSI C++ topics, and the second half deals with C++/CLI.



Chapter 11 discusses how Microsoft Windows applications are structured and describes and demonstrates the essential elements that are present in every Windows application. The chapter explains elementary examples of Windows applications using ISO/ANSI C++ and the Windows API and the MFC, as well as an example of a basic Windows Forms application in C++/CLI.



Chapters 12 to 17 describe in detail the capabilities provided by the MFC for building a GUI. You learn how you create and use common controls to build the graphical user interface for your application and how you handle the events that result from user interactions with your program. In the process, you create a substantial working application. In addition to the techniques you learn for building a GUI, the application that you develop also shows you how you use MFC to print documents and to save them on disk.



Chapter 18 teaches you the essentials you need to know for creating your own libraries using MFC. You learn about the different kinds of libraries you can create, and you develop working examples of these that work with the application that you have evolved over the preceding six chapters.



In Chapters 19 and 20, you learn about accessing data sources in an MFC application. You gain experience in accessing a database in read-only mode; then you learn the fundamental programming techniques for updating a database using MFC. The examples use the Northwind database that can be downloaded from the Web, but you can also apply the techniques described to your own data source.

Introduction ❑

In Chapter 21 you work with Windows Forms and C++/CLI to build an example that teaches you how to create, customize, and use Windows Forms controls in an application. You gain practical experience by building an application incrementally throughout the chapter.



Chapter 22 builds on the knowledge you gain in Chapter 21 and shows how the controls available for accessing data sources work, and how you customize them. You also learn how you can create an application for accessing a database with virtually no coding at all on your part.

All chapters include numerous working examples that demonstrate the programming techniques that are discussed. Every chapter concludes with a summary of the key points that were covered, and most chapters include a set of exercises at the end that you can attempt to apply what you have learned. Solutions to the exercises together with all the code from the book are available for download from the publisher’s Web site (see the “Source Code” section later in this Introduction for more details). The tutorial on the C++ language uses examples that are console programs with simple command-line input and output. This approach enables you to learn the various capabilities of C++ without getting bogged down in the complexities of Windows GUI programming. Programming for Windows is really only practicable after you have a thorough understanding of the programming language. If you want to keep things as simple as possible, you can just learn ISO/ANSI C++ programming in the first instance. Each of the chapters that cover the C++ language (Chapters 2 to 10) first discusses particular aspects of the capabilities of ISO/ANSI C++ followed by the new features introduced by C++/CLI in the same context. The reason for organizing things this way is that C++/CLI is defined as an extension to the ISO/ANSI standard language, so an understanding of C++/CLI is predicated on knowledge of ISO/ANSI C++. Thus, you can just read the ISO/ANSI topics in each of Chapters 2 to 20 and ignore the C++/CLI sections that follow. You then can to progress to Windows application development with ISO/ANSI C++ without having to keep the two versions of the language in mind. You can return to C++/CLI when you are comfortable with ISO/ANSI C++. Of course, you can also work straight through and add to your knowledge of both versions of the C++ language incrementally.

What You Need to Use This Book To use this book you need any of Visual Studio 2005 Standard Edition, Visual Studio 2005 Professional Edition, or Visual Studio 2005 Team System. Note that Visual C++ Express 2005 is not sufficient because the MFC is not included. Visual Studio 2005 requires Windows XP Service Pack 2 or Windows 2000 Service Pack 4.To install any of the three Visual Studio 2005 editions identified you need to have a 1 GHz processor with at least 256MB of memory and at least 1GB of space available on your system drive and 2GB available on the installation drive. To install the full MSDN documentation that comes with the product you’ll need an additional 1.8GB available on the installation drive. The database examples in the book use the Northwind Traders database. You can find the download for this database by searching for “Northwind Traders” on http://msdn.microsoft.com. Of course, you can also adapt the examples to work with a database of your choice. Most importantly, to get the most out of this book you need a willingness to learn, and a determination to master the most powerful programming tool for Windows applications presently available. You need the dedication to type in and work through all the examples and try out the exercises in the book. This sounds more difficult than it is, and I think you’ll be surprised how much you can achieve in a relatively

xxxvii

Introduction short period of time. Keep in mind that everybody who learns programming gets bogged down from time to time, but if you keep at it, things become clearer and you’ll get there eventually. This book helps you to start experimenting on your own and, from there, to become a successful C++ programmer.

Conventions To help you get the most from the text and keep track of what’s happening, a number of conventions are used throughout the book.

Try It Out The Try It Out is an exercise you should work through, following the text in the book.

How It Works After many Try It Outs, a How It Works section explains the code you’ve typed in detail.

Boxes like this one hold important, not-to-be forgotten information that is directly relevant to the surrounding text.

Tips, hints, tricks, and asides to the current discussion are offset and placed in italics like this. As for styles in the text: ❑

New terms and important words appear bold when first introduced.



Keyboard strokes are shown like this: Ctrl+A.



Filenames, URLs, and code within the text appear like so: persistence.properties.



Code is presented in two different ways:

In code examples I highlight new and important code with a gray background. The gray highlighting is used for code that’s less important in the present context, or has been shown before.

Source Code As you work through the examples in this book, you may choose either to type in all the code manually or to use the source code files that accompany the book. All of the source code used in this book is available for download at http://www.wrox.com. At the site, simply locate the book’s title (either by using the Search box or by using one of the title lists) and click the Download Code link on the book’s detail page to obtain all the source code for the book.

xxxviii

Introduction Because many books have similar titles, you may find it easiest to search by ISBN; this book’s ISBN is 0-7645-7197-4 (changing to 978-0-7645-7197-8 as the new industry-wide 13-digit ISBN numbering system is phased in by January 2007). After you download the code, just decompress it with your favorite compression tool. Alternatively, you can go to the main Wrox code download page at http://www.wrox.com/dynamic/books/ download.aspx to see the code available for this book and all other Wrox books.

Errata We make every effort to ensure that there are no errors in the text or in the code. However, no one is perfect, and mistakes do occur. If you find an error in one of our books, like a spelling mistake or faulty piece of code, we would be very grateful for your feedback. By sending in errata you may save another reader hours of frustration and at the same time you will be helping us provide even higher quality information. To find the errata page for this book, go to http://www.wrox.com and locate the title using the Search box or one of the title lists. Then, on the book details page, click the Book Errata link. On this page you can view all errata that has been submitted for this book and posted by Wrox editors. A complete book list including links to each book’s errata is also available at www.wrox.com/misc-pages/booklist .shtml. If you don’t spot “your” error on the Book Errata page, go to www.wrox.com/contact/techsupport .shtml and complete the form there to send us the error you have found. We’ll check the information and, if appropriate, post a message to the book’s errata page and fix the problem in subsequent editions of the book.

p2p.wrox.com For author and peer discussion, join the P2P forums at p2p.wrox.com. The forums are a Web-based system for you to post messages relating to Wrox books and related technologies and interact with other readers and technology users. The forums offer a subscription feature to e-mail you topics of interest of your choosing when new posts are made to the forums. Wrox authors, editors, other industry experts, and your fellow readers are present on these forums. At http://p2p.wrox.com you will find a number of different forums that will help you not only as you read this book, but also as you develop your own applications. To join the forums, just follow these steps:

1. 2. 3.

Go to p2p.wrox.com and click the Register link.

4.

You will receive an e-mail with information describing how to verify your account and complete the joining process.

Read the terms of use and click Agree. Complete the required information to join as well as any optional information you wish to provide and click Submit.

xxxix

1 Programming with Visual C++ 2005 Windows programming isn’t difficult. In fact, Microsoft Visual C++ 2005 makes it remarkably easy, as you’ll see throughout the course of this book. There’s just one obstacle in your path: Before you get to the specifics of Windows programming, you have to be thoroughly familiar with the capabilities of the C++ programming language, particularly the object-oriented aspects of the language. Object-oriented techniques are central to the effectiveness of all the tools that are provided by Visual C++ 2005 for Windows programming, so it’s essential that you gain a good understanding of them. That’s exactly what this book provides. This chapter gives you an overview of the essential concepts involved in programming applications in C++. You’ll take a rapid tour of the Integrated Development Environment (IDE) that comes with Visual C++ 2005. The IDE is straightforward and generally intuitive in its operation, so you’ll be able to pick up most of it as you go along. The best approach to getting familiar with it is to work through the process of creating, compiling, and executing a simple program. By the end of this chapter, you will have learned: ❑

What the principal components of Visual C++ 2005 are



What the .NET Framework consists of and the advantages it offers



What solutions and projects are and how you create them



About console programs



How to create and edit a program



How to compile, link, and execute C++ console programs



How to create and execute basic Windows programs

So power up your PC, start Windows, load the mighty Visual C++ 2005, and begin your journey.

Introduction You can read messages in the forums without joining P2P but in order to post your own messages, you must join. After you join, you can post new messages and respond to messages other users post. You can read messages at any time on the Web. If you would like to have new messages from a particular forum e-mailed to you, click the Subscribe to this Forum icon by the forum name in the forum listing. For more information about how to use the Wrox P2P, be sure to read the P2P FAQs for answers to questions about how the forum software works as well as many common questions specific to P2P and Wrox books. To read the FAQs, click the FAQ link on any P2P page.

xl

Chapter 1

The .NET Framework The .NET Framework is a central concept in Visual C++ 2005 as well as in all the other .NET development products from Microsoft. The .NET Framework consists of two elements: the Common Language Runtime (CLR) in which your application executes, and a set of libraries called the .NET Framework class libraries. The .NET Framework class libraries provide the functional support your code will need when executing with the CLR, regardless of the programming language used, so .NET programs written in C++, C#, or any of the other languages that support the .NET Framework all use the same .NET libraries. There are two fundamentally different kinds of C++ applications you can develop with Visual C++ 2005. You can write applications that natively execute on your computer. These applications will be referred to as native C++ programs. You write native C++ programs in the version of C++ that is defined by the ISO/ANSI language standard. You can also write applications to run under the control of the CLR in an extended version of C++ called C++/CLI. These programs will be referred to as CLR programs, or C++/CLI programs. The .NET Framework is not strictly part of Visual C++ 2005 but rather a component of the Windows operating system that makes it easier to build software applications and Web services. The .NET Framework offers substantial advantages in code reliability and security, as well as the ability to integrate your C++ code with code written in over 20 other programming languages that target the .NET Framework. A slight disadvantage of targeting the .NET Framework is that there is a small performance penalty, but you won’t notice this in the majority of circumstances.

The Common Language Runtime (CLR) The CLR is a standardized environment for the execution of programs written in a wide range of highlevel languages including Visual Basic, C#, and of course C++. The specification of the CLR is now embodied in the European Computer Manufacturers (ECMA) standard for the Common Language Infrastructure (CLI), ECMA-335, and also in the equivalent ISO standard, ISO/IEC 23271, so the CLR is an implementation of this standard. You can see why C++ for the CLR is referred to as C++/CLI — it’s C++ for the Common Language Infrastructure, so you are likely to see C++/CLI compilers on other operating systems that implement the CLI. Note that information on all ECMA standards is available from http://www.ecma-international. org and ECMA-335 is currently available as a free download.

The CLI is essentially a specification for a virtual machine environment that enables applications written in diverse high-level programming languages to be executed in different system environments without changing or recompiling the original source code. The CLI specifies a standard intermediate language for the virtual machine to which the high-level language source code is compiled. With the .NET Framework, this intermediate language is referred to as Microsoft Intermediate Language (MSIL). Code in the intermediate language is ultimately mapped to machine code by a just-in-time (JIT) compiler when you execute a program. Of course, code in the CLI intermediate language can be executed within any other environment that has a CLI implementation.

2

Programming with Visual C++ 2005 The CLI also defines a common set of data types called the Common Type System (CTS) that should be used for programs written in any programming language targeting a CLI implementation. The CTS specifies how data types are used within the CLR and includes a set of predefined types. You may also define your own data types, and these must be defined in a particular way to be consistent with the CLR, as you’ll see. Having a standardized type system for representing data allows components written in different programming languages to handle data in a uniform way and makes it possible to integrate components written in different languages to be integrated into a single application. Data security and program reliability is greatly enhanced by the CLR, in part because dynamic memory allocation and release for data is fully automatic but also because the MSIL code for a program is comprehensively checked and validated before the program executes. The CLR is just one implementation of the CLI specification that executes under Microsoft Windows on a PC; there will undoubtedly be other implementations of the CLI for other operating system environments and hardware platforms. You’ll sometimes find that the terms CLI and CLR used interchangeably, although it should be evident that they are not the same things. The CLI is a standard specification; the CLR is Microsoft’s implementation of the CLI.

Writing C++ Applications You have tremendous flexibility in the types of applications and program components that you can develop with Visual C++ 2005. As noted earlier in this chapter, you have two basic options for Windows applications: you can write code that executes with the CLR, and you can also write code that compiles directly to machine code and thus executes natively. For window-based applications targeting the CLR, you use Windows Forms as the base for the GUI provided by the .NET Framework libraries. Using Windows Forms enables rapid GUI development because you assemble the GUI graphically from standard components and have the code generated completely automatically. You then just need to customize the code that has been generated to provide the functionality you require. For natively executing code, you have several ways to go. One possibility is to use the Microsoft Foundation Classes (MFC) for programming the graphical user interface for your Windows application. The MFC encapsulates the Windows operating system Application Programming Interface (API) for GUI creation and control and greatly eases the process of program development. The Windows API originated long before the C++ language arrived on the scene so it has none of the object-oriented characteristics that would be expected if it were written today; however, you are not obliged to use the MFC. If you want the ultimate in performance, you can write your C++ code to access the Windows API directly. C++ code that executes with the CLR is described as managed C++ because data and code is managed by the CLR. In CLR programs, the release of memory that you have allocated dynamically for storing data is taken care of automatically, thus eliminating a common source of error in native C++ applications. C++ code that executes outside of the CLR is sometimes described by Microsoft as unmanaged C++ because the CLR is not involved in its execution. With unmanaged C++ you must take care of all aspects allocating and releasing memory during execution of your program yourself, and you also forego the enhanced security provided by the CLR. You’ll also see unmanaged C++ referred to as native C++ because it compiles directly to native machine code. Figure 1-1 shows the basic options you have for developing C++ applications.

3

Chapter 1

Managed C++

Native C++

Native C++

Framework Classes

MFC

Common Language Runtime

Operating System

Hardware

Figure 1-1

Figure 1-1 is not the whole story. An application can consist partly of managed C++ and partly of native C++, so you are not obliged to stick to one environment or the other. Of course, you do lose out somewhat by mixing the code, so you would choose to follow this approach only when necessary, such as when you want to convert an existing native C++ application to run with the CLR. You obviously won’t get the benefits inherent in managed C++ in the native C++ code, and there can also be appreciable overhead involved in communications between the managed and unmanaged code components. The ability to mix managed and unmanaged code can be invaluable, however, when you need to develop or extend existing unmanaged code but also want to obtain the advantages of using the CLR. Of course, for new applications you should decide whether you want to create it as a managed C++ application at the outset.

Learning Windows Programming There are always two basic aspects to interactive applications executing under Windows: you need code to create the Graphical User Interface (the GUI) with which the user interacts, and you need code to process these interactions to provide the functionality of the application. Visual C++ 2005 provides you with a great deal of assistance in both aspects of Windows application development. As you’ll see later in this chapter, you can create a working Windows program with a GUI without writing any code yourself at all. All the basic code to create the GUI can be generated automatically by Visual C++ 2005; however, it’s essential to understand how this automatically generated code works because you need to extend and modify it to make it do what you want, and to do that you need a comprehensive understanding of C++.

4

Programming with Visual C++ 2005 For this reason, you’ll first learn C++ — both the native C++ and C++/CLI versions of the language — without getting involved in Windows programming considerations. After you’re comfortable with C++, you’ll learn how you develop fully-fledged Windows applications using native C++ and C++/CLI. This means that while you are learning C++, you’ll be working with programs that just involved command line input and output. By sticking to this rather limited input and output capability, you’ll be able to concentrate of the specifics of how the C++ language works and avoid the inevitable complications involved in GUI building and control. After you become comfortable with C++, you’ll find that it’s an easy and natural progression to applying C++ to the development of Windows application programs.

Learning C++ Visual C++ 2005 fully supports two versions of C++ defined by two separate standards: ❑

The ISO/ANSI C++ standard is for implementing native applications — unmanaged C++. This version of C++ is supported on the majority of computer platforms.



The C++/CLI standard is designed specifically for writing programs that target the CLR and is an extension to the ISO/ANSI C++.

Chapters 2 through 10 of this book teach you the C++ language. Because C++/CLI is an extension of ISO/ANSI C++, the first part of each chapter introduces elements of the ISO/ANSI C++ language; the second part explains the additional features that C++/CLI introduces. Writing programs in C++/CLI allows you to take full advantage of the capabilities of the .NET Framework, something that is not possible with programs written in ISO/ANSI C++. Although C++/CLI is an extension of ANSI/ISO C++, to be able to execute your program fully with the CLR means that it must conform to the requirements of the CLR. This implies that there are some features of ANSI/ISO C++ that you cannot use in your CLR programs. One example of this that you might deduce from what I have said up to now is that the dynamic memory allocation and release facilities offered by ISO/ANSI C++ are not compatible with the CLR; you must use the CLR mechanism for memory management and this implies that you must use C++/CLI classes, not native C++ classes.

The C++ Standards The ISO/ANSI standard is defined by the document ISO/IEC 14882 that is published by the American National Standards Institute (ANSI). ISO/ANSI standard C++ is the well-established version of C++ that has been around since 1998 and is supported by compilers on the majority of computer hardware platforms and operating systems. Programs that you write in ISO/ANSI C++ can be ported from one system environment to another reasonably easily, although the library functions that a program uses — particularly those related to building a graphical user interface — are a major determinant of how easy or difficult it will be. ISO/ANSI standard C++ has been the first choice of many professional program developers because it is so widely supported, and because is one of the most powerful programming languages available today. The ISO/ANSI standard for C++ can be purchased from http://www.iso.org. C++/CLI is a version of C++ that extends the ISO/ANSI standard for C++ to better support the Common Language Infrastructure (CLI) that is defined by the standard ECMA-355. The first draft of this standard appeared in 2003 and was developed from an initial technical specification that was produced by Microsoft to support the execution of C++ programs with the .NET Framework. Thus both the CLI and C++/CLI were originated by Microsoft in support of the .NET Framework. Of course, standardizing

5

Chapter 1 the CLI and C++/CLI greatly increases the likelihood of implementations in environments other than Windows. It’s important to appreciate that although C++/CLI is an extension of ISO/ANSI C++, there are features of ISO/ANSI C++ that you must not use when you want your program to execute fully under the control of the CLR. You’ll learn what these are as you progress through the book. The CLR offers substantial advantages over the native environment. By targeting your C++ programs at the CLR, your programs will be more secure and not prone to the potential errors you can make when using the full power of ISO/ANSI C++. The CLR also removes the incompatibilities introduced by various high-level languages by standardizing the target environment to which they are compiled and thus permit modules written in C++ to be combined with modules written in other languages such as C# or Visual Basic.

Console Applications As well as developing Windows applications, Visual C++ 2005 also allows you to write, compile, and test C++ programs that have none of the baggage required for Windows programs — that is, applications that are essentially character-based, command-line programs. These programs are called console applications in Visual C++ 2005 because you communicate with them through the keyboard and the screen in character mode. Writing console applications might seem as though you are being sidetracked from the main objective of Windows programming, but when it comes to learning C++ (which you do need to do before embarking on Windows-specific programming), it’s the best way to proceed. There’s a lot of code in even a simple Windows program, and it’s very important not to be distracted by the complexities of Windows when learning the ins and outs of C++. Therefore, in the early chapters of the book where you are concerned with how C++ works, you’ll spend time walking with a few lightweight console applications before you get to run with the heavyweight sacks of code in the world of Windows. While you’re learning C++, you’ll be able to concentrate on the language features without worrying about the environment in which you’re operating. With the console applications that you’ll write, you have only a text interface, but this will be quite sufficient for understanding all of C++ because there’s no graphical capability within the definition of the language. Naturally, I will provide extensive coverage of graphical user interface programming when you come to write programs specifically for Windows using Microsoft Foundation Classes (MFC) in native C++ applications and Windows Forms with the CLR. There are two distinct kinds of console applications and you’ll be using both. Win32 console applications compile to native code, and you’ll be using these to try out the capabilities of ISO/ANSI C++. CLR console applications target the CLR so you’ll be using these when you are working with the features of C++/CLI.

Windows Programming Concepts Our approach to Windows programming is to use all the tools that Visual C++ 2005 provides. The project creation facilities that are provided with Visual C++ 2005 can generate skeleton code for a wide variety of application programs automatically, including basic Windows programs. Creating a project is the starting point for all applications and components that you develop with Visual C++ 2005, and to get a

6

Programming with Visual C++ 2005 flavor of how this works, you’ll look at the mechanics of creating some examples, including an outline Windows program, later in this chapter. A Windows program has a different structure from that of the typical console program you execute from the command line, and it’s more complicated. In a console program, you can get input from the keyboard and write output back to the command line directly, whereas a Windows program can access the input and output facilities of the computer only by way of functions supplied by the Windows operating system; no direct access to the hardware resources is permitted. Because several programs can be active at one time under Windows, Windows has to determine which application a given raw input such as a mouse click or the pressing of a key on the keyboard is destined for and signal the program concerned accordingly. Thus the Windows operating system has primary control of all communications with the user. Also, the nature of the interface between a user and a Windows application is such that a wide range of different inputs is usually possible at any given time. A user may select any of a number of menu options, click a toolbar button, or click the mouse somewhere in the application window. A welldesigned Windows application has to be prepared to deal with any of the possible types of input at any time because there is no way of knowing in advance which type of input is going to occur. These user actions are received by the operating system in the first instance and are all regarded by Windows as events. An event that originates with the user interface for your application will typically result in a particular piece of your program code being executed. How program execution proceeds is therefore determined by the sequence of user actions. Programs that operate in this way are referred to as event-driven programs and are different from traditional procedural programs that have a single order of execution. Input to a procedural program is controlled by the program code and can occur only when the program permits it; therefore, a Windows program consists primarily of pieces of code that respond to events caused by the action of the user, or by Windows itself. This sort of program structure is illustrated in Figure 1-2. Each square block in Figure 1-2 represents a piece of code written specifically to deal with a particular event. The program may appear to be somewhat fragmented because of the number of disjointed blocks of code, but the primary factor welding the program into a whole is the Windows operating system itself. You can think of your program as customizing Windows to provide a particular set of capabilities. Of course, the modules servicing various external events, such as selecting a menu or clicking the mouse, all typically have access to a common set of application-specific data in a particular program. This application data contains information that relates to what the program is about — for example, blocks of text in an editor or player scoring records in a program aimed at tracking how your baseball team is doing — as well as information about some of the events that have occurred during execution of the program. This shared collection of data allows various parts of the program that look independent to communicate and operate in a coordinated and integrated fashion. I will go into this in much more detail later in the book. Even an elementary Windows program involves several lines of code, and with Windows programs that are generated by the application wizards that come with Visual C++ 2005, “several” turns out to be “many.” To simplify process of understanding how C++ works, you need a context that is as uncomplicated as possible. Fortunately, Visual C++ 2005 comes with an environment that is ready-made for the purpose.

7

Chapter 1

Events:

Keyboard Input

Press Left Mouse Button

Press Right Mouse Button

WINDOWS

Process Keyboard Input

Process Left Mouse Button

Process Right Mouse Button

Program Data Your Program

Figure 1-2

What Is the Integrated Development Environment? The Integrated Development Environment (IDE) that comes with Visual C++ 2005 is a completely selfcontained environment for creating, compiling, linking, and testing your C++ programs. It also happens to be a great environment in which to learn C++ (particularly when combined with a great book). Visual C++ 2005 incorporates a range of fully integrated tools designed to make the whole process of writing C++ programs easy. You will see something of these in this chapter, but rather than grind through a boring litany of features and options in the abstract, first take a look at the basics to get a view of how the IDE works and then pick up the rest in context as you go along.

8

Programming with Visual C++ 2005

Components of the System The fundamental parts of Visual C++ 2005, provided as part of the IDE, are the editor, the compiler, the linker, and the libraries. These are the basic tools that are essential to writing and executing a C++ program. Their functions are as follows.

The Editor The editor provides an interactive environment for you to create and edit C++ source code. As well as the usual facilities, such as cut and paste, which you are certainly already familiar with, the editor also provides color cues to differentiate between various language elements. The editor automatically recognizes fundamental words in the C++ language and assigns a color to them according to what they are. This not only helps to make your code more readable but also provides a clear indicator of when you make errors in keying such words.

The Compiler The compiler converts your source code into object code, and detects and reports errors in the compilation process. The compiler can detect a wide range of errors that are due to invalid or unrecognized program code, as well as structural errors, where, for example, part of a program can never be executed. The object code output from the compiler is stored in files called object files. There are two types of object code that the compiler produces. These object codes usually have names with the extension .obj.

The Linker The linker combines the various modules generated by the compiler from source code files, adds required code modules from program libraries supplied as part of C++, and welds everything into an executable whole. The linker can also detect and report errors — for example, if part of your program is missing or a non-existent library component is referenced.

The Libraries A library is simply a collection of pre-written routines that supports and extends the C++ language by providing standard professionally produced code units that you can incorporate into your programs to carry out common operations. The operations that are implemented by routines in the various libraries provided by Visual C++ 2005 greatly enhance productivity by saving you the effort of writing and testing the code for such operations yourself. I have already mentioned the .NET Framework library, and there are a number of others — too many to enumerate here — but I’ll mention the most important ones. The Standard C++ Library defines a basic set of routines common to all ISO/ANSI C++ compilers. It contains a wide range of routines including numerical functions such as calculating square roots and evaluating trigonometrical functions, character and string processing routines such as classifying characters and comparing character strings, and many others. You’ll get to know quite a number of these as you develop your knowledge of ISO/ANSI C++. There are also libraries that support the C++/CLI extensions to ISO/ANSI C++. Native window-based applications are supported by a library called the Microsoft Foundation Classes (MFC). The MFC greatly reduces the effort needed to build the graphical user interface for an application. You’ll see a lot more of the MFC when you finish exploring the nuances of the C++ language. Another library contains a set of facilities called Windows Forms that are roughly the equivalent of the MFC for window-based applications that executed with the .NET Framework. You’ll be seeing how you make use of Windows Forms to develop applications, too.

9

Chapter 1

Using the IDE All program development and execution in this book is performed from within the IDE. When you start Visual C++ 2005, notice an application window similar to that shown in Figure 1-3.

Figure 1-3

The window to the left in Figure 1-3 is the Solution Explorer window, the top-right window presently showing the Start page is the Editor window, and the window at the bottom is the Output window. The Solution Explorer window enables you to navigate through your program files and display their contents in the Editor window and to add new files to your program. The Solution Explorer window has up to three additional tabs (only two are shown in Figure 1-3) that display Class View, Resource View, and Property Manager for your application, and you can select which tabs are to be displayed from the View menu. The Editor window is where you enter and modify source code and other components of your application. The Output window displays messages that result from compiling and linking your program.

Toolbar Options You can choose which toolbars are displayed in your Visual C++ window by right-clicking in the toolbar area. A pop-up menu with a list of toolbars (Figure 1-4) appears, and the toolbars that are currently displayed have check marks alongside.

10

Programming with Visual C++ 2005

Figure 1-4

This is where you decide which toolbars are visible at any one time. You can make your set of toolbars the same as those shown in Figure 1-3 by making sure the Build, Class Designer, Debug, Standard, and View Designer menu items are checked. Clicking in the gray area to the left of a toolbar checks it if it unchecked and results in it being displayed; clicking a check mark hides the corresponding toolbar. You don’t need to clutter up the application window with all the toolbars you think you might need at some time. Some toolbars appear automatically when required, so you’ll probably find that the default toolbar selections are perfectly adequate most of the time. As you develop your applications, from time to time you might think it would be more convenient to have access to toolbars that aren’t displayed. You can change the set of toolbars that are visible whenever it suits you by right-clicking in the toolbar area and choosing from the context menu.

11

Chapter 1 Similar to many other Windows applications, the toolbars that make up Visual C++ 2005 come complete with tooltips. Just let the mouse pointer linger over a toolbar button for a second or two and a white label displays the function of that button.

Dockable Toolbars A dockable toolbar is one that you can drag around with the mouse to position at a convenient place in the window. When it is placed in any of the four borders of the application, it is said to be docked and looks similar to the toolbars you see at the top of the application window. The toolbar on the upper line of toolbar buttons that contains the disk icons and the text box to the right of a pair of binoculars is the Standard toolbar. You can drag this away from the toolbar by placing the cursor on it and dragging it with the mouse while you hold down the left mouse button. It then appears as a separate window you can position anywhere. If you drag any dockable toolbar away from its docked position, it looks like the Standard toolbar you see in Figure 1-5, enclosed in a little window — with a different caption. In this state, it is called a floating toolbar. All the toolbars that you see in Figure 1-3 are dockable and can be floating, so you can experiment with dragging any of them around. You can position them in docked positions where they revert to their normal toolbar appearance. You can dock a dockable toolbar at any side of the main window.

Figure 1-5

You’ll become familiar with many of the toolbar icons that Visual C++ 2005 uses from other Windows applications, but you may not appreciate exactly what these icons do in the context of Visual C++, so I’ll describe them as we use them. Because you’ll use a new project for every program you develop, looking at what exactly a project is and understanding how the mechanism for defining a project works is a good place to start finding out about Visual C++ 2005.

Documentation There will be plenty of occasions when you’ll want to find out more information about Visual C++ 2005. The Microsoft Development Network (MSDN) Library provides comprehensive reference material on all the capabilities on Visual C++ 2005 and more besides. When you install Visual C++ 2005 onto your machine, there is an option to install part or all of the MSDN documentation. If you have the disk space available I strongly recommend that you install the MSDN Library.

12

Programming with Visual C++ 2005 Press the F1 function to browse the MSDN Library. The Help menu also provides various routes into the documentation. As well as offering reference documentation, the MSDN Library is a useful tool when dealing with errors in your code, as you’ll see later in this chapter.

Projects and Solutions A project is a container for all the things that make up a program of some kind — it might be a console program, a window-based program, or some other kind of program, and it usually consists of one or more source files containing your code plus possibly other files containing auxiliary data. All the files for a project are stored in the project folder and detailed information about the project is stored in an XML file with the extension .vcproj that is also in the project folder. The project folder also contains other folders that are used to store the output from compiling and linking your project. The idea of a solution is expressed by its name, in that it is a mechanism for bringing together all the programs and other resources that represent a solution to a particular data processing problem. For example, a distributed order entry system for a business operation might be composed of several different programs that could each be developed as a project within a single solution; therefore, a solution is a folder in which all the information relating to one or more projects is stored, so one or more project folders are subfolders of the solution folder. Information about the projects in a solution is stored in two files with the extensions .sln and .suo. When you create a project, a new solution is created automatically unless you elect to add the project to an existing solution. When you create a project along with a solution, you can add further projects to the same solution. You can add any kind of project to an existing solution, but you would usually add only a project that was related in some way to the existing project or projects in the solution. Generally, unless you have a good reason to do otherwise, each of your projects should have its own solution. Each example you create with this book will be a single project within its own solution.

Defining a Project The first step in writing a Visual C++ 2005 program is to create a project for it using the File > New > Project menu option from the main menu or you can press Ctrl+Shift+N. As well as containing files that define all the code and any other data that goes to make up your program, the project XML file in the project folder also records the Visual C++ 2005 options you’re using. Although you don’t need to concern yourself with the project file — it is entirely maintained by the IDE — you can browse it if you want to see what the contents are, but take care not to modify it accidentally. That’s enough introductory stuff for the moment. It’s time to get your hands dirty.

Try It Out

Creating a Project for a Win32 Console Application

You’ll now take a look at creating a project for a console application. First select File > New > Project to bring up the New Project dialog box, shown in Figure 1-6.

13

Chapter 1

Figure 1-6

The left pane in the New Project dialog box displays the types of projects you can create; in this case, click Win32. This also identifies an application wizard that creates the initial contents for the project. The right pane displays a list of templates available for the project type you have selected in the left pane. The template you select is used by the application wizard when creating the files that make up the project. In the next dialog box, you have an opportunity to customize the files that are created when you click the OK button in this dialog box. For most of the type/template options, a basic set of program source modules are created automatically. You can now enter a suitable name for your project by typing into the Name: edit box — for example, you could call this one Ex1_01, or you can choose your own project name. Visual C++ 2005 supports long file names, so you have a lot of flexibility. The name of the solution folder appears in the bottom edit box and, by default, the solution folder has the came name as the project. You can change this if you want. The dialog box also allows you to modify the location for the solution that contains your project — this appears in the Location: edit box. If you simply enter a name for your project, the solution folder is automatically set to a folder with that name, with the path shown in the Location: edit box. By default the solution folder is created for you if it doesn’t already exist. If you want to specify a different path for the solution folder, just enter it in the Location: edit box. Alternatively, you can use the Browse button to select another path for your solution. Clicking the OK button displays the Win32 Application Wizard dialog box shown in Figure 1-7. This dialog box explains the settings currently in effect. If you click the Finish button, the wizard creates all the project files based on this. In this case you can click Applications Settings on the left to display the Application Settings page of the wizard shown in Figure 1-8.

14

Programming with Visual C++ 2005

Figure 1-7

Figure 1-8

The Application Settings page allows you to choose options that you want to apply to the project. For most of the projects you’ll be creating when you are learning the C++ language, you select the Empty project checkbox, but here you can leave things as they are and click the Finish button. The application wizard then creates the project with all the default files.

15

Chapter 1 The project folder will have the name that you supplied as the project name and will hold all the files making up the project definition. If you didn’t change it, the solution folder has the same name as the project folder and contains the project folder plus the files defining the contents of the solution. If you use Windows Explorer to inspect the contents of the solution folder, you’ll see that it contains three files: ❑

A file with the extension .sln that records information about the projects in the solution.



A file with the extension .suo in which user options that apply to the solution will be recorded.



A file with the extension .ncb that records data about Intellisense for the solution. Intellisense is the facility that provides auto-completion and prompting for code in the Editor window as you enter it.

If you use Windows Explorer to look in the project folder, notice there are six files initially, including a file with the name ReadMe.txt that contains a summary of the contents of the files that have been created for the project. The one file that ReadMe.txt may not mention is a file with a compound name of the form Ex1_01.vcproj.ComputerName.UserName.user used to store options you set for the project. The project you have created will automatically open in Visual C++ 2005 with the left pane as in Figure 1-9. I have increased the width of this pane so that you can see the complete names on the tabs.

Figure 1-9

The Solution Explorer tab presents a view of all the projects in the current solution and the files they contains — here there is just one project of course. You can display the contents of any file as an additional tab in the Editor pane just by double-clicking in name in the Solution Explorer tab. In the edit pane you can switch instantly between any of the files that have been displayed just by clicking on the appropriate tab.

16

Programming with Visual C++ 2005 The Class View tab displays the classes defined in your project and also shows the contents of each class. You don’t have any classes in this application, so the view is empty. When we discuss classes, you will see that you can use the Class View tab to move around the code relating to the definition and implementation of all your application classes quickly and easily. The Property Manager tab shows the properties that have been set for the Debug and Release versions of your project. I’ll explain these versions a little later in this chapter. You can change any of the properties shown by right-clicking a property and selecting Properties from the context menu; this displays a dialog box where you can set the project property. You can also press Alt+F7 to display the properties dialog box at any time; I’ll also discuss this in more detail when we go into the Debug and Release versions of a program. The Resource View shows the dialog boxes, icons, menus toolbars, and other resources that are used by the program. Because this is a console program, no resources are used; however, when you start writing Windows applications, you’ll see a lot of things here. Through this tab you can edit or add to the resources available to the project. Like most elements of the Visual C++ 2005 IDE, the Solution Explorer and other tabs provide contextsensitive pop-up menus when you right-click items displayed in the tab and in some cases in the empty space in the tab, too. If you find that the Solution Explorer pane gets in your way when writing code, you can hide it by clicking the Autohide icon. To redisplay it, click the name tab on the left of the IDE window.

Modifying the Source Code The Application wizard generates a complete Win32 console program that you can compile and execute. Unfortunately, the program doesn’t do anything as it stands, so to make it a little more interesting you need to change it. If it is not already visible in the Editor pane, double-click Ex1_01.cpp in the Solution Explorer pane. This file is the main source file for the program that the Application wizard generated and it looks like that shown in Figure 1-10.

Figure 1-10

17

Chapter 1 If the line numbers are not displayed on your system, select Tools > Options from the main menu to display the Options dialog box. If you extend the C/C++ option in the right pane and select General from the extended tree, you can select Line Numbers in the right pane of the dialog box. I’ll first give you a rough guide to what this code in Figure 1-10 does, and you’ll see more on all of these later. The first two lines are just comments. Anything following “//”in a line is ignored by the compiler. When you want to add descriptive comments in a line, precede your text by “//”. Line 4 is an #include directive that adds the contents of the file stdafx.h to this file in place of this #include directive. This is the standard way of adding the contents of .h source files to a .cpp source file a in a C++ program. Line 7 is the first line of the executable code in this file and the beginning of the function _tmain(). A function is simply a named unit of executable code in a C++ program; every C++ program consists of at least one — and usually many more — functions. Lines 8 and 10 contain left and right braces, respectively, that enclose all the executable code in the function _tmain(). The executable code is, therefore, just the single line 10 and all this does is end the program. Now you can add the following two lines of code in the Editor window: // Ex1_01.cpp : Defines the entry point for the console application. // #include “stdafx.h” #include int _tmain(int argc, _TCHAR* argv[]) { std::cout Build Solution menu item. Alternatively, you can click the toolbar button corresponding to this menu item. The toolbar buttons for the Build menu may not display, but you can easily fix this by right-clicking in the toolbar area and selecting the Build

18

Programming with Visual C++ 2005 toolbar from those in the list. The program should then compile successfully. If there are errors, ensure you didn’t make an error while entering the new code, so check the two new lines very carefully.

Files Created by Building a Console Application After the example has been built without error, take a look in the project folder by using Windows Explorer to see a new subfolder called Debug. This folder contains the output of the build you just performed on the project. Notice that this folder contains several files. Other than the .exe file, which is your program in executable form, you don’t need to know much about what’s in these files. In case you’re curious, however, let’s do a quick run-through of what the more interesting ones are for. File Extension

Description

.exe

This is the executable file for the program. You get this file only if both the compile and link steps are successful.

.obj

The compiler produces these object files containing machine code from your program source files. These are used by the linker, along with files from the libraries, to produce your .exe file.

.ilk

This file is used by the linker when you rebuild your project. It enables the linker to incrementally link the object files produced from the modified source code into the existing .exe file. This avoids the need to re-link everything each time you change your program.

.pch

This is a pre-compiled header file. With pre-compiled headers, large tracts of code that are not subject to modification (particularly code supplied by C++ libraries) can be processed once and stored in the .pch file. Using the .pch file substantially reduces the time needed to rebuild your program.

.pdb

This file contains debugging information that is used when you execute the program in debug mode. In this mode, you can dynamically inspect information that is generated during program execution.

.idb

Contains information used when you rebuild the solution.

Debug and Release Versions of Your Program You can set a range of options for a project through the Project > Ex1_01 Properties menu item. These options determine how your source code is processed during the compile and link stages. The set of options that produces a particular executable version of your program is called a configuration. When you create a new project workspace, Visual C++ 2005 automatically creates configurations for producing two versions of your application. One version, called the Debug version, includes information that helps you debug the program. With the Debug version of your program you can step through the code when things go wrong, checking on the data values in the program. The other, called the Release version, has no debug information included and has the code optimization options for the compiler turned on to provide you with the most efficient executable module. These two configurations are sufficient for your needs throughout this book, but when you need to add other configurations for an application, you can do so through the Build > Configuration Manager menu. Note that this menu item won’t appear if you haven’t got a project loaded. This is obviously not a problem, but might be confusing if you’re just browsing through the menus to see what’s there.

19

Chapter 1 You can choose which configuration of your program to work with by selecting the configuration from the Active solution configuration drop-down list in the Configuration Manager dialog box, as shown in Figure 1-11.

Figure 1-11

Select the configuration you want to work with from the list and then click the Close button. While you’re developing an application, you’ll work with the debug configuration. After your application has been tested using the debug configuration and appears to be working correctly, you typically rebuild the program as a release version; this produces optimized code without the debug and trace capability, so the program runs faster and occupies less memory.

Executing the Program After you have successfully compiled the solution, you can execute your program by pressing Ctrl+F5. You should see the window shown in Figure 1-12.

Figure 1-12

20

Programming with Visual C++ 2005 As you see, you get the text that was between the double quotes written to the command line. The “\n” that appeared at the end of the text string is a special sequence called an escape sequence that denotes a newline character. Escape sequences are used to represent characters in a text string that you cannot enter directly from the keyboard.

Try It Out

Creating an Empty Console Project

The previous project contained a certain amount of excess baggage that you don’t need when working with simple C++ language examples. The precompiled headers option chosen by default resulted in the stdafx.h file being created in the project. This is a mechanism for making the compilation process more efficient when there are a lot of files in a program but this won’t be necessary for many of our examples. In these instances you start with an empty project to which you can add your own source files. You can see how this works by creating a new project in a new solution for a Win32 console program with the name Ex1_02. After you have entered the project name and clicked the OK button, click on Applications Settings on the right side of the dialog box that follows. You can then select Empty project from the additional options, as Figure 1-13 shows.

Figure 1-13

When you click the Finish button, the project is created as before, but this time without any source files. Next you add a new source file to the project. Right-click the Solution Explorer pane and then select Add > New Item from the context menu. A dialog box displays; click Code in the right pane, and C++ File(.cpp) in the left pane. Enter the file name as Ex1_02, as shown in Figure 1-14.

21

Chapter 1

Figure 1-14

When you click the Add button, the new file is added to the project and is displayed in the Editor window. Of course, the file is empty so nothing will be displayed; enter the following code in the Editor window: // Ex1_02.cpp A simple console program #include // Basic input and output library int main() { std::cout ColumnHeadersDefaultCellStyle = headerStyle;

This sets the value of the ColumnHeadersDefaultCellStyle property for the control to be the headerStyle handle. This replaces the existing DataGridViewCellStyle object that was in effect for the headers. There is one other thing you should do in relation to the column headers. The larger font requires the height of the cells to be adjusted to accommodate it. Calling the AutoResizeColumnHeadersHeight() function for the control adjusts the heights of the header cells to accommodate their current contents: dataGridView->AutoResizeColumnHeadersHeight();

1105

Chapter 22 The heights of all header cells is adjusted to fit the largest cell contents. If you just want the height of a particular column header to be adjusted, you can use the overloaded version of the function that accepts an argument specifying the index of the column to be adjusted. If you don’t want the row or column headers to be visible you can make them disappear by setting the value of the RowHeadersVisible property and/or ColumnHeadersVisible property for the control to false.

Formatting a Column The first column contains handles to a DateTime object. As it is, the application simply calls the ToString() function for the objects to get something to display, but you can do better than that. You can set the Format property for the DefaultCellStyle property for the column, and this format specification is then used to display the contents of the cells: dataGridView->Columns[0]->DefaultCellStyle->Format = L”y”;

This sets the Format property to the string containing the y format specification for a DateTime object that presents the object in the short date form as month plus year. There are several other format specifiers for DateTime objects that you could use. For example, D displays the day as well as the month and year, and f and F displays the time as well as the date. If you have added all that code to the Form1 class constructor, it’s time to don the sunglasses and give the example a whirl. If you compile and run it, you should see something like the application window shown in Figure 22-7.

Figure 22-7

I have resized the width of the window in Figure 22-7 to show more of the columns. Unfortunately, in the book the application window appears in shades of grey but you should see it on your screen in glorious Technicolor. If you click one of the row headers on the left of the control, you should see the row highlighted as shown in Figure 22-8.

1106

Accessing Data Sources in a Windows Forms Application

Figure 22-8

The background color in the cells in the row is the one you set for the SelectionBackColor property of the DefaultCellStyle property for the control. You can also select an individual cell by clicking it, and the background color of the cell changes to green. The ability to sort the rows based on any given column is built into the DataGridView control. You could try clicking a column header and see the rows sorted by the column you select. If you click the column header a second time, the rows are ordered in the opposite sense. You could add a tooltip to each of the columns to explain the sort possibility. Adding this loop to the Form1 class constructor does this: for each(DataGridViewColumn^ column in dataGridView->Columns) column->ToolTipText = L”Click to\nsort rows”;

The Columns property value is a collection of columns where each column is an object of type DataGridViewColumn. The loop iterates over each of the columns and sets the value of the ToolTipText property. Figure 22-9 shows the tooltip for one of the column headers.

Figure 22-9

1107

Chapter 22 These tooltips display only when the mouse cursor is over a column header cell. You can set a tooltip for any of the cells that display the data by setting the ToolTipText property for the cell object.

Customizing Alternate Rows When you are displaying many rows that are similar in appearance, it can be difficult to see which row you are looking at. You can color alternate rows differently to help overcome the problem by setting a different color as the BackColor property for the AlternatingRowsDefaultCellStyle property for the control object: dataGridView->AlternatingRowsDefaultCellStyle->BackColor = Color::Blue;

You will probably want to change the ForeColor property for the AlternatingRowsDefaultCellStyle property to get a reasonable contrast between the text and the background: dataGridView->AlternatingRowsDefaultCellStyle->ForeColor = Color::White;

Now rows are displayed with colors alternating between pink and blue, as shown in Figure 22-10 (in shades of grey, of course, as there is no color in the book).

Figure 22-10

Now it’s easy to separate the rows and the white text against a blue background is clear. You can still select a row by clicking a row header and see the selected row in green. Clicking in the cell at the left end of the column headers selects all the rows.

Dynamically Setting Cell Styles You have several possibilities for changing the appearance of cells by handling events for the DataGridView control. The CellFormatting event for a DataGridView control fires when the contents of a cell need to be formatted ready to be displayed, so by adding a handler for this event you can adjust the appearance of any cell depending on what the contents are. I want now to explore how you could extend Ex22_02 to do this.

1108

Accessing Data Sources in a Windows Forms Application Suppose, for example, that in Ex22_02 you wanted to set the background color of cells in the Date column to red if the date is before the year 2000. Recall from the discussion of events in Chapter 9 that to register a handler for an event you add an instance of the delegate to the event. The delegate for the CellFormatting event is of type DataGridViewCellFormattingEventHandler, and it expects two parameters: the first parameter is of type Object^ and identifies the source of the event and the second parameter is a handle to an object of type DataGridViewCellFormattingEventArgs. The second argument passed to a handler for the CellFormatting event provides additional information about the event through the following properties: Property

Description

Value

The value is a handle to the contents of the cell that is being formatted.

DesiredType

The value is handle to an object of type Type that identifies the type of the contents off the cell being formatted.

CellStyle

Gets or sets the cell style of the cell that is associated with the formatting event so the value is a handle to an object of type DataGrid ViewCellStyle.

ColumnIndex

The value is the column index for the cell that is being formatted.

RowIndex

The value is the row index for the cell that is being formatted.

FormattingApplied

The value, true or false, indicates whether formatting of the cell contents has been applied.

These properties enable you to find out all you need to know about the cell being formatted — the row and column for the cell, the current style in effect, and the contents of the cell. The first step in handling the CellFormatting event is to define a handler function for it. The handler code needs to be as short and efficient as possible because the function is called for every cell in the control whenever the cell needs to be formatted. You could add the following function to the Form1 class that is a handler function for the CellFormatting event: private: void OnCellFormatting(Object^ sender, DataGridViewCellFormattingEventArgs^ e) { // Check if it’s the date column if(dataGridView->Columns[e->ColumnIndex]->Name == L”Date”) { // If the cell content is not null and the year is less than 2000 // Set the background to red if(e->Value != nullptr && safe_cast(e->Value)->Year < 2000) { e->CellStyle->BackColor = Color::Red; e->FormattingApplied = false; // We did not format the data } } }

1109

Chapter 22 You first check whether the current column is the Date column because you are interested only in modifying cells in that column. For cells in the Date column you check if the cell contents actually exist, and if there is a DateTime object present, that the year is less than 2000. In this case you set the BackColor property for the object returned by the CellStyle property to Color::Red. You set the FormattingApplied property to false to indicate that you have not formatted the contents. This is not strictly necessary because the value starts out as false. You would set it to true if you were taking care of formatting the contents in the handler and this would prevent subsequent formatting using the value of the Format property. To register this function as a handler for the CellFormatting event, add the following statement to the end of the Form1 class constructor: dataGridView->CellFormatting += gcnew DataGridViewCellFormattingEventHandler(this, &Form1::OnCellFormatting);

The first argument to the delegate is the handle to the object containing the handler function and is the current Form1 object. The second argument is the address of the function that is the new handler for the event. If you recompile the example and execute it once again, you should see that all the cells in the Date column that contain a date prior to the year 2000 have the background color red. The DataGridView control defines CellMouseEnter and CellMouseLeave events that fire when the mouse cursor enters or leaves a cell. You could implement handlers for these events to highlight the cell that the mouse cursor is over by changing its background color. You could set new background and foreground colors in the handler for the CellMouseEnter event and restore the original colors in the handler for the CellMouseLeave event. There are a few tricky aspects to this, so it’s worth looking into specifically.

Try It Out

Highlighting the Cell under the Mouse Cursor

This will be an extension to Ex22_02 including the latest addition of the CellFormatting event handler rather than a new example from scratch. You’ll need to store the old background and foreground colors somewhere, so add the following private data members to the Form1 class: // Stores for old cell colors in mouse enter event handler // for restoring later in mouse leave event handler private: Color oldCellBackColor; private: Color oldCellForeColor;

You should initialize both of these to Color::Empty in the Form1 class constructor. The first parameter to the delegate for either the CellMouseEnter or CellMouseLeave events is a handle to the object originating the event, which is the DataGridView control. The second parameter to both delegates is a handle to an object of type DataGridViewCellEventsArg that provides additional information about the event. This object has RowIndex and ColumnIndex properties, and the values of these properties enable you to locate the cell the mouse is entering or leaving; you can use the former to index the Rows property to select the row that contains the cell and the latter to index the Cells property to select the cell itself within the row. There’s one thing to note — the value of the RowIndex property is -1 when the mouse cursor is in the column header row and the ColumnIndex property value is -1 when the mouse cursor is over one of the row headers. You’ll need to check for these possibilities because attempting to use a negative index with the Rows property value causes an exception to be thrown, as does indexing the Cells property for a row with a negative value.

1110

Accessing Data Sources in a Windows Forms Application You can now define a private handler function in the Form1 class for the CellMouseEnter event like this: private: void OnCellMouseEnter(Object^ sender, DataGridViewCellEventArgs^ e) { if(e->ColumnIndex >= 0 && e->RowIndex >= 0) // Verify indexes non-negative { // Identify the cell we have entered DataGridViewCell^ cell = dataGridView->Rows[e->RowIndex]->Cells[e->ColumnIndex]; // Save any old colors that are set oldCellBackColor = cell->Style->BackColor; oldCellForeColor = cell->Style->ForeColor; // Set highlight colors cell->Style->BackColor = Color::White; cell->Style->ForeColor = Color::Black; } }

After establishing that both index values are non-negative, you obtain the handle for the cell that the mouse cursor entered. You do this by first selecting the row by indexing the value of the Rows property for the control with the RowIndex property value for the parameter e; you then index the Cells property of the row using the ColumnIndex property of e to select the cell within the row. After you have the cell handle, it’s easy to save the values of the BackColor and ForeColor properties from the Style property of the cell and set new colors to display the cell as black text on a white background. The Style property may not have been set, in which case accessing the property value creates a new DataGridViewCellStyle object as the value that has BackColor and ForeColor property values as Color::Empty. If the Style property for the cell has been set, you’ll get the object containing whatever properties have been set for it. The handler function for the CellMouseEnter event has to restore the color back to what is was. You can implement this handler function like this: private: void OnCellMouseLeave(Object^ sender, DataGridViewCellEventArgs^ e) { if(e->ColumnIndex >=0 && e->RowIndex >=0) { // Identify the cell we are leaving DataGridViewCell^ cell = dataGridView->Rows[e->RowIndex]->Cells[e->ColumnIndex]; // Restore the saved color values cell->Style->BackColor = oldCellBackColor; cell->Style->ForeColor = oldCellForeColor; // Reset save stores to no color oldCellForeColor = oldCellBackColor = Color::Empty; } }

1111

Chapter 22 Again you check that the index values are non-negative before doing anything. After identifying the cell as in the previous handler, you restore the saved colors in the Style property for the cell. The way in which the foreground and background colors for a cell are determined is by the priority list you saw earlier. If the Style property had not been set for the cell, the values you restore are Color::Empty and this is ignored when the colors for the cells are determined. Thus, the original color applies. If the Style property had been defined with ForeColor and BackColor properties set, these are the values you restore, and they determine the cell formatting colors. To register the function handlers, add the following statements to the end of the Form1 class constructor: dataGridView->CellMouseEnter += gcnew DataGridViewCellEventHandler(this, &Form1::OnCellMouseEnter); dataGridView->CellMouseLeave += gcnew DataGridViewCellEventHandler(this, &Form1::OnCellMouseLeave);

The same delegate applies to all cell events, so you register both handlers using the DataGridViewCellEventHandler delegate. If you recompile the program a run it once again, you should see highlighting of cells in action, as illustrated in Figure 22-11.

Figure 22-11

Well, it certainly works — at least most of the time. However, the red cells in the Date column aren’t highlighted, so what’s going on? The sequence of events is at the root of the problem. The CellFormatting event is triggered after the CellMouseEnter event, so the handler function that sets the background color to red has the last word and overrides the effect of the handler for the CellMouseEnter event. What you want to happen is that the CellFormatting event handler should recognize that the cell is highlighted and do nothing when this is the case. You could provide for this by adding another member to the Form1 class that stores the handle to the cell that is currently highlighted: private: DataGridViewCell^ highlightedCell;

// The currently highlighted cell

You should also initialize this new member to nullptr in the Form1 class constructor.

1112

Accessing Data Sources in a Windows Forms Application You now need to amend the handler for the CellMouseEnter event to store the handle for the highlighted cell in the new member: void OnCellMouseEnter(Object^ sender, DataGridViewCellEventArgs^ e) { if(e->ColumnIndex >= 0 && e->RowIndex >= 0) // Verify indexes non-negative { // Identify the cell we have entered highlightedCell = dataGridView->Rows[e->RowIndex]->Cells[e->ColumnIndex]; // Save any old colors that are set oldCellBackColor = highlightedCell->Style->BackColor; oldCellForeColor = highlightedCell->Style->ForeColor; // Set highlight colors hightLightedCell->Style->BackColor = Color::White; highlightedCell->Style->ForeColor = Color::Black; } }

You can change the implementation of the handler for the CellMouseLeave event to the following: void OnCellMouseLeave(Object^ sender, DataGridViewCellEventArgs^ e) { if(e->ColumnIndex >=0 && e->RowIndex >=0) { // Restore the saved color values highlightedCell->Style->BackColor = oldCellBackColor; highlightedCell->Style->ForeColor = oldCellForeColor; // Reset save stores to no color oldCellForeColor = oldCellBackColor = Color::Empty; highlightedCell = nullptr;

// Reset highlighted cell handle

} }

You no longer need to determine the cell handle, as it’s available in the highlightedCell member of the Form1 class. You don’t even have to check it, because a CellMouseLeave event must always be preceded by a CellMouseEnter event. You reset the handle of the highlighted cell to null because it’s good practice to do so. You can now amend the handler for the CellFormatting event: void OnCellFormatting(Object^ sender, DataGridViewCellFormattingEventArgs^ e) { // Check whether the cell is highlighted if(dataGridView->Rows[e->RowIndex]->Cells[e->ColumnIndex] == highlightedCell) return; // Check if it’s the date column if(dataGridView->Columns[e->ColumnIndex]->Name == L”Date”) {

1113

Chapter 22 // If the cell content is not null and the year is less than 2000 // Set the background to red if(e->Value != nullptr && safe_cast(e->Value)->Year < 2000) { e->CellStyle->BackColor = Color::Red; e->FormattingApplied = false; // We did not format the data } } }

If you rebuild the example, you should now see all the cells highlighted. You should now have a good idea of how you can implement event handler for a DataGridView control. There are a multitude of other events, so you have huge scope for doing many more things dynamically to customize the control to your application needs.

Using Bound Mode In bound mode, the source of the data that a DataGridView control displays is specified by the value of its DataSource property, which in general you can set to be any ref class object of a type that implements any of the following interfaces: Interface

Description

System::Collections::Ilist

A class that implements this interface represents a collection of objects that can be accessed through a single index. All C++/CLI onedimensional arrays implement this interface, so a DataGridView object can use any onedimensional array as the source of the data that is displayed. The IList interface inherits the members of the ICollection and IEnumerable interface classes that are defined in the System::Collections namespace.

System::ComponentModel::IListSource

A class that implements this interface makes the data available as a list that is an IList object. The list can contain objects that also implement the IList interface.

System::ComponentModel::IBindingList

This interface class extends the IList interface class to allow more complex data binding situations to be accommodated.

System::ComponentModel:: IBindingListView

Adds sorting and filtering capabilities to the IBindingList interface. The BindingSource class that you’ll meet a lit-

tle later in this chapter defines a control that implements this interface.

1114

Accessing Data Sources in a Windows Forms Application You can obviously design your own classes so that that implement one or other of these interfaces, and then you’ll be able to use them as a data source for a DataGridView control in bound mode. Most of the time, though, you’ll want to access an existing data source without having to go to the trouble of creating your own classes to access the data in which case the BindingSource component is likely to be your first choice.

The BindingSource Component You use the BindingSource component as an intermediary between controls on a form and a table in a data source. You have the option of binding the component to a DataGridView control that displays the contents of the table, or to a set of individual controls where each displays a column from the table. You can also add data programmatically to a BindingSource component, in which case it acts as the data source and behaves essentially as a list. You’ll first look at how you use a BindingSource component as the data source for a DataGridView control. There is a high degree of automation possible in creating a program that uses a BindingSource component, but to get an idea of how the component hooks up with the control, you’ll assemble the components on the form manually in the first instance. To make a BindingSource component the data source for a DataGridView control, you set the value of the DataSource property for the control to be the handle that references the BindingSource component.

Try It Out

Using a BindingSource Component

Here you’ll put together a simple program to view a database table. I’ll describe the process assuming you are using the Northwind database that you used back when you were working with the MFC, but you can use any database you have available on your system. Create a new Windows Forms project with the name Ex22_03 and change the Text property for the form to something helpful such as “Using a Binding Source Component.” Add a DataGridView control to the client area of the form and change its Name property to dataGridView. You can also set the Dock property value for the control to FILL. At the moment, the DataGridView control is unbound, so you need to add a data source to the project that you can bind to the control, and this process will create the BindingSource component along the way. Click the small arrow at the top right of the control to display its menu, click the arrow for the list box adjacent to the Choose Data Source menu item, and click the Add Project Data Source link. This displays the dialog box shown in Figure 22-12. The same dialog box is displayed if you select the Data→ Add New Data Source menu item from the main menu, but this only adds the data source to the project — it does not associate it with a control. As you see, you have a choice of two locations for the data source, but here you want to click the Database option. The second option allows you to specify an object that provides the data source defined either within the project or within some other assembly that you have created. After selecting the Database option and clicking the Next button, you’ll see the dialog box shown in Figure 22-13.

1115

Chapter 22

Figure 22-12

Figure 22-13

The existing data connections that you have set up appear in the drop-down list, and you can choose one of those. You can also click the New Connection button to set up a new connection to a data source. This displays the Add Connection dialog box shown in Figure 22-14.

1116

Accessing Data Sources in a Windows Forms Application

Figure 22-14

Here you can enter the data source specification as a name, or you can enter a connection string for the data source by clicking the second radio button. After you have entered any necessary login information, you can test that the connection really does work by clicking the Test Connection button. On my system, the ODBC source is preselected, but if you don’t want the default that you see displayed, you can click the Change button to display the Change Data Source dialog box shown in Figure 22-15.

Figure 22-15

1117

Chapter 22 The dialog box displays the types of data sources that you have available, and you choose the type of data source that you want to work with and click the OK button. You’ll then return to the dialog box shown in Figure 22-14 where you can complete the identification and verification of the data source before clicking the OK button to return to the dialog shown in Figure 22-13. When you click the Next button, you are likely to see a message box asking if you want to add the data source to the project; clicking the Yes button then displays the dialog box shown in Figure 22-16 where you can choose the objects in the database that you want to work with.

Figure 22-16

Here you can choose which database objects you want added to the project. You do this by expanding the tree so you can select the individual tables you want to work with, or even individual fields within a table. For this example, you can keep it simple and choose just the Customers table. You can also change the name of the dataset — I changed it to Customers. When you click the Finish button, the wizard creates the code that you need to access the database. The database is encapsulated in a class derived from the DataSet class. Each database table that you select results in a class derived from the DataTable class being defined as an inner class to the DataSet class. There is also a table adapter class for each DataTable in the DataSet class that has the job of establishing the connection to the database and loading the data from the database table into the corresponding DataTable member of the DataSet object. This results in a considerable amount of code being generated; with just the Customers table in the Northwind database selected you get nearly 2000 lines of code. It also adds a BindingSource component to the project that provides the interface between the Customers table in the Northwind database and the DataGridView control. The Design tab in the editing window should look like Figure 22-17.

1118

Accessing Data Sources in a Windows Forms Application

Figure 22-17

You can see that three objects have been added to the project as a result of adding the data source: the NorthWindDataSet object that encapsulates the database, the CustomersTableAdapter object that accesses the data in the Customers table in the database, and the CustomersBindingSource object that manages the communications between the database and the DataGridView control. The application is now complete, and so far you have not written a single line of code. That’s quite remarkable considering the amount of function you have in the program; however, when I ran the program, the column headers look a little cramped. I prefer the column widths to be set to accommodate the text in the rows, so I couldn’t resist adding the following two lines of code to the Form1 class constructor: dataGridView->AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode::AllCells; dataGridView->AutoResizeColumnHeadersHeight();

The application window now looks as shown in Figure 22-18.

1119

Chapter 22

Figure 22-18

You can use the scrollbars to navigate the data and your mouse wheel should scroll the rows. The BindingNavigator control could improve things a bit, so next you’ll see how to use that.

Using the BindingNavigator Control The BindingNavigator control has been specifically designed to work with a BindingSource component. To use a BindingNavigator control to navigate the data from a data source could not be simpler; you just add the control to the form and set the value of the BindingSource property for the control to the variable encapsulating the BindingSource component. The next Try It Out extends Ex22_03 to do that.

Try It Out

Using a BindingNavigator Control

Click the BindingNavigator control in the Toolbox window and then click in the client area of the form to add it to the project. If you open the Properties window for the control, you are able to set the value for the BindingSource property to customersBindingSource, which is the name of the handle to the BindingSource control that encapsulates the Customers table. That’s it; you’re done. If you recompile and rerun the application, you see that the application window now has a toolbar for navigating the data, as shown in Figure 22-19. You can click the button arrows to progress forwards and backwards through the data records, and there are also buttons to go to the first or last records. If you type a record sequence number in the text box on the toolbar and press Enter, you’ll go directly to that record. The ability to navigate through the records works in whatever sequence they are in. You could sort the records in country order by clicking the header for the Country column to sort the records, and you’ll then be able to navigate through them in that sequence. The BindingNavigator control also provides buttons for adding a new record and deleting a record. Each of the buttons provided by the BindingNavigator control connects to a member of the BindingSource object being navigated:

1120

Accessing Data Sources in a Windows Forms Application

Figure 22-19

Toolbar Control

Action

Move First

Calls the MoveFirst() function for the BindingSource control object, which changes the current record for the underlying data source to be the first record.

Move Previous

Calls the MovePrevious() function for the BindingSource control object, which changes the current record for the underlying data source to be the previous record if there is one.

Current Position

Corresponds to the value of the Current property for the BindingSource object, which is the current record in the underlying data source.

Total Number of Items

Corresponds to the value of the Count property value for the BindingSource object, which corresponds to the number of records in the underlying data source.

Move Next

Calls the MoveNext() function for the BindingSource control object, which changes the current record for the underlying data source to be the next record if there is one.

Move Last

Calls the MoveLast() function for the BindingSource control object, which changes the current record for the underlying data source to be the last record.

Add New

Calls the AddNew() function for the BindingSource object. This has the effect of calling EndEdit() to execute any pending edit operations for the underlying data source and creates a new record in the list maintained by the BindingSource object. This does not update the underlying data source.

Delete

Calls the RemoveCurrent() function for the BindingSource object to remove the current record from the list. This does not modify the underlying data source.

1121

Chapter 22 Thus clicking a button on the navigator toolbar initiates an action in the BindingSource object that is managing the data source, but none of the default operations change the database that the BindingSource component is managing. To do that you must write some code.

Try It Out

Updating a Database

You are going to have to do something extra when the user clicks a button in the BindingNavigator control to add a new record or to delete a record. The way to do this is to implement a handler function to deal with a Click event for the buttons. As you already know, you can add a Click event handler for a button by double-clicking the button in the Design tab, so add handler functions for the Add New and Delete buttons on the toolbar. When you click either button at the moment, everything has been put in place in the BindingSource component to allow the database to be updated. All you have to do is call the Update() function for the table adapter object for the table that is to be updated. This function throws an exception if things go wrong, so you must put the call in a try block and catch any exception that may be thrown. Here’s how you can implement the handler function for the Add New button Click event: System::Void bindingNavigatorAddNewItem_Click(System::Object^

sender, System::EventArgs^

e)

{ try { CustomersTableAdapter->Update(Customers->_Customers); } catch (Exception^ ex) { MessageBox::Show(L”Update Failed!\n”+ex, L”Database Record Update Error”, MessageBoxButtons::OK, MessageBoxIcon::Error); } }

The argument to the Update() function must be the name of the data table that contains the values that are to be written to the database, so in this case it’s the _Customers member of the Customers object in the Form1 class. If things don’t go as well as expected, you display a message box explaining the problem. The message box shows the text from the Exception object that was thrown, and this explains the cause of the problem. The implementation of the Click event handler for the Delete button is almost identical: private: System::Void bindingNavigatorDeleteItem_Click(System::Object^ sender, System::EventArgs^ { try { CustomersTableAdapter->Update(Customers->_Customers); } catch (Exception^ ex) {

1122

e)

Accessing Data Sources in a Windows Forms Application MessageBox::Show(L”Delete Failed!\n”+ex, L”Database Record Delete Error”, MessageBoxButtons::OK, MessageBoxIcon::Error); } }

The only difference is in the text in the message box. With these two handler functions in place, you should be able to add new customer records and delete existing records.

Binding to Individual Controls You can also create a Windows Forms application that binds each column on a database table to a separate control; what’s more, you’ll find this easier and quicker than the previous example. Start by creating a new CLR project using the Windows Forms Application template with the name Ex22_04. The next step is to add a data source to the project, and again you will be working with a single table. Press Shift+Alt+D to display the Data Sources window and click Add New Data Source. You can use the Northwind database or a database of your choice, but keep in mind that you have a separate control on the form for each column in the table that you choose. To keep the number of controls manageable, for the Northwind database I suggest you select the Order Details table, as shown in Figure 22-20, because it has only five columns.

Figure 22-20

When you click the Finish button, the Data Sources window shows the Northwind database as the data source with just the Order Details table available. Click the Order Details table name to select it and then click the down arrow to the right to display the menu shown in Figure 22-21.

1123

Chapter 22

Figure 22-21

The top three menu items enable you to choose the controls to be used with the table when you add the data source to the form. If you click the DataGridView item from the menu, you are selecting that control as the one to be for displaying the table, whereas clicking on the Details item indicates you want one control per table column. If you click the [None] item, you are indicating you want no controls to be created when you add the data source to the form. The last menu item opens a dialog box for changing the default control for the table from the current default of DataGridView and for customizing the choice of controls. In this instance, you should just click Details because you want one control for each table column. You now have to decide which control you want to use for each table column. You can extend the tree that shows the column names in the Order Details table name by clicking the + symbol to the left of the table name. If you then click the first column name to select it, you’ll see that you can display a menu for that, too, by clicking the down arrow. The menu is shown in Figure 22-22. You can choose any of the controls shown in the menu, but I suggest a TextBox control is most appropriate for the OrderID column. You need to repeat the process for each table column; you can choose a NumericUpDown control for the Quantity column and select a TextBox control for each of the others. Note that selecting the Customize menu option in the Data Sources pane shown in Figure 22-22 displays the Options dialog box in which you can change the selection of controls available for displaying different types of data. You can also change the control to be selected by default when you drag an item from the Data Sources pane to a form. Figure 22-23 shows the Options dialog box.

1124

Accessing Data Sources in a Windows Forms Application

Figure 22-22

Figure 22-23

Figure 22-23 shows the controls associated with displaying a list, and there is a separate list of associated controls for each of the data types you can select. I have checked the ComboBox and ListBox controls in addition to the DataGridView default, so all three controls are options for displaying a list of data items. You can choose other data types in the drop-down list box at the top of the dialog box for which you want to modify the choice of controls available.

1125

Chapter 22 The final step to create the program is to drag the Order Details table from the Data Sources window to the client area of the form window. The Design tab in the Editor pane will then look similar to that shown in Figure 22-24.

Figure 22-24

I have changed the Text property for the form to make the text in the title bar a little more relevant, and I repositioned the controls slightly so they are better located within the client area. I also rearranged the items in the grey area at the bottom to make them all visible in the Design pane. You can see that five controls corresponding to the five table columns have been added automatically to the form as well as label controls to indicate which is which. There’s a BindingNavigator control at the top of the client area for navigating the table data. Below the form you can see that the application has a BindingSource component that links the database to the controls, and the DataSet and table adapter classes are also identified. If you press Ctrl+F5 to build and execute the program, you’ll have a complete working program for viewing and editing the Order Details table in the Northwind database. There is a Save button that has been added to the BindingNavigator toolbar that you click to store any changes you make back in the database table. Figure 22-25 shows the application window. You could create a program that uses the DataGridView control to display a table in essentially the same way. If you want to try it, just create another project and add the data source as in the previous example. If you then immediately drag the table from the Data Sources window to the form, the application is complete. You need only set Text property for the form for the title bar text and set the value of the Dock property for the DataGridView control before compiling and running the program.

1126

Accessing Data Sources in a Windows Forms Application

Figure 22-25

Working with Multiple Tables Creating an application that works with multiple tables is almost as easy as the previous example. In this example, you’ll use a tab control to allow three different tables in the Northwind to be accessed. Create a new Forms project with the name Ex22_05, and press Shift+Alt+D to open the Data Sources window. Add the Northwind database to the project with the Customers, Products, and Employees tables checked. Add a TabControl control from the Containers group in the Toolbox window to the form and set the Dock property value for the tab control to Fill. If you click the arrow at the top right of the control, you’ll be able to add a third tab page to the control. You can move between the tabs on the TabControl control using the Tab key, or by clicking the tab page label twice; take care not to double-click the control or you’ll generate handler functions for it. Move to the first tab page and set its Text property value to Employees. You can then set the Text property value for the other two tabs to Customers and Products. You should also add a Panel control to each tab page with its Dock property value set to Fill. This is necessary to locate the BindingNavigator and DataGridView controls properly on the tab page. If you add them directly to the tab, setting the DataGridView Dock property to Fill with the BindingNavigator control docked to the top of the tab page, the column headers for the DataGridView control are hidden by the BindingNavigator control. This won’t happen Within a Panel container. You might also want to change the Text property value for the form to something relevant — I made it “Accessing Multiple Tables.”

You can now drag the Customer table from the Data Sources window to the panel on the tab page labeled Customers. A DataGridView control IS added to the panel, and a BindingNavigator control appears at the top of the form. You’ll want each tab page to have its own BindingNavigator control, so having it placed on the form is not convenient. You’ll need to move it to the panel on the tab page. You can do this by first setting the Dock property value for the BindingNavigator control to None and then dragging the control on to panel on the Customers tab page.

1127

Chapter 22 After you have added the table to the Customers tab page, switch to the next tab before dragging the next table on to its panel from the Data Sources window. When you have added the appropriate table to the panels on the other two tab pages, they each contain a DataGridView control, but no BindingNavigator control — this was not added because you have one already from adding the Customers table. You could add BindingNavigator controls to these tab pages from the Toolbox window, but there’s a shortcut you can use. Click the BindingNavigator control on the Customers tab page and press Ctrl+C to copy it to the Clipboard. Switch to one of the other tab pages, select its panel, and press Ctrl+V to copy the control from the Clipboard to the panel on the tab page. Switch to the third tab page, select its panel, and then press Ctrl+V once more to add a BindingNavigator control to the panel on that tab page. You can then set the Dock property value for each of the three BindingNavigator controls to Top and the Dock property value for each of the DataGridView controls to Fill. The two BindingNavigator controls that are copies have their BindingSource property values set incorrectly, so select the value field for the property for each of these controls and select the correct BindingSource component from the drop-down list. You should select EmployeesBindingSource for the control on the Employees tab page, and ProductsBindingSource for the control on the Products tab page. If you press Ctrl+F5 to build and execute the example, you should see the application window shown in Figure 22-26.

Figure 22-26

This all works with no coding at all. I think you’ll agree that this is an amazing capability for generating applications to access data sources.

1128

Accessing Data Sources in a Windows Forms Application

Summar y This has been a brief introduction to the capabilities you have for accessing data sources in a Windows Forms application. There’s a great deal more you can do, but you should find that as you now have a good idea of how you use the design capability to assemble controls on a form and how the controls involved in data access work together. You’ll have few problems getting into other areas by yourself. The key points you have learned about in this chapter include: ❑

A data source can be a relational database, a Web service, or an object.



A class derived from the System::Data::DataSet class is used to encapsulate a data source, and a class derived from the System::Data::DataTable class table encapsulates a table in a data source.



A row of data in a DataTable object is represented by an object of type System::Data::DataRow, and the schema for a column is described by an object of type System::Data::DataColumn.



A connection to a data source and the commands to access the data are encapsulated in a component called a table adapter.



You use a DataGridView control on a form to display data in the form of a rectangular grid.



You can bind a DataGridView control to a data source to display the contents of a table. You can also use a DataGridView control in unbound mode to display data originating in your program.



You can customize a DataGridView control to modify how rows, columns, headers and individual cells are displayed.



A BindingSource component provides an interface between a data source and controls on a form. A BindingSource component can link the columns in a table to individual controls on a form, or it can link the contents of a table to a DataGridView control.



A BindingNavigator control provides a toolbar for navigating data that you access via a BindingSource component.

Exercises You can download the source code for the examples in the book and the solutions to the following exercises from http://www.wrox.com.

1. 2. 3. 4.

Modify Ex22_04 so that the column headers are displayed in a 12-point italic font. Modify Ex22_05 so the columns are wide enough to accommodate the text in each cell. Modify Ex22_05 so that alternate rows of data on each tab page appear shaded. Create a Windows Forms application that displays the Suppliers table from the Northwind database.

1129

A C++ Keywords Keywords have been assigned special significance within the C++ language, so you must not use them as names within your programs. The Visual C++ 2005 compiler compiles programs written in ISO/ANSI C++ and programs written for the CLR that conform to the C++/CLI specification, so the compiler recognizes the set of keywords defined by ISO/ANSI C++ as well as the additional set of keywords defined by C++/CLI. Although programming in native C++, you need be concerned only with the ISO/ANSI C++ keywords. When writing programs for the CLR, you need to be aware of both sets of keywords.

ISO/ANSI C++ Keywords The ISO/ANSI C++ language specification defines the following keywords: asm

false

sizeof

auto

float

static

bool

for

static_cast

break

friend

struct

case

goto

switch

catch

if

template

char

inline

this

class

int

throw

const

long

true

const_cast

mutable

try

continue

namespace

typedef Table continued on following page

Appendix A default

new

typeid

delete

operator

typename

do

private

union

double

protected

unsigned

dynamic_cast

public

using

else

register

virtual

enum

reinterpret_cast

void

explicit

return

volatile

export

short

wchar_t

extern

signed

while

C++/CLI Keywords The C++/CLI language specification defines the following keywords in addition to those defined for ISO/ANSI C++: enum class

enum struct

for each

gcnew

interface class

interface struct

nullptr

ref class

ref struct

value class

value struct

Note that the word pairs are keywords, not necessarily the individual words; for example, for each is a keyword, but each is not. The C++/CLI language also defines a number of identifiers that are not keywords but have a contextsensitive meaning in some circumstances. These are: abstract

delegate

event

finally

generic

in

initonly

internal

literal

override

property

sealed

where In principle you can still use these identifiers as names in your code because the context determines when they have special significance, but I recommend that you treat them as keywords and do not use them for other purposes. In that way you avoid any possibility for confusion on the part of someone else who may be reading your code.

1132

B ASCII Codes The first 32 ASCII (American Standard Code for Information Interchange) characters provide control functions. In the following table, only the first 128 ASCII characters have been included. The remaining 128 characters include further special symbols and letters for national character sets, so there are many varieties of these to suit a wide range of language contexts. Decimal

Hexadecimal

Character

Control

000

00

null

NUL

001

01

J

SOH

002

02



STX

003

03



ETX

004

04



EOT

005

05



ENQ

006

06



ACK

007

07



BEL (Audible bell)

008

08

Backspace

009

09

HT

010

0A

LF (Line feed)

011

0B

VT (Vertical tab)

012

0C

FF (Form feed)

013

0D

CR (Carriage return)

014

0E

SO

015

0F

¤

SI Table continued on following page

Appendix B Decimal

Hexadecimal

016

10

DLE

017

11

DC1

018

12

DC2

019

13

DC3

020

14

DC4

021

15

NAK

022

16

SYN

023

17

ETB

024

18

CAN

025

19

EM

026

1A



SUB

027

1B



ESC (Escape)

028

1C

\

FS

029

1D

GS

030

1E

RS

031

1F

US

032

20

space

033

21

!

034

22



035

23

#

036

24

$

037

25

%

038

26

&

039

27



040

28

(

041

29

)

042

2A

*

043

2B

+

044

2C

,

045

2D

-

046

2E

.

1134

Character

Control

ASCII Codes Decimal

Hexadecimal

Character

047

2F

/

048

30

0

049

31

1

050

32

2

051

33

3

052

34

4

053

35

5

054

36

6

055

37

7

056

38

8

057

39

9

058

3A

:

059

3B

;

060

3C




063

3F

?

064

40

@

065

41

A

066

42

B

067

43

C

068

44

D

069

45

E

070

46

F

071

47

G

072

48

H

073

49

I

074

4A

J

075

4B

K

076

4C

L

077

4D

M

Control

Table continued on following page

1135

Appendix B Decimal

Hexadecimal

Character

078

4E

N

079

4F

O

080

50

P

081

51

Q

082

52

R

083

53

S

084

54

T

085

55

U

086

56

V

087

57

W

088

58

X

089

59

Y

090

5A

Z

091

5B

[

092

5C

\

093

5D

]

094

5E

^

095

5F

_

096

60



097

61

a

098

62

b

099

63

c

100

64

d

101

65

e

102

66

f

103

67

g

104

68

h

105

69

i

106

6A

j

107

6B

k

108

6C

l

1136

Control

ASCII Codes Decimal

Hexadecimal

Character

109

6D

m

110

6E

n

111

6F

o

112

70

p

113

71

q

114

72

r

115

73

s

116

74

t

117

75

u

118

76

v

119

77

w

120

78

x

121

79

y

122

7A

z

123

7B

{

124

7C

|

125

7D

}

126

7E

~

127

7F

delete

Control

The Unicode codes that have the same numerical code values as the ASCII codes in the table represent the same characters. You’ll find comprehensive information on the Unicode character coding system at http://www.unicode.org.

1137

Index

Index

Index

Index

SYMBOLS :: (colons), scope resolution operator classes, 341–342 definition, 26 example, 93–94 , (comma), expression separator, 76–77 . (period) member access operator, 325 member selection operator, 325 ; (semicolon), end of statement indicator, 47 & (ampersand) AND, 82–83 address-of operator, 173–174 && (ampersands), logical AND, 125 >> (angle brackets), extraction operator, 62–63 -> (arrow) indirect member access operator, 332 indirect member selection operator, 332 * (asterisk), indirection operator, 174 ^ (caret), exclusive OR, 85 “...” (double quotes), special character indicator, 65 = (equal sign), assignment operator, overloading, 418–422 == (equal signs), relational operator, 115–116 ! (exclamation mark), logical NOT, 126 != (exclamation mark, equal sign), relational operator, 115–116 > (greater than) operator overloading, 415–417 OR, 84–85 relational operator, 115–116

>= (greater than, equal sign), relational operator, 115–116 (right angle bracket), OR, 84–85 >> (right angle brackets), shift right, 86–87 // (slashes), comment indicator, 44 || (vertical bars), logical OR, 125–126 { } (curly braces), function syntax, 46 ~ (tilde), NOT, 86

A abstract classes, inheritance, 505–508 access control classes, 336 inheritance, 479–482, 489–490

access specifiers access specifiers, 531–532 Add() function, 1094 AddCopy() function, 1094 AddHead() function, 764–766, 772 AddNew() function, 980–982, 1121 addresses, returning values from, 256–257 AddTail() function, 764–766, 772 AFX_EXT_CLASS keyword, 912–913, 916 aliases. See references; tracking references. alignment, cells, 1100 Alignment property, 1100 allocating memory. See dynamic memory allocation. AlternatingRowsDefaultCellStyle property, 1101 ampersand (&) AND, 82–83 address-of operator, 173–174 ampersands (&&), logical AND, 125 angle brackets (>>), extraction operator, 62–63 anonymous unions, 409–410 API (application programming interface), 617–618 application class, 653 application programming interface (API), 617–618 Application wizard. See MFC Application wizard. Arc() function, 716–717 arguments, to functions arrays as, 243–247 arrays of function pointers as, 277 definition, 232 function pointers as, 275–277 passing to main(), 250–252, 267–268 passing-by-pointer, 241–243 passing-by-reference, 247–249 passing-by-value, 240–241 pointer notation, 244–245 variable number of, 252–254, 266–267 arithmetic operations , (comma), expression separator, 76–77 -- (minus signs), decrement operator, 74–76 ++ (plus signs), increment operator, 74–76 assignment statements, 67–68 basic operators, 68 bitwise operators & (ampersand), AND, 82–83 ^ (caret), exclusive OR, 85 (right angle bracket), OR, 84–85 >> (right angle brackets), shift right, 86–87 ~ (tilde), NOT, 86 description, 81 inclusive OR, 84–85 casting types

1142

in assignment statements, 79–80 C++/CLI, 108–109 definition, 78 explicit casts, 80–81 old-style casts, 81 rules for, 78–79 safe_cast operation, 108–109 const modifier, 70–71 example, 69–73 expressions, separating, 76–77 Lvalues, 68 memory addresses, 68 modifying variables, 73–74 operator precedence, 77–78 with pointers, 185–187 remainders, calculating, 69–73 Rvalues, 68 arrays of arrays, 213–216 character, 166–169 CLR, 200–205 collection classes CArray template class, 761–763 collections of objects, 761–763 definition, 760 collections of objects, 761–763 elements, 160 entering data, 163 as function arguments, 243–247 indexing, 160–161 multidimensional basic structure of, 169–170 initializing, 170–172 passing to functions, 245–247 pointer notation, 191–192 string handling, 171–172 names, as pointers, 187–189 null character, 166 of objects, 363–364 one-dimensional basic structure of, 160–161 declaring, 161–164 initializing, 164–165 string handling, 166–169 string termination character, 166 and pointers, 185–192 of pointers, 179–181 size of, determining, 181–183 sizeof operator, 181–183

arrow (->) indirect member access operator, 332 indirect member selection operator, 332 ASCII codes, table of, 1133–1137 assemblies, 25 Assert() function, 578–580, 607–608 assertions, 578–580, 607–608 assignment statements, 47, 67–68, 79–80 asterisk (*), indirection operator, 174 automatic variables, 88–91

B b prefix, 619–620 BackColor property, 1099–1100 background color, cells, 1099–1100 base classes accessing private members, 480–482 definition, 475–476 deriving classes from, 476–479 direct, 475–476 indirect, 475–476, 508–511 pointers to, 501–503 BeginTrans() function, 983–984 binding controls to columns, 1123–1127 data sources, 1115–1120 BindingNavigator control, 1120–1123 BindingSource component, 1115–1120 bitwise operators & (ampersand), AND, 82–83 ^ (caret), exclusive OR, 85 (right angle bracket), OR, 84–85 >> (right angle brackets), shift right, 86–87 ~ (tilde), NOT, 86 description, 81 inclusive OR, 84–85 black-and-white drawing, 747 block scope, 88 body, function, 234–235 bool data type, 57 BOOLEAN data type, 618 Boolean variables, 57 borders, windows, 615 bound mode, 1093, 1114–1115 bounding rectangles, 739–741 boxing data types, 101

branching, unconditional, 132 breakpoints, 570–572 Browser style toolbar option, 659 brushes, 719–721 bugs. See also debugging. common examples, 567–568 definition, 565 semantic errors, 567 syntactic errors, 567 Button control, 1044–1046 buttons cells, 1095 in cells, 1095 clicks, handling, 1076–1079, 1083–1086 definition, 819 illustration, 819 labels, changing, 992–993 movement, detecting, 725 by prefix, 619–620 BYTE data type, 618

C c prefix, 619–620 C++ programs. See also C++/CLI programs; program structure. basic development options, 3–4 managed C++, 3 native C++, 2, 3 simple example, 39–44 standards, 5–6 unmanaged C++, 3 C++/CLI programs. See also specific topics. definition, 5–6 overview, 150–156 calculations. See arithmetic operations. calculator example analyzing a number, 299–302, 318–319 C++/CLI, 315–320 expressions, evaluating, 295–298, 316–317 extending the program, 304–305 project description, 291–294 returning values from terms, 298–299, 318 running the program, 307–308 source code, 302–303 strings extracting substrings, 305–307, 319–320 removing blanks, 294–295, 316

1143

Index

calculator example

call stack, debugging call stack, debugging, 585–587 calling functions counting calls, 260 process description, 235–239 recursively, 262–265 Cancel button, visibility, 993–994 canceling database update, 980–982, 982–984, 997–998 CancelUpdate() function, 980–982 CArchive class, serialization, 870–871 caret (^), exclusive OR, 85 CArray template class, 761–763 case labels, 130 casting types in assignment statements, 79–80 C++/CLI, 108–109 definition, 78 explicit casts, 80–81 old-style casts, 81 rules for, 78–79 safe_cast operation, 108–109 variables in assignment statements, 79–80 definition, 78 explicit casts, 80–81 old-style casts, 81 rules for, 78–79 catch blocks, 281–282 catching exceptions C++/CLI, 308–309 example, 280–281 CBox class analyzing objects, 441–445 class implementation, 444 combining objects, 439–441 comparing objects, 438–439 defining the constructor, 447–448 data members, 446–447 function members, 448–453 global functions, 453–455 source code, 437–438 using, 455–458 CCircle class, 744–746 CCurve class defining, 775–777 drawing curves, 746 exercising, 778–779 implementing, 777––778

1144

CDatabase class, 930–931, 983–984 CDBException class, 930–931 C D C class, 712–720 CEditView class, 660 CElement class, 736–737 cells, database tables alignment, 1100 background color, 1099–1100 buttons, 1095 CellStyle property, 1109 ColumnIndex property, 1109 default styles, 1101–1108 DesiredType property, 1109 dynamic styles, 1108–1114 fonts, 1099–1100 foreground color, 1099–1100 formatting, 1100 FormattingApplied property, 1109 header, customizing, 1101 highlighting on mouseover, 1110–1114 images, 1096 non-header, customizing, 1101–1108 padding, 1100 properties, 1109 RowIndex property, 1109 selection color, 1099–1100 Value property, 1109 wrapping text, 1100 CellStyle property, 1109 CFieldExchange class, 930–931 CFormView class, 660 CFrameWnd class, 642 CHAR data type, 618 character arrays, 166–169 character data type, 55–56 check boxes, in cells, 1095 child windows, 615 CHtmlEditView class, 660 CHtmlView class, 660 circles, drawing Arc() function, 715–717 CCircle class, 744–746 Ellipse() function, 715–717 with the mouse, 722–723, 744–746 class constructors adding to a class, 343–345 copy, 356–358 copy constructors, 356–358, 405–407, 490–495 default, 345–347 default parameter values, assigning, 347–349

defining, example, 447–448 definition, 343 derived classes, 482–486 initialization lists, 350 no-arg, 345–347 reference class, 549–551 class destructors calling the wrong one, 511–516 default, 400 definition, 399–400 dynamic memory allocation, 402–405 example, 400–402 virtual, 511–516 class interface, 436 class libraries, creating, 532–535 class objects. See also class constructors; class destructors. arrays of, 363–364 declaring, 336–337 definition, 335 pointers to, 368–371 protecting, 360–361 references to, 371–372 class templates creating objects from, 431–433 defining, 428–431 definition, 427 instantiating, 427–428 with multiple parameters, 434–436 template member functions, 430–431 Class View, 10, 17 classes. See also CBox class; class constructors; class destructors; collection classes; inheritance. :: (colons), scope resolution operator, 341–342 abstract, 505–508 access control, 336, 479–482, 489–490 application, 653 base accessing private members, 480–482 definition, 475–476 deriving classes from, 476–479 direct, 475–476 indirect, 475–476, 508–511 pointers to, 501–503 CArray template, 761–763 CBox analyzing objects, 441–445 class implementation, 444

combining objects, 439–441 comparing objects, 438–439 defining the constructor, 447–448 data members, 446–447 function members, 448–453 global functions, 453–455 source code, 437–438 using, 455–458 CCircle, 744–746 CCurve defining, 775–777 drawing curves, 746 exercising, 778–779 implementing, 777––778 CDatabase, 930–931, 983–984 CDBException, 930–931 CDC, 712–720 CEditView, 660 CElement, 736–737 CFieldExchange, 930–931 CFormView, 660 CFrameWnd, 642 CHtmlEditView, 660 CHtmlView, 660 CLine, 737–741 CList template, 774–775. See also curves, drawing. arguments, 773–774 CCurve class, 775–779 description, 763–768 CListView, 660 CMap template, 768–771 CMyApp, 653–654 CMyDoc, 653–654 CMyView, 653–654 CMyWnd, 653–654 copying, 356–358 CPrintInfo, 886 CRecordset, 930–931 CRecordView, 930–931 CRectangle, 742–743 CRichEditView, 660 CScrollView, 660 CString, 858–859 CText, 861–862 CTreeView, 660 CTypedPtrList, 771 CView, 660

1145

Index

classes

classes (continued) classes (continued) CWinApp, 641–642 data members accessing, 337–339 definition, 335–336 private, 350–353 static, 365–367 Debug, 602–611 defining, 336 definition, 335 derived. See also inheritance. from base classes, 476–479 constructors, 482–486 copy constructors, 490–495 creating, 476–479 definition, 475 pointers to, 501–503 reference classes, C++/CLI, 524–526 value classes, C++/CLI, 520–526 document, 653 encapsulation, 335 fields, 336 frame window, 653 friend, 495–496 friend functions, 354–356 generic collection classes, 555–561 defining, 551–552 Dictionary, generic dictionary, 558 interface classes, 554–555 LinkedList, generic doubly linked list, 557 List, generic list, 556–557 using, 552–561 history of, 334 incomplete definitions, 504 inline functions, 342–343 instances counting, 366–367 definition, 335 instantiation, 335 interface, 526–531 member functions adding to a class, 339–341 defined outside the class, 362–363 definition, 335–336 positioning, 341–342 protecting, 361–362 static, 367–368

1146

members, 335–336 nesting, 516–519 OOP (object-oriented programming), 335 operations, 334–335 overview, 332–334 private members, 350–353 properties default indexed, 388 definition, 381 indexed, 381, 388–393 named indexed, 388 read-only, 381 reserved names, 394 scalar, 381, 382–388 static, 393–394 trivial scalar, 384–388 write-only, 381 protected class members, 486–489 serialization, 874 System::Data::DataColumn, 1090 System::Data::DataRow, 1090 System::Data::DataSet, 1090 System::Data::DataTable, 1090 this pointer, 358–360 Trace, 602–611 unions, 410 view, 653, 711–712, 954–957 virtual destructors, 511–516 virtual functions definition, 499 description, 497–501 pure, 505 references with, 503–504 classes, C++/CLI class properties default indexed, 388 definition, 381 indexed, 381, 388–393 named indexed, 388 read-only, 381 reserved names, 394 scalar, 381, 382–388 static, 393–394 trivial scalar, 384–388 write-only, 381 initonly fields, 394–395 literal fields, 377–378. See also initonly fields. operator overloading -- (minus signs), decrement operator, 467 ++ (plus signs), increment operator, 467

in reference classes, 467–470 in value classes, 461–466 reference class types, defining, 378–381 static constructors, 396 ToString() function, 376–377 value classes defining, 373–378 deriving, 520–526 overloading, 461–466 Clear() function, 1094 CLI (Common Language Infrastructure), 2 client area definition, 615 drawing, 634–636 redrawing, 731–732 client coordinates, 789–792 CLine class, 737–741 CList template class, 763–768. See also curves, drawing. arguments, 773–774 CCurve class defining, 775–777 exercising, 778–779 implementing, 777––778 drawing curves, 774–775 CListView class, 660 CLR (Common Language Runtime). See also C++/CLI programs. console applications description, 6 sample project, 24–27 description, 2–3 CMap template class, 768–771 CMyApp class, 653–654 CMyDoc class, 653–654 CMyView class, 653–654 C M y W n d class, 653–654 CObject-based classes, serialization, 872 collection classes. See also classes. arrays CArray template class, 761–763 collections of objects, 761–763 definition, 760 collections of objects arrays, 761–763 CArray template class, 761–763 CList template class, 763–768 CMap template class, 768–771 helper functions, 761–763 lists, 763–768

definition, 759–760 generic, 555–561 lists AddHead() function, 764–766 adding elements, 764–766 AddTail() function, 764–766 CList template class, 763–768 CompareElements() function, 767 ConstructElements() function, 768 counting elements, 773 definition, 760 deleting elements, 767–768 DestructElements() function, 768 empty, verifying, 773 Find() function, 766–767 GetHeadPosition() function, 766 GetTailPosition() function, 766 helper functions, 768 InsertAfter() function, 765–766 InsertBefore() function, 765–766 iterating through, 766 pointers to elements, 772–773 RemoveHead() function, 767–768 RemoveTail() function, 767–768 removing elements, 772–773 searching, 766–767 searching for pointers, 773 maps CMap template class, 768–771 definition, 760 hashing addresses, 768–769 HashKey() function, 770–771 helper functions, 770 LookUp() function, 769 retrieving objects from, 769 storing objects in, 769 shapes, 760 typed pointers AddHead() function, 772 AddTail() function, 772 CTypedPtrList class, 771 CTypedPtrList operators, 771–773 Find() function, 773 FindIndex() function, 773 GetAt() function, 772 GetCount() function, 773 GetHead() function, 772 GetHeadPos() function, 773 GetNext() function, 772 GetPrev() function, 772

1147

Index

collection classes

collection classes (continued) collection classes (continued) typed pointers GetTail() function, 772 GetTailPos() function, 773 InsertAfter() function, 773 InsertBefore() function, 773 IsEmpty() function, 773 RemoveAll() function, 772 RemoveAt() function, 773 RemoveHead() function, 772 RemoveTail() function, 772 SetAt() function, 773 types of collection, 760 type-safe handling, 760–761 collections of objects arrays, 761–763 CArray template class, 761–763 CList template class, 763–768 CMap template class, 768–771 helper functions, 761–763 lists, 763–768 colons (::), scope resolution operator classes, 341–342 definition, 26 example, 93–94 color BackColor property, 1099–1100 background, cells, 1099–1100 drawing in, 717–721 ForeColor property, 1099–1100 foreground, cells, 1099–1100 pen, 747–748 selected cells, 1099–1100 SelectionBackColor property, 1099–1100 SelectionForeColor property, 1099–1100 column types, 1095–1099 ColumnIndex property, 1109 columns, database tables adding, 1096 binding to controls, 1123–1127 buttons in cells, 1095 check boxes, 1095 defining, 1093–1099 drop-down lists, 1096 editing, 1096–1098 images in cells, 1096 links, displaying, 1096 width, setting, 1098–1099 combo boxes, 819, 1068–1070, 1072 ComboBox control, 1068–1070, 1072

1148

comma (,), expression separator, 76–77 command line output, 63–64, 104 command line pointer, 622 COMMAND messages, 689 command messages, 682–683 command update handler, 697–699 comments, 44–45 CommitTrans() function, 983–984 common controls, 819 Common Language Infrastructure (CLI), 2 Common Language Runtime (CLR). See CLR (Common Language Runtime). Common Type System (CTS), 3 CompareElements() function, 767 comparing values. See also loops. && (ampersands), logical AND, 125 ! (exclamation mark), logical NOT, 126 || (vertical bars), logical OR, 125–126 case labels, 130 C++/CLI, 150–156 conditional operator, 127–129 if statement description, 117–118 extended, 120–122 nesting, 118–120 if-else statement, nesting, 122–124 logical operators, 124–127 loops for, 133–139 continue statement, 139–140 definition, 132–133 do-while, 146–147 for each, 153–156 floating-point counters, 143 infinite, 137–139 multiple counters, 136–137 nesting, 147–150 non-integer counters, 140–143 while, 143–145 member access operators, 153 relational operators, 115–116 switch statement, 129–131 unconditional branching, 132 compiler, IDE, 9 compound statements, 49–50 conditional operator, 127–129 configurations, IDE, 19

console applications automatic generation, 50–51 CLR description, 6 sample projects, 24–27, 101–104 description, 6 sample project, 21–23 Win32 description, 6 sample project, 13–21 const modifier description, 70–71 function parameters, 249–250 member functions, 361–362 member functions defined outside the class, 362–363 objects, 360–361 constant pointers, 183–185 constants. See initonly fields; literal fields. constants, pointers to, 183–185 ConstructElements() function, 768 constructors. See class constructors. context menus associating with classes, 795–796 checking items, 800–802 choosing, 797–802 creating, 794–795 deleting elements, 807–808 drawing highlighted elements, 806–807 highlighting elements, 802–806 identifying selected elements, 798–800 masked elements, 814–815 moving elements, 808–814 positioning elements, 813–814 servicing menu messages, 807–814 Windows Forms creating, 1049 responding to, 1079–1086 WM_MOUSEMOVE handler, 810–811 ContextMenuStrip control, 1049 Context-sensitive help option, 659 continue statement, 139–140 ContinueRouting() method, 698 control menu, 616 control notification messages, 681 ControlBox property, 1068 controls. See also dialog boxes. adding to dialog boxes, 820–822 appearance, 1102–1103

buttons in cells, 1095 clicks, handling, 1076–1079, 1083–1086 definition, 819 illustration, 819 labels, changing, 992–993 movement, detecting, 725 categories of, 819 column format, 1106–1108 column headers, 1105–1106 combo boxes, 819 common, 819 database appearance, 1102–1103 binding to columns, 1123–1127 binding to data sources, 1115–1120 column format, 1106–1108 column headers, 1105–1106 setting up, 1103–1104 database update button label, changing, 992–993 Cancel button, visibility, 993–994 canceling the update, 997–998 description, 990–991 edit controls, enabling/disabling, 991–992 expediting the update, 996–997 Record menu, disabling, 994–996 edit boxes creating, 856–857 creating text elements, 863–865 creating the dialog classes, 858–859 CString class, 858–859 CText class, 861–862 definition, 819 drawing CText objects, 862 illustration, 819 moving CText objects, 862 text elements, defining, 860–862 Text menu item, 859–860 group boxes, 821–822 horizontal guides, 821 illustration, 819 linking to recordsets, 946–948 list boxes creating, 853–855 creating the dialog class, 854–855 definition, 819 displaying, 855 illustration, 819 scaling, 852–853

1149

Index

controls

controls (continued) controls (continued) positioning, 822 scrollbars, 819 setting up, 1103–1104 spin buttons creating, 835–837 dialog data exchange, 840 displaying, 841–842 initializing the dialog, 840–841 scale dialog class, 838–841 scale menu item, 835 scale toolbar button, 835 scaling, 835 validation, 840 static, 819 tab sequence, 838 testing, 822 cooperative mulltitasking, 629–630 coordinate systems client coordinates, 789–792, 843 device coordinates, 843 drawing, 708 logical coordinates, 789–790 page coordinates, 843 screen coordinates, 843 copy class constructors, 356–358 copy constructors, 405–407, 490–495 copying classes, 356–358 rows, 1094 CPrintInfo class, 886 CreateElement() function, 751–753 CRecordset class, 930–931 CRecordset operations, 980–982 CRecordView class, 930–931 CRectangle class, 742–743 CRichEditView class, 660 _CRTDBG... control bits, 595–596 _crtDbgFlag flag, 595 crtdbg.h header, 594–595 CrtSetReportFile() function, 596–597 CrtSetReportMode() function, 596–597 CScrollView class, 660 CString class, 858–859 CText class, 861–862 CTreeView class, 660 Ctrl key detection, 728 CTS (Common Type System), 3

1150

CTypedPtrList class, 771 CTypedPtrList operators, 771–773 curly braces ({ }), function syntax, 46 current position, 713 CurrentPosition() function, 1121 cursor position, recording, 729–731 curves, drawing CCurve class defining, 775–777 drawing curves, 746 exercising, 778–779 implementing, 777––778 CList template class, 774–775 example, 723–724 CView class, 660 CWinApp class, 641–642

D dash-dot lines, 718 dashed lines, 718 data, displaying. See DataGridView control. data members accessing, 337–339 defining, example, 446–447 definition, 335–336 private, 350–353 static, 365–367 data sources. See databases. data types. See also variables. fundamental. See also Boolean variables. bool, 57 Boolean variables, 57 boxing, 101 C++/CLI, 99–104, 109–111 char, 55–56 character, 55–56 const modifier, 70–71 double, 58 enumeration constants, 62, 109–111 float, 58 floating-point, 57–58 int, 54 integer type modifiers, 56–57 integer variables, 54–55 literals, 59 long, 55

long double, 58 minimum/maximum values, 56–57 short, 54 signed modifier, 56–57 summary of, 58–59 synonyms for, 60 true/false, 57 typedef keyword, 60 unboxing, 101 wchar_t, 56 wide character, 56 Windows programs BOOLEAN, 618 BYTE, 618 CHAR, 618 CTS (Common Type System), 3 DWORD, 618 HANDLE, 618 HBRUSH, 618 HCURSOR, 618 HDC, 618 HINSTANCE, 618 LPARAM, 619 LPCSTR, 619 LPHANDLE, 619 LRESULT, 619 overview, 332–334 WORD, 619 database applications, creating dynaset recordsets, 935–936 generating an MFC ODBC program, 933–936 program structure database/recordset data transfer, 940–941 DDX_FieldText() function, 946–948 DoFieldExchange() function, 940–941 linking controls to recordsets, 946–948 querying the database, 938–940 record view, 941–943 recordsets, 937–941 RFX_() function, 941 view dialog, creating, 943–946 registering an ODBC database, 931–933 snapshot recordsets, 935–936 database applications, Windows Forms accessing data, 1090–1091 AddNew() function, 1121 BindingNavigator control, 1120–1123 BindingSource component, 1115–1120 bound mode, 1114–1115

cells alignment, 1100 background color, 1099–1100 buttons, 1095 CellStyle property, 1109 ColumnIndex property, 1109 default styles, 1101–1108 DesiredType property, 1109 dynamic styles, 1108–1114 fonts, 1099–1100 foreground color, 1099–1100 formatting, 1100 FormattingApplied property, 1109 header, customizing, 1101 highlighting on mouseover, 1110–1114 images, 1096 non-header, customizing, 1101–1108 padding, 1100 properties, 1109 RowIndex property, 1109 selection color, 1099–1100 Value property, 1109 wrapping text, 1100 columns adding, 1096 binding to controls, 1123–1127 buttons in cells, 1095 check boxes, 1095 defining, 1093–1099 drop-down lists, 1096 editing, 1096–1098 images in cells, 1096 links, displaying, 1096 width, setting, 1098–1099 controls appearance, 1102–1103 binding to columns, 1123–1127 binding to data sources, 1115–1120 column format, 1106–1108 column headers, 1105–1106 setting up, 1103–1104 CurrentPosition() function, 1121 data source classes, 1090 DataGridView control Add() function, 1094 AddCopy() function, 1094 bound mode, 1093 Clear() function, 1094 column types, 1095–1099

1151

Index

database applications, Windows Forms

database applications, Windows Forms (continued) database applications, Windows Forms (continued) DataGridView control DataGridViewButtonColumn column, 1095 DataGridViewCheckBoxColumn column, 1095 DataGridViewComboBoxColumn column, 1096 DataGridViewImageColumn column, 1096 DataGridViewLinkColumn column, 1096 definition, 1090 displaying data, 1091–1093 Insert() function, 1094 InsertCopy() function, 1094 modes, 1092–1099 Remove() function, 1094 RemoveAt() function, 1094 unbound mode, 1093–1099 virtual mode, 1093 DataGridView control, customizing Alignment property, 1100 databases. See also DataGridView control. customer details dialog resource, 968 filter parameters, 972–973 filters, 970–972 linking dialogs, 973–975 recordset, 967 view class, 968–970 fields, 922 keys, 923 MFC support for CDatabase class, 930–931 CDBException class, 930–931 CFieldExchange class, 930–931 classes, 930–931 CRecordset class, 930–931 CRecordView class, 930–931 ODBC approach, 929–930 OLE DB approach, 929–930 m_strSort() function, 948 overview, 922–924 primary keys, 923 RDBMS (relational database management systems), 923 records, 922 recordsets description, 937–941 dynaset, 935–936 snapshot, 935–936 sorting, 948–950

1152

recordsets, second object customizing, 957–961 dialog resources, creating, 954–955 filter parameters, defining, 958–960 filters, adding, 958 initializing record view, 960–961 m_strFilter() function, 958 multiple table views, 961–966 OnActiveView() function, 965–966 recordset class, adding, 950–954 switching views, 961–965 view activation, 965–966 view class, adding, 954–957 viewing product orders, 966–967 relational, 921 SQL choosing records, 925–926 joining tables, 926–928 retrieving data, 924–926 sorting records, 929 tables, 922 window caption, modifying, 949–950 databases, updating adding records, 980–982 adding rows to tables adding orders, 1023–1028 dialog switching, 1010–1014 order data, storing, 1019–1021 order entry process, 1000–1001 order IDs, creating, 1014–1019 overview, 999–1000 recordsets, creating, 1002 recordsets views, creating, 1002–1006 resources, adding controls, 1006–1010 resources, creating, 1001 selecting products, 1021–1023 setting dates, 1020–1021 AddNew() function, 980–982 BeginTrans() function, 983–984 canceling updates, 980–982, 997–998 CancelUpdate() function, 980–982 CDatabase class, 983–984 CommitTrans() function, 983–984 completing an update, 980–982 controls button label, changing, 992–993 Cancel button, visibility, 993–994 canceling the update, 997–998

description, 990–991 edit controls, enabling/disabling, 991–992 expediting the update, 996–997 Record menu, disabling, 994–996 CRecordset operations, 980–982 Delete() function, 980–982 deleting records, 980–982 Edit() function, 980–982 editing records, 980–982 example, 984–988 inhibiting update, 988–990 optimistic record locking, 982 pessimistic record locking, 982 record locking, 982 Rollback() function, 983–984 rolling back an update, 982–984 starting an update, 988–990 tables, adding rows to adding orders, 1023–1028 dialog switching, 1010–1014 order data, storing, 1019–1021 order entry process, 1000–1001 order IDs, creating, 1014–1019 overview, 999–1000 recordsets, creating, 1002 recordsets views, creating, 1002–1006 resources, adding controls, 1006–1010 resources, creating, 1001 selecting products, 1021–1023 setting dates, 1020–1021 transactions, 982–984 Update() function, 980–982 update mode button label, changing, 992–993 Cancel button, visibility, 993–994 canceling the update, 997–998 description, 990–991 edit controls, enabling/disabling, 991–992 expediting the update, 996–997 Record menu, disabling, 994–996 validating operations, 981 DataGridView control Add() function, 1094 AddCopy() function, 1094 bound mode, 1093 Clear() function, 1094 column types, 1095–1099

customizing Alignment property, 1100 AlternatingRowsDefaultCellStyle property, 1101 BackColor property, 1099–1100 DataGridViewCellStyle object, 1099–1100 DefaultCellStyle property, 1101 Font property, 1099–1100 ForeColor property, 1099–1100 Format property, 1100 InheritedStyle property, 1100–1101 Padding property, 1100 RowsDefaultCellStyle property, 1101 SelectionBackColor property, 1099–1100 SelectionForeColor property, 1099–1100 Style property, 1101 System::Collections::Ilist interface, 1114 System::ComponentModel::BindingList interface, 1114 System::ComponentModel::BindingListView interface, 1114 System::ComponentModel::IlistSource interface, 1114 WrapMode property, 1100 DataGridViewButtonColumn column, 1095 DataGridViewCheckBoxColumn column, 1095 DataGridViewComboBoxColumn column, 1096 DataGridViewImageColumn column, 1096 DataGridViewLinkColumn column, 1096 definition, 1091 displaying data, 1091–1093 Insert() function, 1094 InsertCopy() function, 1094 modes, 1092–1099 Remove() function, 1094 RemoveAt() function, 1094 unbound mode, 1093–1099 virtual mode, 1093 DataGridViewButtonColumn column, 1095 DataGridViewCellStyle object, 1099–1100 DataGridViewCheckBoxColumn column, 1095 DataGridViewComboBoxColumn column, 1096 DataGridViewImageColumn column, 1096 DataGridViewLinkColumn column, 1096 DDX_FieldText() function, 946–948 Debug class, 602–611 Debug configuration, 570

1153

Index

Debug configuration

debugger debugger definition, 568 starting, 570, 573–576 windows, 575 debugging. See also bugs. adding code for, 578–585 assert() function, 578–580 assertions, 578–580 basic operations, 568–570 breakpoints, 570–572 call stack, 585–587 C++/CLI Assert() function, 607–608 assertions, 607–608 controlling output, 605–607 Debug class, 602–611 generating output, 603–604 Indent() function, 604–605 indenting output, 604–605 listeners, 604 output destination, 604 Trace class, 602–611 trace switches, 605–607 Unindent() function, 604–605 Write() function, 603–604 WriteIf() function, 603–604 WriteLine() function, 603–604 WriteLineIf() function, 603–604 changing variables, 577–578 _CRTDBG... control bits, 595–596 _crtDbgFlag flag, 595 crtdbg.h header, 594–595 CrtSetReportFile() function, 596–597 CrtSetReportMode() function, 596–597 definition, 565 description, 565–566 dynamic memory, 593–601 finding the next bug, 593 free store operations, 594–601 in IDE, 19–23 #ifdef/#endif directives, 580–581 inspecting variables, 576–577 memory leaks, 594–601 NDEBUG symbol, 578–579 null pointers, 576 setting a watch, 576 stepping through code, 587–590 testing the extended class, 591–593 tracepoints, 572–573 DECLARE_DYNAMIC() macro, 872

1154

DECLARE_DYNCREATE() macro, 869, 872 DECLARE_SERIAL() macro, 872 declaring pointers, 173–174 variables, 52–53, 91 _declspec keyword, 916–917 decoding windows messages, 633–636 decorated names, 912 decrementing variables, 74–76 default indexed properties, 388 DefaultCellStyle property, 1101 definition, 759–760 delegates calling, 540–541 creating, 537–541 declaring, 537 definition, 536 unbound, 541–545 Delete() function, 980–982 delete operator, 193 deleting context menu elements, 807–808 database records, 980–982 list elements, 767–768 rows, 1094 shapes from documents, 793–794 de-referencing pointers, 174 derived classes from base classes, 476–479 class constructors, 482–486 constructors, 482–486 copy constructors, 490–495 creating, 476–479 definition, 475 pointers to, 501–503 reference classes, C++/CLI, 524–526 value classes, C++/CLI, 520–526 DesiredType property, 1109 DestructElements() function, 768 device context, 634–636, 709, 893 Dialog based option, 657–658 dialog boxes adding, 820–822 adding a class, 823–824 closing, 827 controls adding, 820–822 enabling, 831 initializing, 828–830

radio button messages, 830–831 creating elements, 833–834 description, 817–818 displaying, 824–827 enabling, 831 illustration, 818 initializing, 828–830 linking, 973–975 modal, 824 modeless, 824 pen widths, 832–833 radio button messages, 830–831 scale factor document size, 844 mapping mode, 844–846 scaleable mapping modes, 842–844 scrolling, 846–848 scrollbars, 847–848 status bars adding to frames, 848–850 overview, 848 parts of, 850–851 updating, 851––852 testing, 822, 834–835 Windows Forms adding, 1068–1075 button clicks, handling, 1076–1079, 1083–1086 ComboBox control, 1068–1070, 1072 context menu, responding to, 1079–1086 ControlBox property, 1068 creating, 1056–1062 DialogResult property, 1057, 1063–1066 event handler, Reset menu, 1067–1068 FormBorderStyle property, 1068 getting data from, 1070–1073 Help > About menu, 1075–1076 input controls, disabling, 1073–1074 Limits menu, 1074–1075 MaximizeBox property, 1068 MinimizeBox property, 1068 NumericUpDown control, 1068–1070, 1073 Show() function, 1062–1066 ShowDialog() function, 1062–1063 Text property, 1068 using, 1062–1068 validating input, 1063–1066 dialog button events, 1058–1060 dialog objects, creating, 1061–1062

DialogResult property, 1057, 1063–1066 Dictionary, generic dictionary, 558 direct base classes, 475–476 display content, 634–636 displaying data. See DataGridView control. displaying graphics, 713–717 dllexport attribute, 916–917 DllMain() function, 906, 910–911 DLLs (dynamic link libraries) AFX_EXT_CLASS keyword, 912–913, 916 contents choosing, 907–908 description, 906 _declspec keyword, 916–917 decorated names, 912 dllexport attribute, 916–917 DllMain() function, 906 early binding, 904–906 exporting symbols, 917–920 variables and functions, 916–917 functional description, 903–906 importing symbols, 917 interface, 906, 913 late binding, 904–906 load-time dynamic linking, 904–906 MFC extension, 906–907 ordinals, 912 overview, 901–903 regular, dynamically linked, 907 regular, statically linked, 907 run-time dynamic linking, 904–906 varieties, 906–907 writing extension DLLs adding classes, 911–912 building DLLs, 914 DllMain() function, 910–911 example, 914–915 exporting classes, 912–913 overview, 908–910 required files, 915–916 docking toolbars, 12 document class, 653 document interfaces, MFC, 650 documentation, IDE, 12–13 documents. See also printing documents; serialization; views. context menus

1155

Index

documentation, IDE

documents associating with classes, 795–796 checking items, 800–802 choosing, 797–802 creating, 794–795 deleting elements, 807–808 drawing highlighted elements, 806–807 highlighting elements, 802–806 identifying selected elements, 798–800 masked elements, 814–815 moving elements, 808–814 positioning elements, 813–814 servicing menu messages, 807–814 WM_MOUSEMOVE handler, 810–811 creating adding elements, 783–784 CTypedPtrList template, 779–784 document destructor, 780–781 drawing the document, 781–783 OnDraw() function, 781–783 pointers to shape classes, 779–784 RectVisible() function, 783 definition, 650 deleting shapes, 793–794 linking to views, 652–653 moving shapes, 793–794 moving text, 882–883 pen widths, 832–833 recording changes, 874–876 size, getting, 889–890 size, scale factor, 844 template classes, 653 templates, 652–653 Document/View architecture support option, 657–658 DoFieldExchange() function, 940–941 dotted lines, 718 double data type, 58 double quotes (“...”), special character indicator, 65 do-while loops, 146–147 Draw() function, 738–739 drawing in windows alternating dash-dot lines, 718 Arc() function, 716–717 brushes, 719–721 CDC class, 712–720

1156

circles Arc() function, 715–717 CCircle class, 744–746 Ellipse() function, 715–717 with the mouse, 722–723, 744–746 in color, 717–721 coordinate system, 708 current position, 713 curves CCurve class, 746, 775––778, 778–779 CList template class, 774–775 example, 723–724 dashed lines, 718 device context, 709 displaying graphics, 713–717 dotted lines, 718 GDI (Graphical Device Interface), 709–711 hatching, 719–720 HS_BDIAGONAL hatching, 720 HS_CROSS hatching, 720 HS_DIAGCROSS hatching, 720 HS_FDIAGONAL hatching, 720 HS_HORIZONTAL hatching, 720 HS_VERTICAL hatching, 720 inside a frame, 718 lines alternating dash-dot, 718 CLine class, 737–741 dashed, 718 dotted, 718 LineTo() function, 714–715 with the mouse, 737–741 solid, 718 straight, 714–715 LineTo() function, 714–715 mapping modes, 709–711 MM_ANISOTROPIC mapping mode, 710–711 MM_HIENGLISH mapping mode, 709–711 MM_HIMETRIC mapping mode, 709–711 MM_ISOTROPIC mapping mode, 709–711 MM_LOENGLISH mapping mode, 709–711 MM_LOMETRIC mapping mode, 709–711 MM_TEXT mapping mode, 709–711 MM_TWIPS mapping mode, 710–711 mouse black-and-white, 747 bounding rectangles, 739–741 button movement, detection, 725

CCircle class, 744–746 CCurve class, 746 CElement class, 736–737 circles, 744–746 CLine class, 737–741 CreateElement() function, 751–753 creating elements, 751–753 CRectangle class, 742–743 Ctrl key detection, 728 cursor position, recording, 729–731 curves, 746 Draw() function, 738–739 drawing mode, 747–749 element classes, 732–736 Ellipse() function, 745–746 InvalidateRect() function, 731–732 left button detection, 725, 728 lines, 737–741 message handlers, 727–729, 747–753 messages, capturing, 755–756 messages, types of, 725–727 middle button detection, 728 MK_CONTROL flag, 728–729 MK_LBUTTON flag, 728–729 MK_MBUTTON flag, 728–729 MK_RBUTTON flag, 728–729 MK_SHIFT flag, 728–729 movement, handling, 749–751 normalized rectangles, 741 OnMouseMove() handler, 749–751 pen color, 747–748 R2_BLACK mode, 747–748 R2_COPYPEN mode, 747–748 R2_MASKNOTOPEN mode, 748 R2_MASKPEN mode, 748 R2_MASKPENNOT mode, 747–748 R2_MERGENOTOPEN mode, 747–748 R2_MERGEPEN mode, 748 R2_MERGEPENNOT mode, 747–748 R2_NOP mode, 747–748 R2_NOT mode, 747–748 R2_NOTCOPYPEN mode, 747–748 R2_NOTMASKPEN mode, 748 R2_NOTMERGEPEN mode, 748 R2_NOTXORPEN mode, 748 R2_WHITE mode, 747–748 R2_XORPEN mode, 748 Rectangle() function, 743

rectangles, 739–741, 742–743 redrawing the client area, 731–732 ReleaseCapture() function, 755–756 right button detection, 728 rubberbanding, 747, 750 SetCapture() function, 755–756 SetROP2() function, 747–750 Shift key detection, 728 temporary element storage, 734–736 update region, 731 WM_LBUTTONDOWN message, 725–726 WM_LBUTTONUP message, 725, 727, 753 WM_MOUSEMOVE message, 725, 726–727 OnDraw() function, 711–712 pen objects, 717–719 positioning the drawing, 708 PS_DASH pen style, 718 PS_DASHDOT pen style, 718 PS_DASHDOTDOT pen style, 718 PS_DOT pen style, 718 PS_INSIDEFRAME pen style, 718 PS_NULL pen style, 718 PS_SOLID pen style, 718 rectangles, 722, 724 rectangles, with the mouse bounding rectangles, 739–741 CRectangle class, 742–743 normalized rectangles, 741 Rectangle() function, 743 rectangles, 722, 724, 739–741, 742–743 solid lines, 718 view class, 711–712 window client area, 708 WM_PAINT message, 708, 711, 731, 754–755 drawing mode, 747–749 drop-down lists, in cells, 1096 d w prefix, 619–620 DWORD data type, 618 dynamic link libraries (DLLs). See DLLs. dynamic memory, debugging, 593–601 dynamic memory allocation. See also free store. allocating, 193 C++/CLI arrays of arrays, 213–216 CLR arrays, 200–205 freeing memory, 198–199 garbage collection, 198–199 handles, 199–200

1157

Index

dynamic memory allocation

dynamic memory allocation (continued) dynamic memory allocation (continued) C++/CLI jagged arrays, 213–216 multidimensional arrays, 209–213 searching one-dimensional arrays, 206–209 sorting one-dimensional arrays, 205–206 string handling, 216–225 tracking handles, 199–200 class destructors, 402–405 delete operator, 193 free store definition, 192–193 example, 194–196 freeing, 193 handling allocation errors, 284–285 multidimensional arrays, 196–197 new operator, 193, 284–285 one-dimensional arrays, 194–196 references. See also pointers; tracking references. declaring, 197–198 definition, 197 initializing, 197–198 dynamic_cast operator, 516 dynaset recordsets, 935–936

E early binding, 904–906 edit boxes creating, 856–857 CString class, 858–859 CText class, 861–862 definition, 819 dialog classes, creating, 858–859 drawing CText objects, 862 illustration, 819 moving CText objects, 862 text elements, creating, 863–865 text elements, defining, 860–862 Text menu item, 859–860 Edit() function, 980–982 editing columns, 1096–1098 database records, 980–982 editor, IDE, 9 Editor tab, 10 element classes, 732–736, 877–879

1158

elements, of arrays, 160 Ellipse() function, 745–746 Enable() method, 698 encapsulation, 335 EndsWith() function, 222–225 enumeration, 60–62 enumeration constants, 62, 109–111 equal sign (=), assignment operator, overloading, 418–422 equal signs (==), relational operator, 115–116 error handling, 23–24. See also exceptions. escape sequences, 65–67 event handlers dialog button, 1058–1060 menu items, 1049–1056 Reset menu, 1067–1068 event-driven applications, 7 Windows programs, 617 events creating, 545–546 definition, 536 handling, 547–548 Windows applications, 7 exceptions. See also error handling. catch blocks, 281–282 catching C++/CLI, 308–309 example, 280–281 C++/CLI, 308–309 definition, 279–280 in the MFC, 283 throwing C++/CLI, 308–309 description, 281 example, 280–281 try blocks, 281–283 exclamation mark, equal sign (!=), relational operator, 115–116 exclamation mark (!), logical NOT, 126 .exe file extension, 19 executing programs, IDE, 20–21 explicit casts, 80–81 exporting classes from extension DLLs, 912–913 symbols from DLLs, 917–920 variables and functions from DLLs, 916–917

expressions casting in assignment statements, 79–80 definition, 78 explicit casts, 80–81 old-style casts, 81 rules for, 78–79 evaluating, 295–298, 316–317 mixed type, casting, 80–81 separating, 76–77 extension DLLs adding classes, 911–912 building DLLs, 914 DllMain() function, 910–911 example, 914–915 exporting classes, 912–913 overview, 908–910 required files, 915–916

F fields classes, 336 databases, 922 file scope. See global scope. filter parameters, databases, 958–960, 972–973 filters, databases, 958, 970–972 finalizers, 549–551 Find() function, 766–767, 773 FindIndex() function, 773 FixedDialog property, 1056–1062 float data type, 58 floating-point data types, 57–58 floating-point loop counters, 143 fn prefix, 619–620 Font property, 1099–1100 fonts, cells, 1099–1100 for each loops, 153–156 for loops, 133–139 ForeColor property, 1099–1100 foreground color, cells, 1099–1100 Format property, 1100 formatting cells, 1100 formatting output, 64–65, 104–107 FormattingApplied property, 1109 FormBorderStyle property, 1056–1062, 1068 forms. See Windows Forms.

frame window class, 653 frame windows, 642 free store debugging, 594–601 definition, 192–193 example, 194–196 freeing memory, 193, 198–199. See also garbage collection. friend classes, 495–496 friend functions, in classes, 354–356 function members. See member functions. function pointers as arguments, 275–277 arrays of as arguments, 277 declaring, 272–273 definition, 271–272 example, 273–275 functions { } (curly braces), function syntax, 46 Add(), 1094 AddCopy(), 1094 AddHead(), 764–766, 772 AddNew(), 980–982, 1121 AddTail(), 764–766, 772 Arc(), 716–717 arguments arrays as, 243–247 arrays of function pointers as, 277 definition, 232 function pointers as, 275–277 passing to main(), 250–252, 267–268 passing-by-pointer, 241–243 passing-by-reference, 247–249 passing-by-value, 240–241 pointer notation, 244–245 variable number of, 252–254, 266–267 Assert(), 578–580, 607–608 BeginTrans(), 983–984 body, 46, 234–235 calling, 235–239 calling, recursively, 262–265 calls, counting, 260 CancelUpdate(), 980–982 C++/CLI, 265–268, 309–315 Clear(), 1094 CommitTrans(), 983–984 CompareElements(), 767 ConstructElements(), 768

1159

Index

functions

functions (continued) functions (continued) CreateElement(), 751–753 CrtSetReportFile(), 596–597 CrtSetReportMode(), 596–597 CurrentPosition(), 1121 DDX_FieldText(), 946–948 Delete(), 980–982 description, 38 DestructElements(), 768 DllMain(), 906, 910–911 DoFieldExchange(), 940–941 Draw(), 738–739 Edit(), 980–982 Ellipse(), 745–746 EndsWith(), 222–225 executable statements, 46 Find(), 766–767, 773 FindIndex(), 773 generic, 309–315 GetAt(), 772 GetCount(), 773 GetFromPage(), 887 GetHead(), 772 GetHeadPos(), 773 GetHeadPosition(), 766 GetMaxPage(), 887 GetMinPage(), 887 GetNext(), 772 GetPrev(), 772 GetTail(), 772 GetTailPos(), 773 GetTailPosition(), 766 GetToPage(), 887 global variables, 260 HashKey(), 770–771 header, 233–234 Indent(), 604–605 inline, in classes, 342–343 Insert(), 1094 InsertAfter(), 765–766, 773 InsertBefore(), 765–766, 773 InsertCopy(), 1094 InvalidateRect(), 731–732 IsEmpty(), 773 LineTo(), 714–715 LookUp(), 769 main(), 46, 250–252, 267–268 MoveFirst(), 1121 MoveLast(), 1121

1160

MoveNext(), 1121 MovePrevious(), 1121 m_strFilter(), 958 new, 536 OnActiveView(), 965–966 OnDraw(), 711–712 OnUpdate(), 785–787 overloading, 285–288 parameters description, 232 initializing, 277–279 protecting, 249–250 prototypes, 235–239 Rectangle(), 743 recursive, 262–265 RegisterClassEx(), 625–627 ReleaseCapture(), 755–756 Remove(), 1094 RemoveAll(), 772 RemoveAt(), 773, 1094 RemoveCurrent(), 1121 RemoveHead(), 767–768, 772 RemoveTail(), 767–768, 772 return statement, 235 returning values from addresses, 256–257 bad pointers, 255–256 pointers, 254–257 references, 258–260 terms, 298–299, 318 RFX_(), 941 Rollback(), 983–984 Serialize() definition, 870 serializing documents, 876–877 shape classes, 879–881 SetAt(), 773 SetCapture(), 755–756 SetMaxPage(), 887 SetMinPage(), 887 SetROP2(), 747–750 Show(), 1062–1066 ShowDialog(), 1062–1063 StartsWith(), 222–225 static variables, 261–262 structure of, 233–235 templates, 288–291 ToString(), 376–377 TotalNumberofItems(), 1121

trim(), 220–221 Unindent(), 604–605 Update(), 980–982 UpdateAllViews(), 785–787 uses for, 233 using, 235–239 WINAPI(), 622 WindowProc(), 632–637 WinMain() arguments, 622 example, 631–632 hInstance argument, 622 hPrevInstance argument, 622 lpCmdLine argument, 622 nCmdShow argument, 622 prototype, 621 RegisterClassEx() function, 625–627 WINAPI() function, 622 WNDCLASSEX struct, 623–625 Write(), 103–104, 603–604 WriteIf(), 603–604 WriteLine(), 103–104, 603–604 WriteLineIf(), 603–604 functions, example (calculator) analyzing a number, 299–302, 318–319 C++/CLI, 315–320 expressions, evaluating, 295–298, 316–317 extending the program, 304–305 project description, 291–294 returning values from terms, 298–299, 318 running the program, 307–308 source code, 302–303 strings extracting substrings, 305–307, 319–320 removing blanks, 294–295, 316 fundamental data types. See also Boolean variables; data types. bool, 57 Boolean variables, 57 boxing, 101 C++/CLI, 99–104, 109–111 char, 55–56 character, 55–56 const modifier, 70–71 double, 58 enumeration constants, 62, 109–111 float, 58 floating-point, 57–58 int, 54

integer type modifiers, 56–57 integer variables, 54–55 literals, 59 long, 55 long double, 58 minimum/maximum values, 56–57 short, 54 signed modifier, 56–57 summary of, 58–59 synonyms for, 60 true/false, 57 typedef keyword, 60 unboxing, 101 wchar_t, 56 wide character, 56

G garbage collection, 198–199 GDI (Graphical Device Interface), 709–711 generic classes collection classes, 555–561 defining, 551–552 Dictionary, generic dictionary, 558 interface classes, 554–555 LinkedList, generic doubly linked list, 557 List, generic list, 556–557 using, 552–561 generic functions, 309–315 GetAt() function, 772 GetCount() function, 773 GetFromPage() function, 887 GetHead() function, 772 GetHeadPos() function, 773 GetHeadPosition() function, 766 GetMaxPage() function, 887 GetMinPage() function, 887 GetNext() function, 772 GetPrev() function, 772 GetTail() function, 772 GetTailPos() function, 773 GetTailPosition() function, 766 GetToPage() function, 887 global functions, defining, 453–455 global namespace scope. See global scope. global scope, 91–94 global variables, 260

1161

Index

global variables

Graphical Device Interface (GDI) Graphical Device Interface (GDI), 709–711 Graphical User Interface (GUI). See GUI (Graphical User Interface). graphics, displaying, 713–717 greater than, equal sign (>=), relational operator, 115–116 greater than (>) operator overloading, 415–417 OR, 84–85 relational operator, 115–116 group boxes, 821–822, 1042–1044 GroupBox control, 1042–1044 grouping controls, 821–822, 1042–1044 GUI (Graphical User Interface), Windows Forms Button control, 1044–1046 context menus, 1049 ContextMenuStrip control, 1049 dialog boxes adding, 1068–1075 button clicks, handling, 1076–1079, 1083–1086 ComboBox control, 1068–1070, 1072 context menu, responding to, 1079–1086 ControlBox property, 1068 creating, 1056–1062 DialogResult property, 1057, 1063–1066 event handler, Reset menu, 1067–1068 FormBorderStyle property, 1068 getting data from, 1070–1073 Help > About menu, 1075–1076 input controls, disabling, 1073–1074 Limits menu, 1074–1075 MaximizeBox property, 1068 MinimizeBox property, 1068 NumericUpDown control, 1068–1070, 1073 Show() function, 1062–1066 ShowDialog() function, 1062–1063 Text property, 1068 using, 1062–1068 validating input, 1063–1066 dialog button events, 1058–1060 dialog objects, creating, 1061–1062 event handler, dialog button, 1058–1060 event handlers, menu items, 1049–1056 FixedDialog property, 1056–1062 FormBorderStyle property, 1056–1062 GroupBox control, 1042–1044 grouping controls, 1042–1044

1162

list boxes, 1058–1061 menu items, event handlers, 1049–1056 menus, 1037–1038 overview, 1035–1036 submenus, 1038–1040 tab controls, 1040–1042 TabControl control, 1040–1042 testing, 1048–1049 Web browser controls, 1047–1048 WebBrowser control, 1047–1048

H h prefix, 619–620 HANDLE data type, 618 handles, 199–200, 622 hashing addresses, 768–769 HashKey() function, 770–771 hatching, 719–720 HBRUSH data type, 618 HCURSOR data type, 618 HDC data type, 618 headers cell, customizing, 1101 functions, 233–234 programs, 45 Help > About menu, 1075–1076 helper functions collections of objects, 761–763 lists, 768 maps, 770 highlighting cells on mouseover, 1110–1114 hInstance argument, 622 HINSTANCE data type, 618 horizontal guides, in controls, 821 hPrevInstance argument, 622 HS_BDIAGONAL hatching, 720 HS_CROSS hatching, 720 HS_DIAGCROSS hatching, 720 HS_FDIAGONAL hatching, 720 HS_HORIZONTAL hatching, 720 HS_VERTICAL hatching, 720 Hungarian notation MFC (Microsoft Foundation Classes), 640 Windows programs, 620

I iprefix, 619–620 .idb file extension, 19 IDE (Integrated Development Environment) :: (colons), scope resolution operator, 26 assemblies, 25 Class View, 10, 17 compiler, 9 components, 9 configurations, 19 debugging, 19–23 documentation, 12–13 Editor, 10 editor, 9 error handling, 23–24 executing programs, 20–21 file extensions, 19 libraries, 9 linker, 9 namespaces, 26 options, setting, 26 Output window, 10 project folder, 13 projects current settings, displaying, 14 defining, 13–19, 21–23 definition, 13 naming, 14 type of, displaying, 14 viewing, 16–17 projects, samples CLR console application, 24–27 empty console application, 21–23 Win32 console application, 13–21 Property Manager, 10, 16 release versions, 19–23 Resource View, 10, 16 Solution Explorer, 10, 16 solutions creating, 18–19 definition, 13 source code, modifying, 17–18 Standard C++ Library, 9 toolbar options, 10–12 toolbars, docking, 12 user interface, 10

Windows applications, creating and executing MFC, 28–31 Windows Forms, 31–35 identifiers, variables, 51–52 i f statement description, 117–118 extended, 120–122 nesting, 118–120 #ifdef/#endif directives, 580–581 if-else statement, nesting, 122–124 .ilk file extension, 19 images, in cells, 1096 IMPLEMENT_SERIAL() macro, 872–873 importing symbols into DLLs, 917 #include directive, 45 inclusive OR, 84–85 incomplete class definitions, 504 incrementing variables, 74–76 Indent() function, 604–605 indexed properties, 381, 388–393 indexing arrays, 160–161 indirect base classes, 475–476, 508–511 infinite loops, 137–139 inheritance. See also classes. abstract classes, 505–508 access control, 479–482, 489–490 base classes accessing private members, 480–482 definition, 475–476 deriving classes from, 476–479 direct, 475–476 indirect, 475–476, 508–511 pointers to, 501–503 definition, 475 derived classes constructors, 482–486 copy constructors, 490–495 creating, 476–479 definition, 475 pointers to, 501–503 friend classes, 495–496 incomplete class definitions, 504 multiple levels of, 508–511 pointers to class objects, 501–503 polymorphism, 501 protected class members, 486–489

1163

Index

inheritance

inheritance (continued) inheritance (continued) virtual destructors, 511–516 virtual functions definition, 499 description, 497–501 pure, 505 references with, 503–504 inheritance, C++/CLI access specifiers, 531–532 class libraries, creating, 532–535 delegates calling, 540–541 creating, 537–541 declaring, 537 definition, 536 unbound, 541–545 derived reference classes, 524–526 derived value classes, 520–524 events creating, 545–546 definition, 536 handling, 547–548 finalizers, 549–551 generic classes collection classes, 555–561 defining, 551–552 Dictionary, generic dictionary, 558 interface classes, 554–555 LinkedList, generic doubly linked list, 557 List, generic list, 556–557 using, 552–561 interface classes, 526–531 new functions, 536 reference class destructors, 549–551 visibility specifiers, 531 InheritedStyle property, 1100–1101 Initial status bar option, 658 initializing multidimensional arrays, 170–172 one-dimensional arrays, 164–165 pointers, 176–179 references, 197–198 variables, 53–54 initonly fields, 394–395 inline functions, in classes, 342–343

1164

input/output operations >> (angle brackets), extraction operator, 62–63 “...” (double quotes), special character indicator, 65 C++/CLI, 104–108 command line output, 63–64, 104 escape sequences, 65–67 formatting output, 64–65, 104–107 keyboard input, 62–63, 107–108, 152–153 manipulators, 64–65 special characters, 65–67 streams, 48 Insert() function, 1094 InsertAfter() function, 765–766, 773 InsertBefore() function, 765–766, 773 InsertCopy() function, 1094 instance handles, 622 instances counting, 366–367 definition, 335 overview, 332–334 instantiation, 335 int data type, 54 integer type modifiers, 56–57 integer variables, 54–55 Integrated Development Environment (IDE). See IDE (Integrated Development Environment). interface, DLL, 906, 913 interface classes, 526–531, 554–555 interior pointers, 225–228 internal specifier, 531 InvalidateRect() function, 731–732 IsEmpty() function, 773

J jagged arrays, 213–216 joining strings, 217–219

K keyboard input, 62–63, 107–108 keys, databases, 923 keywords, C++ C++/CLI, 1132 ISO/ANSI, 1131–1132 reserved, 52

L lprefix, 619–620 late binding, 904–906 left angle brackets (>), shift right, 86–87 right button detection, 728 Rollback() function, 983–984

rolling back database update, 980–982, 982–984, 997–998 RowIndex property, 1109 rows, database tables adding to tables adding orders, 1023–1028 DataGridView control, 1094 dialog switching, 1010–1014 order data, storing, 1019–1021 order entry process, 1000–1001 order IDs, creating, 1014–1019 overview, 999–1000 recordsets, creating, 1002 recordsets views, creating, 1002–1006 resources, adding controls, 1006–1010 resources, creating, 1001 selecting products, 1021–1023 setting dates, 1020–1021 alternate, customizing, 1108 copying, 1094 deleting, 1094 RowsDefaultCellStyle property, 1101 rubberbanding, 747, 750 run-time dynamic linking, 904–906 Rvalues, 68

S s prefix, 619–620 safe_cast operation, 108–109 scalar properties, 381, 382–388 scale factor document size, 844 mapping mode, 844–846 scaleable mapping modes, 842–844 scrolling, 846–848 scaling list boxes, 852–853 spin buttons, 835 scope of variables block, 88 global, 91–94 local, 88 scrollbars definition, 819 illustration, 819 setting up, 847–848

scrolling scale factor, 846–848 views, 787–792 SDI (Single Document Interface). See also MFC (Microsoft Foundation Classes). creating applications base classes, 660 Browser style toolbar option, 659 CEditView class, 660 CFormView class, 660 CHtmlEditView class, 660 CHtmlView class, 660 CListView class, 660 Context-sensitive help option, 659 CRichEditView class, 660 CScrollView class, 660 CTreeView class, 660 CView class, 660 Dialog based option, 657–658 Document/View architecture support option, 657–658 Initial status bar option, 658 Maximize box option, 658 Maximized option, 658 Minimize box option, 658 Minimized option, 658 Multiple top-level documents option, 657–658 options, 657–660 Printing and print preview option, 659 Resource language option, 657–658 SDI (Single Document Interface), 657–660 Split window option, 658 Standard docking toolbar option, 659 Thick Frame option, 658 Use Unicode libraries option, 657–658 definition, 650 searching lists, 766–767 one-dimensional arrays, 206–209 pointers in lists, 773 strings, 222–225 selection color, cells, 1099–1100 SelectionBackColor property, 1099–1100 SelectionForeColor property, 1099–1100 semantic errors, 567 semicolon (;), end of statement indicator, 47

1173

Index

semicolon (;), end of statement indicator

serialization serialization applying to documents, 876–877 to element classes, 877–879 recording document changes, 874–876 to shape classes, 879–881 CArchive class, 870–871 for a class, 874 CObject-based classes, 872 DECLARE_DYNAMIC() macro, 872 DECLARE_DYNCREATE() macro, 869, 872 DECLARE_SERIAL() macro, 872 default constructor, 869 disk input/output capability, 870–871 in document class definition, 868–869 to documents, 876–877 IMPLEMENT_SERIAL() macro, 872–873 moving text, 882–883 object types, 871 primitive types, 871 process description, 873–874 Serialize() function definition, 870 serializing documents, 876–877 shape classes, 879–881 Serialize() function definition, 870 serializing documents, 876–877 shape classes, 879–881 SetAt() function, 773 SetCapture() function, 755–756 SetCheck() method, 698 SetMaxPage() function, 887 SetMinPage() function, 887 SetRadio() method, 698 SetROP2() function, 747–750 SetText() method, 698 shape classes, serialization, 879–881 shapes, collection classes, 760 shapes, drawing circles Arc() function, 715–717 CCircle class, 744–746 Ellipse() function, 715–717 with the mouse, 722–723, 744–746 curves CCurve class, 746, 775–779 CList template class, 774–775 example, 723–724

1174

lines alternating dash-dot, 718 CLine class, 737–741 dashed, 718 dotted, 718 LineTo() function, 714–715 with the mouse, 737–741 solid, 718 straight, 714–715 rectangles with the mouse, 722, 724, 739–743 RECT struct, 330 Shift key detection, 728 short data type, 54 Show() function, 1062–1066 ShowDialog() function, 1062–1063 signed modifier data type, 56–57 Single Document Interface (SDI). See SDI (Single Document Interface). sizeof operator, 181–183 slashes (//), comment indicator, 44 snapshot recordsets, 935–936 solid lines, 718 Solution Explorer, 10, 16 solutions creating, 18–19 definition, 13 sorting database records, 929 one-dimensional arrays, 205–206 recordsets, 948–950 source code automatic indenting, 22 compiler, 9 linker, 9 modifying, 17–18 naming program files, 460–461 organizing, 458–461 sources of data. See databases. special characters, input/output, 65–67 spin buttons creating, 835–837 dialog data exchange, 840 displaying, 841–842 initializing the dialog, 840–841 scale dialog class, 838–841 scale menu item, 835 scale toolbar button, 835 scaling, 835 validation, 840

Split window option, 658 SQL choosing records, 925–926 joining tables, 926–928 retrieving data, 924–926 sorting records, 929 stack space, 88 Standard C++ Library, 9 Standard docking toolbar option, 659 StartsWith() function, 222–225 statement blocks, 49–50 static constructors, 396 controls, 819 data members, 365–367 member functions, 367–368 properties, 393–394 storage duration, 91, 94–95 variables, 261–262 static specifier, 94–95 static_cast keyword, 80–81 status bars adding to frames, 848–850 overview, 848 parts of, 850–851 updating, 851––852 storage duration, 88–91, 94–95 streams, input/output, 48 string handling dynamic memory allocation, 216–225 multidimensional arrays, 171–172 one-dimensional arrays, 166–169 pointers, 189–190 strings array termination character, 166 C++/CLI + (plus sign), join operator, 217 description, 216 EndsWith() function, 222–225 joining, 217–219 modifying, 220–221 searching, 222–225 StartsWith() function, 222–225 trim() function, 220–221 trimming, 220–221 counting characters, 154–156, 189–190 extracting substrings, 305–307, 319–320

looping through, 154–156 removing blanks, 294–295, 316 structs . (period) member access operator, 325 member selection operator, 325 -> (arrow) indirect member access operator, 332 indirect member selection operator, 332 defining, 324–325 definition, 324 example, 326–329 initializing, 325 intellisense assistance, 329–330 linked lists, 331 members access, 325–329, 330–332 pointers, 330–332 RECT, 330 unions, 410 Style property, 1101 styles, cells default, 1101–1108 dynamic, 1108–1114 submenus, Windows Forms, 1038–1040 switch statement, 129–131 synonyms for data types, 60 syntactic errors, 567 system menu, 616 System using directive, 1033–1034 System::Collections using directive, 1033–1034 System::Collections::Ilist interface, 1114 System::ComponentModel using directive, 1033–1034 System::ComponentModel::BindingList interface, 1114 System::ComponentModel::BindingListView interface, 1114 System::ComponentModel::IlistSource interface, 1114 System::Data using directive, 1033–1034 System::Data::DataColumn class, 1090 System::Data::DataRow class, 1090 System::Data::DataSet class, 1090 System::Data::DataTable class, 1090 System::Drawing using directive, 1033–1034 System::Windows::Forms using directive, 1033–1034 sz prefix, 619–620

1175

Index

sz prefix

tab controls, Windows Forms

T tab controls, Windows Forms, 1040–1042 TabControl control, 1040–1042, 1127–1128 table adapters, 1090 tables, databases adding rows to adding orders, 1023–1028 dialog switching, 1010–1014 order data, storing, 1019–1021 order entry process, 1000–1001 order IDs, creating, 1014–1019 overview, 999–1000 recordsets, creating, 1002 recordsets views, creating, 1002–1006 resources, adding controls, 1006–1010 resources, creating, 1001 selecting products, 1021–1023 setting dates, 1020–1021 multiple, 1127–1128 tag names, 408–409 template classes, 653 template member functions, 430–431 templates, MFC documents, 652–653 temporary element storage, 734–736 ternary operator. See conditional operator. Text menu item, 859–860 Text property, 1068 Thick Frame option, 658 this pointer, 358–360 throwing exceptions C++/CLI, 308–309 description, 281 example, 280–281 tilde (~), NOT, 86 title bar, 615 toolbar, navigation, 1120–1123 toolbars adding buttons to editing button properties, 701–702 overview, 700–701 testing the buttons, 703 tooltips, 703–704 IDE, 10–12 tooltips, 703–704 ToString() function, 376–377 TotalNumberofItems() function, 1121 Trace class, 602–611 trace switches, 605–607

1176

tracepoints, 572–573 tracking handles, 199–200 tracking references, 225. See also references. transactions, database update, 982–984 trim() function, 220–221 trimming strings, 220–221 trivial scalar properties, 384–388 true/false data types, 57 try blocks, 281–283 typed pointers, collection classes AddHead() function, 772 AddTail() function, 772 CTypedPtrList class, 771 CTypedPtrList operators, 771–773 Find() function, 773 FindIndex() function, 773 GetAt() function, 772 GetCount() function, 773 GetHead() function, 772 GetHeadPos() function, 773 GetNext() function, 772 GetPrev() function, 772 GetTail() function, 772 GetTailPos() function, 773 InsertAfter() function, 773 InsertBefore() function, 773 IsEmpty() function, 773 RemoveAll() function, 772 RemoveAt() function, 773 RemoveHead() function, 772 RemoveTail() function, 772 SetAt() function, 773 typedef keyword, 60 type-safe collections, 760–761

U unbound delegates, 541–545 unbound mode, 1093–1099 unboxing data types, 101 unconditional branching, 132 Unindent() function, 604–605 unions anonymous, 409–410 in classes and structures, 410 defining, 408–409 definition, 407 tag names, 408–409

unmanaged C++, 3 Update() function, 980–982 update handlers, 699–700 update mode button label, changing, 992–993 Cancel button, visibility, 993–994 canceling the update, 997–998 description, 990–991 edit controls, enabling/disabling, 991–992 expediting the update, 996–997 Record menu, disabling, 994–996 update region, 731 UpdateAllViews() function, 785–787 UPDATE_COMMAND_UI messages, 689 updating databases adding records, 980–982 adding rows to tables adding orders, 1023–1028 dialog switching, 1010–1014 order data, storing, 1019–1021 order entry process, 1000–1001 order IDs, creating, 1014–1019 overview, 999–1000 recordsets, creating, 1002 recordsets views, creating, 1002–1006 resources, adding controls, 1006–1010 resources, creating, 1001 selecting products, 1021–1023 setting dates, 1020–1021 AddNew() function, 980–982 BeginTrans() function, 983–984 canceling updates, 980–982, 997–998 CancelUpdate() function, 980–982 CDatabase class, 983–984 CommitTrans() function, 983–984 completing an update, 980–982 controls button label, changing, 992–993 Cancel button, visibility, 993–994 canceling the update, 997–998 description, 990–991 edit controls, enabling/disabling, 991–992 expediting the update, 996–997 Record menu, disabling, 994–996 CRecordset operations, 980–982 Delete() function, 980–982 deleting records, 980–982 Edit() function, 980–982

editing records, 980–982 example, 984–988 inhibiting update, 988–990 optimistic record locking, 982 pessimistic record locking, 982 record locking, 982 Rollback() function, 983–984 rolling back an update, 982–984 starting an update, 988–990 tables, adding rows to adding orders, 1023–1028 dialog switching, 1010–1014 order data, storing, 1019–1021 order entry process, 1000–1001 order IDs, creating, 1014–1019 overview, 999–1000 recordsets, creating, 1002 recordsets views, creating, 1002–1006 resources, adding controls, 1006–1010 resources, creating, 1001 selecting products, 1021–1023 setting dates, 1020–1021 transactions, 982–984 Update() function, 980–982 update mode button label, changing, 992–993 Cancel button, visibility, 993–994 canceling the update, 997–998 description, 990–991 edit controls, enabling/disabling, 991–992 expediting the update, 996–997 Record menu, disabling, 994–996 validating operations, 981 Use Unicode libraries option, 657–658 user interface. See GUI (Graphical User Interface). using directives, 46, 96, 1033–1034

V validating database update operations, 981 input, dialog boxes, 1063–1066 value classes defining, 373–378 derived classes, C++/CLI, 520–526 deriving, 520–526 overloading, 461–466 Value property, 1109

1177

Index

Value property

variables variables See also const modifier See also literals See also pointers See also storage duration See also unions assigning values to, 47 automatic variables, 88–91 casting in assignment statements, 79–80 definition, 78 explicit casts, 80–81 old-style casts, 81 rules for, 78–79 debugging, 576–578 declaring, 47, 52–53, 91 decrementing, 74–76 default type, 88–91 definition (declaring), 53 definition (meaning of), 51 enumeration, 60–62 identifiers, 51–52 incrementing, 74–76 initialization, 53–54 limiting values of, 60–61 modifying, 73–74 naming, 51–52, 619–620 positioning declaration, 91 prefixes, 619–620 reserved keywords, 52 scope block, 88 global, 91–94 local, 88 stack space, 88 static storage duration, 91, 94–95 storage duration, 88–91, 94–95 vertical bars (||), logical OR, 125–126 view class, 653, 711–712, 954–957 viewing data. See DataGridView control. views. See also documents. client coordinates, 789–792 creating elements, 833–834 logical coordinates, 789–790 MM_LOENGLISH MAPPING MODE, 792–793 OnUpdate() function, 785–787 scrolling, 787–792 UpdateAllViews() function, 785–787 updating multiple, 785–787

1178

virtual class destructors, 511–516 virtual destructors, 511–516 virtual functions definition, 499 description, 497–501 inheritance, 497–501 pure, 505 references with, 503–504 virtual keyword, 499–501 virtual mode, 1093 visibility specifiers, 531

W w prefix, 619–620 watch, setting, 576 wchar_t data type, 56 Web browser controls, 1047–1048 WebBrowser control, 1047–1048 while loops, 143–145 whitespace, 49 wide character data type, 56 Win32 console applications, 6, 13–21 WINAPI() function, 622 window class, registering, 625–627 WindowProc() function, 632–637 windows client area, 708 creating, 625–627 elements borders, 615 child windows, 615 client area, 615 control menu, 616 illustration, 615 parent windows, 615 resource files, 616 system menu, 616 title bar, 615 ending the program, 636 example program, 637–638 initializing, 627 look and feel, 622 messages client area, drawing, 634–636 cooperative mulltitasking, 629–630 decoding, 633–636 definition, 681

device content, 634–636 display content, 634–636 message loop, 628–629 message processing functions, 632–637 message pump, 628–629 mulltitasking, 629–630 non-queued, 627–628 pre-emptive mulltitasking, 629–630 queued, 627–628 specifying, 623–625 Windows Forms containers, 1031 definition, 1031 dialog boxes adding, 1068–1075 button clicks, handling, 1076–1079, 1083–1086 ComboBox control, 1068–1070, 1072 context menu, responding to, 1079–1086 ControlBox property, 1068 creating, 1056–1062 DialogResult property, 1057, 1063–1066 event handler, Reset menu, 1067–1068 FormBorderStyle property, 1068 getting data from, 1070–1073 Help > About menu, 1075–1076 input controls, disabling, 1073–1074 Limits menu, 1074–1075 MaximizeBox property, 1068 MinimizeBox property, 1068 NumericUpDown control, 1068–1070, 1073 Show() function, 1062–1066 ShowDialog() function, 1062–1063 Text property, 1068 using, 1062–1068 validating input, 1063–1066 library, 9 overview, 1031–1032 Windows Forms, application databases accessing data, 1090–1091 AddNew() function, 1121 BindingNavigator control, 1120–1123 BindingSource component, 1115–1120 bound mode, 1114–1115 cells alignment, 1100 background color, 1099–1100 buttons, 1095 CellStyle property, 1109

ColumnIndex property, 1109 default styles, 1101–1108 DesiredType property, 1109 dynamic styles, 1108–1114 fonts, 1099–1100 foreground color, 1099–1100 formatting, 1100 FormattingApplied property, 1109 header, customizing, 1101 highlighting on mouseover, 1110–1114 images, 1096 non-header, customizing, 1101–1108 padding, 1100 properties, 1109 RowIndex property, 1109 selection color, 1099–1100 Value property, 1109 wrapping text, 1100 columns adding, 1096 binding to controls, 1123–1127 buttons in cells, 1095 check boxes, 1095 defining, 1093–1099 drop-down lists, 1096 editing, 1096–1098 images in cells, 1096 links, displaying, 1096 width, setting, 1098–1099 controls appearance, 1102–1103 binding to columns, 1123–1127 binding to data sources, 1115–1120 column format, 1106–1108 column headers, 1105–1106 setting up, 1103–1104 CurrentPosition() function, 1121 data source classes, 1090 DataGridView control Add() function, 1094 AddCopy() function, 1094 bound mode, 1093 Clear() function, 1094 column types, 1095–1099 DataGridViewButtonColumn column, 1095 DataGridViewCheckBoxColumn column, 1095 DataGridViewComboBoxColumn column, 1096 DataGridViewImageColumn column, 1096

1179

Index

Windows Forms, application databases

Windows Forms, application databases (continued) Windows Forms, application databases (continued) DataGridView control DataGridViewLinkColumn column, 1096 definition, 1090 displaying data, 1091–1093 Insert() function, 1094 InsertCopy() function, 1094 modes, 1092–1099 Remove() function, 1094 RemoveAt() function, 1094 unbound mode, 1093–1099 virtual mode, 1093 DataGridView control, customizing Alignment property, 1100 AlternatingRowsDefaultCellStyle property, 1101 BackColor property, 1099–1100 DataGridViewCellStyle object, 1099–1100 DefaultCellStyle property, 1101 Font property, 1099–1100 ForeColor property, 1099–1100 Format property, 1100 InheritedStyle property, 1100–1101 Padding property, 1100 RowsDefaultCellStyle property, 1101 SelectionBackColor property, 1099–1100 SelectionForeColor property, 1099–1100 Style property, 1101 System::Collections::Ilist interface, 1114 System::ComponentModel::BindingList interface, 1114 System::ComponentModel::BindingListView interface, 1114 System::ComponentModel::IlistSource interface, 1114 WrapMode property, 1100 displaying data, 1090–1091 MoveFirst() function, 1121 MoveLast() function, 1121 MoveNext() function, 1121 MovePrevious() function, 1121 navigating data sources, 1120–1123 RemoveCurrent() function, 1121 rows adding, 1094 alternate, customizing, 1108 copying, 1094 deleting, 1094

1180

System::Data::DataColumn class, 1090 System::Data::DataRow class, 1090 System::Data::DataSet class, 1090 System::Data::DataTable class, 1090 TabControl control, 1127–1128 table adapters, 1090 tables, multiple, 1127–1128 toolbar, navigation, 1120–1123 TotalNumberofItems() function, 1121 updating a database, 1122–1123 Windows Forms, application GUI Button control, 1044–1046 context menus, 1049 ContextMenuStrip control, 1049 dialog boxes adding, 1068–1075 button clicks, handling, 1076–1079, 1083–1086 ComboBox control, 1068–1070, 1072 context menu, responding to, 1079–1086 ControlBox property, 1068 creating, 1056–1062 DialogResult property, 1057, 1063–1066 event handler, Reset menu, 1067–1068 FormBorderStyle property, 1068 getting data from, 1070–1073 Help > About menu, 1075–1076 input controls, disabling, 1073–1074 Limits menu, 1074–1075 MaximizeBox property, 1068 MinimizeBox property, 1068 NumericUpDown control, 1068–1070, 1073 Show() function, 1062–1066 ShowDialog() function, 1062–1063 Text property, 1068 using, 1062–1068 validating input, 1063–1066 dialog button events, 1058–1060 dialog objects, creating, 1061–1062 event handler, dialog button, 1058–1060 event handlers, menu items, 1049–1056 FixedDialog property, 1056–1062 FormBorderStyle property, 1056–1062 GroupBox control, 1042–1044 grouping controls, 1042–1044 list boxes, 1058–1061 menu items, event handlers, 1049–1056 menus, 1037–1038 overview, 1035–1036

submenus, 1038–1040 tab controls, 1040–1042 TabControl control, 1040–1042 testing, 1048–1049 Web browser controls, 1047–1048 WebBrowser control, 1047–1048 Windows Forms, applications creating, 31–35 example, 645–647 overview, 1032–1034 properties, modifying, 1034–1035 starting, 1035 System using directive, 1033–1034 System::Collections using directive, 1033–1034 System::ComponentModel using directive, 1033–1034 System::Data using directive, 1033–1034 System::Drawing using directive, 1033–1034 System::Windows::Forms using directive, 1033–1034 using directives, 1033–1034 Windows programs. See also MFC (Microsoft Foundation Classes). API (application programming interface), 617–618 b prefix, 619–620 BOOLEAN data type, 618 by prefix, 619–620 BYTE data type, 618 c prefix, 619–620 C++ standards, 5–6 C++ versions, 5 CHAR data type, 618 CLR console applications, 6 command line pointer, 622 console applications, 6 data types, 618–619 dw prefix, 619–620 DWORD data type, 618 event-driven, 7, 617 events, 7 fn prefix, 619–620 h prefix, 619–620 HANDLE data type, 618 handles, 622 HBRUSH data type, 618 HCURSOR data type, 618 HDC data type, 618 HINSTANCE data type, 618

Hungarian notation, 620 i prefix, 619–620 instance handles, 622 l prefix, 619–620 lp prefix, 619–620 LPARAM data type, 619 LPCSTR data type, 619 LPHANDLE data type, 619 LRESULT data type, 619 message queue, 617 n prefix, 619–620 operating system, 616 organizing, 638–640 p prefix, 619–620 programming concepts, 6–8 s prefix, 619–620 structure of. See also WindowProc() function; WinMain() function. required functions, 620–621 sz prefix, 619–620 variable name notation, 619–620 variable prefixes, 619–620 w prefix, 619–620 Win32 console applications, 6 window class, registering, 625–627 window elements borders, 615 child windows, 615 client area, 615 control menu, 616 illustration, 615 parent windows, 615 resource files, 616 system menu, 616 title bar, 615 WindowProc() function, 632–637 windows creating, 625–627 ending the program, 636 example program, 637–638 initializing, 627 look and feel, 622 specifying, 623–625 windows messages client area, drawing, 634–636 cooperative mulltitasking, 629–630 decoding, 633–636 device content, 634–636

1181

Index

Windows programs

Windows programs (continued) Windows programs (continued) windows messages display content, 634–636 message loop, 628–629 message processing functions, 632–637 message pump, 628–629 mulltitasking, 629–630 non-queued, 627–628 pre-emptive mulltitasking, 629–630 queued, 627–628 WORD data type, 619 WinMain() function arguments, 622 example, 631–632 hInstance argument, 622 hPrevInstance argument, 622 lpCmdLine argument, 622 nCmdShow argument, 622 prototype, 621

1182

RegisterClassEx() function, 625–627 WINAPI() function, 622 WNDCLASSEX struct, 623–625 wizard. See MFC Application wizard. W M _ L B U T T O N D O W N message, 725–726 WM_LBUTTONUP message, 725, 727, 753 W M _ M O U S E M O V E handler, 810–811 W M _ M O U S E M O V E message, 725, 726–727 WM_PAINT message, 708, 711, 731, 754–755 WNDCLASSEX struct, 623–625 WORD data type, 619 WrapMode property, 1100 wrapping text, 1100 Write() function, 103–104, 603–604 WriteIf() function, 603–604 WriteLine() function, 103–104, 603–604 WriteLineIf() function, 603–604 write-only properties, 381