0% found this document useful (0 votes)
67 views2,467 pages

Devwin 32

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
67 views2,467 pages

Devwin 32

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 2467

RAD Studio

Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.


RAD Studio

Table of Contents

Concepts 1
Debugging C++ Applications with CodeGuard Error Reporting 3
CodeGuard Errors 3
Access Errors 4
Exception Errors 5
Function Failure Errors 6
Resource Errors 7
CodeGuard Overview 9
CodeGuard Warnings 10
Memory Block Comparison Warnings 11
Pathname Merging and Splitting Warnings 11
String Comparison Warnings 11

Developing Database Applications for the Win32 Platform 13


dbGo Overview 14
BDE Overview 15
dbExpress Components 16
Getting Started with InterBase Express 17
dbExpress 4 Feature Overview 22
Blackfish SQL Overview 24
dbExpress Framework 26
dbExpress Framework Compatibility 27

Developing Interoperable Applications 29


Developing COM Applications 29

Developing Reports for Your Win32 Applications 35


Using Rave Reports in RAD Studio 35

Developing Applications with VCL Components 36


VCL Overview 36
Using TEncoding for Unicode Files 38
Components Available Only on Specific OS 39

Developing Web Applications with WebSnap 41


Win32 Web Applications Overview 41

Developing Web Services with Win32 Applications 44


Web Services Overview 44

iii
RAD Studio

Developing Windows Applications 45


Windows Overview 45

Procedures 47
CodeGuard Procedures 48
Using CodeGuard 48

Database Procedures 50
Accessing Schema Information 51
Using Data Explorer to Obtain Connection Information 52
Configuring TSQL Connection 53
Connecting to the Application Server using DataSnap Components 55
Debugging dbExpress Applications using TSQLMonitor 55
Executing the Commands using TSQLDataSet 56
Fetching the Data using TSQLDataSet 57
Specifying the Data to Display using TSQLDataSet 58
Specifying the Provider using TLocalConnection or TConnectionBroker 59
Using BDE 60
Using DataSnap 60
Using TBatchMove (BDE) 61
Connecting to Databases with TDatabase 62
Using TQuery (Procedure) 63
Using TSQLQuery 65
Using TSQLStoredProc (Procedure) 66
Using TSQLTable 66
Managing Database Sessions Using TSession 67
Using TSimpleDataSet 68
Using TSimpleObjectBroker 69
Using TStoredProc 69
Using TTable (Procedure) 70
Using TUpdateSQL to Update a Dataset 72
Using dbExpress 72
Adding a New Connection to the Data Explorer 73
Browsing a Database in the Data Explorer 74
Executing SQL in the Data Explorer 74
Modifying Connections in the Data Explorer 75
Connecting to a Database using the dbExpress Driver Framework 76

Interoperable Applications Procedures 79

iv
RAD Studio

Using COM Wizards 79

Reporting Procedures 81
Adding Rave Reports to RAD Studio 81

VCL Procedures 82
Building a Windows "Hello World" Console Application 88
Developing a Windows Application 89
Building Application Menus 90
Building a VCL Forms Application with Decision Support Components 91
Building VCL Forms Applications With Graphics 93
Building a VCL Forms MDI Application Using a Wizard 93
Building a VCL Forms MDI Application Without Using a Wizard 94
Building a VCL Forms SDI Application 96
Creating a New VCL Component 97
Building a VCL Forms ADO Database Application 98
Building a VCL Forms Application 99
Creating Actions in a VCL Forms Application 100
Building a VCL Forms "Hello World" Application 101
Using ActionManager to Create Actions in a VCL Forms Application 102
Building a VCL Forms dbExpress Database Application 103
Building an Application with XML Components 104
Copying Data From One Stream To Another 106
Copying a Complete String List (VCL) 107
Creating Strings 109
Creating a VCL Form Instance Using a Local Variable 110
Deleting Strings 112
Displaying an Auto-Created VCL Form 113
Displaying a Bitmap Image in a VCL Forms Application 114
Displaying a Full View Bitmap Image in a VCL Forms Application 116
Drawing a Polygon in a VCL Forms Application 117
Drawing Rectangles and Ellipses in a VCL Forms Application 118
Drawing a Rounded Rectangle in a VCL Forms Application 118
Drawing Straight Lines In a VCL Forms Application 119
Dynamically Creating a VCL Modal Form 120
Dynamically Creating a VCL Modeless Form 121
Iterating Through Strings in a List 123
Building a Multithreaded Application 124
Writing Cleanup Code 125
Avoiding Simultaneous Thread Access to the Same Memory 125

v
RAD Studio

Defining the Thread Object 126


Handling Exceptions 129
Initializing a Thread 130
Using the Main VCL Thread 131
Waiting for Threads 132
Writing the Thread Function (Procedure) 134
Placing A Bitmap Image in a Control in a VCL Forms Application 135
Reading a String and Writing It To a File 136
Renaming Files 137
Adding and Sorting Strings 138
Creating a VCL Forms ActiveX Button 139
Creating a VCL Forms ActiveX Active Form 140
Building a VCL Forms Web Browser Application 142
Creating an Application that Uses Ribbon Controls 143
Adding Commands to the Ribbon 144

WebSnap Procedures 147


Building a WebSnap Application 148
Building a WebSnap "Hello World" Application 149
Debugging a WebSnap Application using the Web Application Debugger 150
Using the HTML Tag Editor 151

Web Services Procedure 153


Building a "Hello World" Web Services Application 153

Reference 155
C++ Reference 156
Command Line Utilities 156
BCC32, the C++ Command-Line Compiler 159
BRC32, the Resource Shell 163
BRCC32.EXE, the Resource Compiler 165
COFF2OMF.EXE, the Import Library Conversion Tool 166
CPP32.EXE, the C Compiler Preprocessor 167
DCC32.EXE, the Delphi Command Line Compiler 169
GREP.EXE, the text search utility 170
ILINK32.EXE, the Incremental Linker 174
IMPDEF.EXE, the Module Definition Manager 179
IMPLIB.EXE, the Import Library Tool 181
Using Include Files 182
MAKE 183

vi
RAD Studio

MAKE Directives 186


MAKE Macros 191
MAKE Rules (Explicit and Implicit) and Commands 193
Message Options 197
Module Definition Files 199
Using Precompiled Header Files 203
RLINK32.DLL, the Resource Linker (C++) 204
TDUMP.EXE, the File Dumping Utility 204
TLIB.EXE, the Library Manager 208
Using TOUCH.EXE 212
TRIGRAPH 213
RC.EXE, the Microsoft SDK Resource Compiler 213
WSDLIMP.EXE, the Command Line WSDL Import Tool 214
C++ Compiler Errors And Warnings (C++) 216
E2066: Invalid MOM inheritance (C++) 256
E2525: You must define _PCH_STATIC_CONST before including xstring to use this feature (C++) 257
E2526: Property 'name' uses another property as getter/setter; Not allowed (C++) 257
E2008: Published property access functions must use __fastcall calling convention (C++) 257
E2122: Function call terminated by unhandled exception 'value' at address 'addr' (C++) 257
E2506: Explicit specialization of 'specifier' is ambiguous: must specify template arguments (C++) 257
E2483: Array dimension 'specifier' could not be determined (C++) 258
E2509: Value out of range (C++) 258
E2510: Operand size mismatch (C++) 258
E2050: __declspec(delphireturn) class 'class' must have exactly one data member (C++) 258
E2530: Unrecognized option, or no help available (C++) 258
E2527: Option 'name' cannot be set via 'name' (C++) 258
E2528: Option 'name' must be set before compilation begins (C++) 258
E2074: Value after -g or -j should be between 0 and 255 inclusive (C++) 259
E2492: Properties may only be assigned using a simple statement, e.g. \"prop = value;\" (C++) 259
E2505: Explicit instantiation requires an elaborated type specifier (i.e.,"class foo<int>") (C++) 259
E2100: Invalid template declarator list (C++) 259
E2102: Cannot use template 'template' without specifying specialization parameters (C++) 260
E2107: Invalid use of template 'template' (C++) 260
E2105: 'template' qualifier must specify a member template name (C++) 260
E2066: Information not available (C++) 261
E2471: pragma checkoption failed: options are not as expected (C++) 261
E2504: 'dynamic' can only be used with non-template member functions (C++) 261
E2191: '__far16' may only be used with '__pascal' or '__cdecl' (C++) 261
E2199: Template friend function 'function' must be previously declared (C++) 262

vii
RAD Studio

E2502: Error resolving #import: problem (C++) 262


E2501: Unable to open import file 'filename' (C++) 262
E2494: Unrecognized __declspec modifier (C++) 262
E2493: Invalid GUID string (C++) 263
E2499: Invalid __declspec(uuid(GuidString)) format (C++) 263
E2496: Invalid call to uuidof(struct type|variable) (C++) 263
E2511: Unterminated macro argument (C++) 263
E2489: Maximum option context replay depth exceeded; check for recursion (C++) 263
E2488: Maximum token reply depth exceeded; check for recursion (C++) 263
E2491: Maximum VIRDEF count exceeded; check for recursion (C++) 263
E2230: In-line data member initialization requires an integral constant expression (C++) 264
E2241: VCL style classes need virtual destructors (C++) 264
E2524: Anonymous structs/unions not allowed to have anonymous members in C++ (C++) 264
E2246: x is not abstract public single inheritance class hierarchy with no data (C++) 264
E2249: = expected (C++) 264
E2267: First base must be VCL class (C++) 264
E2472: Cannot declare a member function via instantiation (C++) 265
E2515: Cannot explicitly specialize a member of a generic template class (C++) 265
E2474: 'function' cannot be declared as static or inline (C++) 265
E2498: Need previously defined struct GUID (C++) 266
E2295: Too many candidate template specializations from 'specifier' (C++) 266
E2475: 'function' cannot be a template function (C++) 266
E2299: Cannot generate template specialization from 'specifier' (C++) 267
E2300: Could not generate a specialization matching type for 'specifier' (C++) 267
E2497: No GUID associated with type:'type' (C++) 267
E2522: Non-const function 'function' called for const object (C++) 267
E2523: Non-volatile function 'name' called for volatile object (C++) 267
E2513: Cannot emit RTTI for 'parameter' in 'function' (C++) 267
E2512: Cannot emit RTTI for return type of 'function' (C++) 267
E2507: 'class' is not a direct base class of 'class' (C++) 268
E2529: Path 'path' exceeds maximum size of 'n' (C++) 268
E2495: Redefinition of uuid is not identical (C++) 268
E2500: __declspec(selectany) is only for initialized and externally visible variables (C++) 268
E2482: String constant expected (C++) 268
E2481: Unexpected string constant (C++) 268
E2386: Cannot involve parameter 'parameter' in a complex partial specialization expression (C++) 268
E2387: Partial specializations may not specialize dependent non-type parameters ('parameter') (C++) 269
E2388: Argument list of specialization cannot be identical to the parameter list of primary template (C++) 269
E2389: Mismatch in kind of substitution argument and template parameter 'parameter' (C++) 269

viii
RAD Studio

E2480: Cannot involve template parameters in complex partial specialization arguments (C++) 269
E2392: Template instance 'template' is already instantiated (C++) 270
E2393: Cannot take the address of non-type, non-reference template parameter 'parameter' (C++) 270
E2399: Cannot reference template argument 'arg' in template class 'class' this way (C++) 270
E2397: Template argument cannot have static or local linkage (C++) 270
E2485: Cannot use address of array element as non-type template argument (C++) 271
E2402: Illegal base class type: formal type 'type' resolves to 'type' (C++) 271
E2403: Dependent call specifier yields non-function 'name' (C++) 271
E2404: Dependent type qualifier 'qualifier' has no member type named 'name' (C++) 271
E2405: Dependent template reference 'identifier' yields non-template symbol (C++) 271
E2406: Dependent type qualifier 'qualifier' is not a class or struct type (C++) 272
E2407: Dependent type qualifier 'qualifier' has no member symbol named 'name' (C++) 272
E2408: Default values may be specified only in primary class template declarations (C++) 272
E2409: Cannot find a valid specialization for 'specifier' (C++) 272
E2410: Missing template parameters for friend template 'template' (C++) 273
E2486: Cannot use address of class member as non-type template argument (C++) 273
E2411: Declaration of member function default parameters after a specialization has already been 273
expanded (C++)
E2412: Attempting to bind a member reference to a dependent type (C++) 273
E2414: Destructors cannot be declared as template functions (C++) 273
E2473: Invalid explicit specialization of 'specifier' (C++) 274
E2490: Specialization within template classes not yet implemented (C++) 274
E2416: Invalid template function declaration (C++) 274
E2417: Cannot specify template parameters in explicit specialization of 'specifier' (C++) 274
E2418: Maximum instantiation depth exceeded; check for recursion (C++) 274
E2420: Explicit instantiation can only be used at global scope (C++) 274
E2422: Argument kind mismatch in redeclaration of template parameter 'parameter' (C++) 275
E2423: Explicit specialization or instantiation of non-existing template 'template' (C++) 275
E2479: Cannot have both a template class and function named 'name' (C++) 275
E2484: The name of template class 'class' cannot be overloaded (C++) 275
E2426: Explicit specialization of 'specifier' requires 'template<>' declaration (C++) 275
E2487: Cannot specify default function arguments for explicit specializations (C++) 276
E2427: 'main' cannot be a template function (C++) 276
E2429: Not a valid partial specialization of 'specifier' (C++) 276
E2430: Number of template parameters does not match in redeclaration of 'specifier' (C++) 276
E2477: Too few template parameters were declared for template 'template' (C++) 276
E2478: Too many template parameters were declared for template 'template' (C++) 277
E2431: Non-type template parameters cannot be of floating point, class, or void type (C++) 277
E2434: Template declaration missing template parameters ('template<...>') (C++) 277

ix
RAD Studio

E2435: Too many template parameter sets were specified (C++) 277
E2436: Default type for template template argument 'arg' does not name a primary template class (C++) 277
E2437: 'typename' should be followed by a qualified, dependent type name (C++) 278
E2438: Template template arguments must name a class (C++) 278
E2439: 'typename' is only allowed in template declarations (C++) 278
E2440: Cannot generate specialization from 'specifier' because that type is not yet defined (C++) 278
E2441: Instantiating 'specifier' (C++) 278
E2503: Missing or incorrect version of TypeLibImport.dll (C++) 279
E2470: Need to include header <typeinfo> to use typeid (C++) 279
E2514: Cannot (yet) use member overload resolution during template instantiation (C++) 279
E2508: 'using' cannot refer to a template specialization (C++) 279
E2462: 'virtual' can only be used with non-template member functions (C++) 279
W8086: Incorrect use of #pragma alias "aliasName"="substituteName" (C++) 280
W8099: Static main is not treated as an entry point (C++) 280
W8093: Incorrect use of #pragma codeseg [seg_name] ["seg_class"] [group] (C++) 280
W8094: Incorrect use of #pragma comment( <type> [,"string"] ) (C++) 280
W8085: Function 'function' redefined as non-inline (C++) 281
W8105: %s member '%s' in class without constructors (C++) 281
W8095: Incorrect use of #pragma message( "string" ) (C++) 281
W8098: Multi-character character constant (C++) 281
W8096: Incorrect use of #pragma code_seg(["seg_name"[,"seg_class"]]) (C++) 281
W8083: Pragma pack pop with no matching pack push (C++) 282
W8097: Not all options can be restored at this time (C++) 282
W8084: Suggest parentheses to clarify precedence (C++) 282
W8092: 'type' argument 'specifier' passed to 'function' is not an iterator: 'type' iterator required (C++) 282
W8087: 'operator::operator==' must be publicly visible to be contained by a 'type' (C++) 283
W8090: 'type::operator<' must be publicly visible to be used with 'type' (C++) 283
W8089: 'type::operator<' must be publicly visible to be contained by a 'type' (C++) 283
W8091: 'type' argument 'specifier' passed to 'function' is a 'iterator category' iterator: 'iterator category' 283
iterator required (C++)
W8076: Template instance 'specifier' is already instantiated (C++) 283
W8077: Explicitly specializing an explicitly specialized class member makes no sense (C++) 283
Informational messages (C++) 284
E2196: Cannot take address of member function 'function' (C++) 284
F1002: Unable to create output file 'filename' (C++) 284
F1003: Error directive: 'message' (C++) 284
F1004: Internal compiler error (C++) 284
F1006: Bad call of intrinsic function (C++) 284
F1007: Irreducible expression tree (C++) 285

x
RAD Studio

F1009: Unable to open input file 'filename' (C++) 285


F1011: Register allocation failure (C++) 285
F1012: Compiler stack overflow (C++) 285
F1013: Error writing output file (C++) 285
F1000: Compiler table limit exceeded (C++) 285
F1005: Include files nested too deep (C++) 286
F1008: Out of memory (C++) 286
F1010: Unable to open 'filename' (C++) 286
E2000: 286/287 instructions not enabled (C++) 286
Abnormal program termination (C++) 286
E2009: Attempt to grant or reduce access to 'identifier' (C++) 286
E2011: Illegal to take address of bit field (C++) 286
E2010: Cannot add or subtract relocatable symbols (C++) 287
E2013: 'function1' cannot be distinguished from 'function2' (C++) 287
E2014: Member is ambiguous: 'member1' and 'member2' (C++) 287
E2015: Ambiguity between 'function1' and 'function2' (C++) 287
E2017: Ambiguous member name 'name' (C++) 287
E2019: 'identifier' cannot be declared in an anonymous union (C++) 288
E2020: Global anonymous union not static (C++) 288
E2022: Array size too large (C++) 288
E2024: Cannot modify a const object (C++) 288
E2025: Assignment to 'this' not allowed, use X::operator new instead (C++) 288
E2026: Assembler statement too long (C++) 288
E2001: Constructors and destructors not allowed in __automated section (C++) 289
E2002: Only __fastcall functions allowed in __automated section (C++) 289
E2003: Data member definition not allowed in __automated section (C++) 289
E2004: Only read or write clause allowed in property declaration in __automated section (C++) 289
E2005: Redeclaration of property not allowed in __automated section (C++) 290
E2027: Must take address of a memory location (C++) 290
E2028: operator -> must return a pointer or a class (C++) 290
E2029: 'identifier' must be a previously defined class or struct (C++) 290
E2030: Misplaced break (C++) 290
E2031: Cannot cast from 'type1' to 'type2' (C++) 290
E2033: Misplaced continue (C++) 291
E2034: Cannot convert 'type1' to 'type2' (C++) 291
E2036: Conversion operator cannot have a return type specification (C++) 292
E2037: The constructor 'constructor' is not allowed (C++) 292
E2039: Misplaced decimal point (C++) 292
E2041: Incorrect use of default (C++) 292

xi
RAD Studio

E2042: Declare operator delete (void*) or (void*, size_t) (C++) 293


E2044: operator delete must return void (C++) 293
E2045: Destructor name must match the class name (C++) 293
E2048: Unknown preprocessor directive: 'identifier' (C++) 293
E2046: Bad file name format in include directive OR Bad file name format in line directive (C++) 294
E2051: Invalid use of dot (C++) 294
E2053: Misplaced elif directive (C++) 294
E2054: Misplaced else (C++) 294
E2055: Misplaced else directive (C++) 294
E2056: Misplaced endif directive (C++) 295
E2059: Unknown language, must be C or C++ (C++) 295
E2060: Illegal use of floating point (C++) 295
E2061: Friends must be functions or classes (C++) 295
E2062: Invalid indirection (C++) 295
E2063: Illegal initialization (C++) 296
E2064: Cannot initialize 'type1' with 'type2' (C++) 296
E2068: 'identifier' is not a non-static data member and can't be initialized here (C++) 296
E2069: Illegal use of member pointer (C++) 296
E2071: operator new must have an initial parameter of type size_t (C++) 297
E2072: Operator new[] must return an object of type void (C++) 297
E2075: Incorrect 'type' option: option (C++) 297
E2076: Overloadable operator expected (C++) 297
E2080: 'function' must be declared with one parameter (C++) 298
E2077: 'operator' must be declared with one or no parameters (C++) 298
E2079: 'function' must be declared with no parameters (C++) 298
E2078: 'operator' must be declared with one or two parameters (C++) 298
E2081: 'function' must be declared with two parameters (C++) 298
E2082: 'identifier' must be a member function or have a parameter of class type (C++) 298
E2083: Last parameter of 'operator' must have type 'int' (C++) 299
E2084: Parameter names are used only with a function body (C++) 299
E2085: Invalid pointer addition (C++) 299
E2086: Illegal pointer subtraction (C++) 299
E2087: Illegal use of pointer (C++) 299
E2088: Bad syntax for pure function definition (C++) 300
E2089: Identifier 'identifier' cannot have a type qualifier (C++) 300
E2090: Qualifier 'identifier' is not a class or namespace name (C++) 300
E2092: Storage class 'storage class' is not allowed here (C++) 300
E2096: Illegal structure operation (C++) 300
E2104: Invalid use of template keyword (C++) 300

xii
RAD Studio

E2108: Improper use of typedef 'identifier' (C++) 301


E2109: Not an allowed type (C++) 301
E2110: Incompatible type conversion (C++) 301
E2113: Virtual function 'function1' conflicts with base class 'base' (C++) 301
E2114: Multiple base classes require explicit class names (C++) 301
E2115: Bit field too large (C++) 301
E2116: Bit fields must contain at least one bit (C++) 301
W8005: Bit fields must be signed or unsigned int (C++) 302
E2119: User break (C++) 302
E2111: Type 'typename' may not be defined here (C++) 302
E2121: Function call missing ) (C++) 302
E2123: Class 'class' may not contain pure functions (C++) 302
E2126: Case bypasses initialization of a local variable (C++) 302
E2127: Case statement missing : (C++) 302
E2128: Case outside of switch (C++) 302
E2129: Character constant too long (or empty) (C++) 303
E2133: Unable to execute command 'command' (C++) 303
E2134: Compound statement missing closing brace (C++) 303
E2137: Destructor for 'class' required in conditional expression (C++) 303
E2135: Constructor/Destructor cannot be declared 'const' or 'volatile' (C++) 303
E2138: Conflicting type modifiers (C++) 303
E2136: Constructor cannot have a return type specification (C++) 303
E2038: Cannot declare or define 'identifier' here: wrong namespace (C++) 304
E2154: Cannot define 'identifier' using a namespace alias (C++) 304
E2421: Cannot use local type 'identifier' as template argument (C++) 304
E2035: Conversions of class to itself or base class not allowed (C++) 304
E2139: Declaration missing ; (C++) 304
E2140: Declaration is not allowed here (C++) 304
E2141: Declaration syntax error (C++) 304
E2142: Base class 'class' contains dynamically dispatchable functions (C++) 304
E2143: Matching base class function 'function' has different dispatch number (C++) 305
E2144: Matching base class function 'function' is not dynamic (C++) 305
E2145: Functions 'function1' and 'function2' both use the same dispatch number (C++) 305
E2146: Need an identifier to declare (C++) 305
E2147: 'identifier' cannot start a parameter declaration (C++) 305
E2150: Type mismatch in default argument value (C++) 305
E2152: Default expression may not use local variables (C++) 306
E2153: Define directive needs an identifier (C++) 306
E2155: Too many default cases (C++) 306

xiii
RAD Studio

E2156: Default outside of switch (C++) 306


E2158: Operand of 'delete' must be non-const pointer (C++) 306
E2159: Trying to derive a far class from the huge base 'base' (C++) 306
E2160: Trying to derive a far class from the near base 'base' (C++) 306
E2161: Trying to derive a huge class from the far base 'base' (C++) 307
E2162: Trying to derive a huge class from the near base 'base' (C++) 307
E2163: Trying to derive a near class from the far base 'base' (C++) 307
E2164: Trying to derive a near class from the huge base 'base' (C++) 307
E2165: Destructor cannot have a return type specification (C++) 307
E2166: Destructor for 'class' is not accessible (C++) 307
E2167: 'function' was previously declared with the language 'language' (C++) 307
E2168: Division by zero (C++) 308
E2169: 'identifier' specifies multiple or duplicate access (C++) 308
E2170: Base class 'class' is included more than once (C++) 308
E2171: Body has already been defined for function 'function' (C++) 308
E2172: Duplicate case (C++) 308
E2175: Too many storage classes in declaration (C++) 308
E2176: Too many types in declaration (C++) 309
E2179: virtual specified more than once (C++) 309
E2007: Dispid only allowed in __automated sections (C++) 309
Divide error (C++) 309
E2182: Illegal parameter to __emit__ (C++) 309
E2183: File must contain at least one external declaration (C++) 309
E2184: Enum syntax error (C++) 310
E2185: The value for 'identifier' is not within the range of 'type-name' (C++) 310
E2186: Unexpected end of file in comment started on line 'number' (C++) 310
E2187: Unexpected end of file in conditional started on line 'number' (C++) 310
E2188: Expression syntax (C++) 310
E2190: Unexpected closing brace (C++) 311
E2189: extern variable cannot be initialized (C++) 311
E2344: Earlier declaration of 'identifier' (C++) 311
E2192: Too few parameters in call (C++) 311
E2193: Too few parameters in call to 'function' (C++) 311
E2194: Could not find file 'filename' (C++) 311
E2197: File name too long (C++) 311
E2195: Cannot evaluate function call (C++) 312
E2198: Not a valid expression format type (C++) 312
E2200: Functions may not be part of a struct or union (C++) 312
Floating point error: Divide by 0 OR Floating point error: Domain OR Floating point error: Overflow (C++) 312

xiv
RAD Studio

Floating point error: Stack fault (C++) 312


Floating point error: Partial loss of precision OR Floating point error: Underflow (C++) 312
E2201: Too much global data defined in file (C++) 313
E2203: Goto bypasses initialization of a local variable (C++) 313
E2204: Group overflowed maximum size: 'name' (C++) 313
E2206: Illegal character 'character' (0x'value') (C++) 313
E2207: Implicit conversion of 'type1' to 'type2' not allowed (C++) 313
E2208: Cannot access an inactive scope (C++) 313
E2209: Unable to open include file 'filename' (C++) 314
E2210: Reference member 'member' is not initialized (C++) 314
E2212: Function defined inline after use as extern (C++) 314
E2211: Inline assembly not allowed in inline and template functions (C++) 314
F1001: Internal code generator error (C++) 315
E2413: Invalid template declaration (C++) 315
E2070: Invalid use of namespace 'identifier' (C++) 315
E2214: Cannot have a 'non-inline function/static data' in a local class (C++) 315
E2215: Linkage specification not allowed (C++) 315
E2216: Unable to create turboc.$ln (C++) 315
E2218: Templates can only be declared at namespace or class scope (C++) 315
E2217: Local data exceeds segment size limit (C++) 316
E2219: Wrong number of arguments in call of macro 'macro' (C++) 316
E2220: Invalid macro argument separator (C++) 316
E2221: Macro argument syntax error (C++) 316
E2222: Macro expansion too long (C++) 316
E2223: Too many decimal points (C++) 316
E2224: Too many exponents (C++) 316
E2225: Too many initializers (C++) 316
E2226: Extra parameter in call (C++) 317
E2227: Extra parameter in call to function (C++) 317
E2228: Too many error or warning messages (C++) 317
E2233: Cannot initialize a class member here (C++) 317
E2232: Constant/Reference member 'member' in class without constructors (C++) 317
E2229: Member 'member' has the same name as its class (C++) 317
E2234: Memory reference expected (C++) 317
E2231: Member 'member' cannot be used without an object (C++) 318
E2235: Member function must be called or its address taken (C++) 318
O2237: DPMI programs must use the large memory model (C++) 318
E2238: Multiple declaration for 'identifier' (C++) 318
E2239: 'identifier' must be a member function (C++) 319

xv
RAD Studio

E2240: Conversion of near pointer not allowed (C++) 319


E2243: Array allocated using 'new' may not have an initializer (C++) 319
E2244: 'new' and 'delete' not supported (C++) 319
E2245: Cannot allocate a reference (C++) 319
E2309: Inline assembly not allowed (C++) 320
E2250: No base class to initialize (C++) 320
E2254: : expected after private/protected/private (C++) 320
E2255: Use :: to take the address of a member function (C++) 320
E2256: No : following the ? (C++) 320
E2257: , expected (C++) 320
E2258: Declaration was expected (C++) 320
E2259: Default value missing (C++) 321
E2260: Default value missing following parameter 'parameter' (C++) 321
E2263: Exception handling not enabled (C++) 321
E2264: Expression expected (C++) 321
E2266: No file names given (C++) 321
E2265: No file name ending (C++) 321
E2271: Goto statement missing label (C++) 321
E2272: Identifier expected (C++) 321
E2275: Opening brace expected (C++) 322
E2276: ( expected (C++) 322
E2274: < expected (C++) 322
E2277: Lvalue required (C++) 322
E2278: Multiple base classes not supported for Delphi classes (C++) 322
E2280: Member identifier expected (C++) 322
E2279: Cannot find default constructor to initialize member 'identifier' (C++) 323
E2310: Only member functions may be 'const' or 'volatile' (C++) 323
E2311: Non-virtual function 'function' declared pure (C++) 323
E2283: Use . or -> to call 'function' (C++) 323
E2284: Use . or -> to call 'member', or & to take its address (C++) 323
E2285: Could not find a match for 'argument(s)' (C++) 323
E2286: Overloaded function resolution not supported (C++) 324
E2287: Parameter 'number' missing name (C++) 324
E2288: Pointer to structure required on left side of -> or ->* (C++) 324
E2290: 'code' missing ] (C++) 324
E2291: brace expected (C++) 324
E2292: Function should return a value (C++) 324
E2293: ) expected (C++) 325
E2294: Structure required on left side of . or .* (C++) 325

xvi
RAD Studio

E2312: 'constructor' is not an unambiguous base class of 'class' (C++) 325


E2313: Constant expression required (C++) 325
E2296: Templates not supported (C++) 325
E2314: Call of nonfunction (C++) 325
E2321: Declaration does not specify a tag or an identifier (C++) 325
E2297: 'this' can only be used within a member function (C++) 326
E2316: 'identifier' is not a member of 'struct' (C++) 326
E2317: 'identifier' is not a parameter (C++) 326
E2319: 'identifier' is not a public base class of 'classtype' (C++) 326
E2320: Expression of scalar type expected (C++) 326
E2302: No type information (C++) 327
E2303: Type name expected (C++) 327
E2304: 'Constant/Reference' variable 'variable' must be initialized (C++) 327
E2305: Cannot find 'class::class' ('class'&) to copy a vector OR Cannot find 'class'::operator=('class'&) to 327
copy a vector (C++)
E2306: Virtual base classes not supported for Delphi classes (C++) 328
E2308: do statement must have while (C++) 328
E2322: Incorrect number format (C++) 328
E2324: Numeric constant too large (C++) 328
E2282: Namespace name expected (C++) 328
E2334: Namespace member 'identifier' declared outside its namespace (C++) 328
E2325: Illegal octal digit (C++) 329
E2329: Invalid combination of opcode and operands (C++) 329
E2327: Operators may not have default argument values (C++) 329
E2330: Operator must be declared as function (C++) 329
E2333: Class member 'member' declared outside its class (C++) 329
E2335: Overloaded 'function name' ambiguous in this context (C++) 329
E2339: Cannot overload 'main' (C++) 330
E2336: Pointer to overloaded function 'function' doesn't match 'type' (C++) 330
E2337: Only one of a set of overloaded functions can be "C" (C++) 330
E2338: Overlays only supported in medium, large, and huge memory models (C++) 330
E2340: Type mismatch in parameter 'number' (C++) 330
E2341: Type mismatch in parameter 'number' in call to 'function' (C++) 331
E2342: Type mismatch in parameter 'parameter' (C++) 331
E2343: Type mismatch in parameter 'parameter' in call to 'function' (C++) 331
E2345: Access can only be changed to public or protected (C++) 331
E2349: Nonportable pointer conversion (C++) 331
E2350: Cannot define a pointer or reference to a reference (C++) 332
E2352: Cannot create instance of abstract class 'class' (C++) 332

xvii
RAD Studio

E2354: Two operands must evaluate to the same type (C++) 332
E2355: Recursive template function: 'x' instantiated 'y' (C++) 333
E2356: Type mismatch in redeclaration of 'identifier' (C++) 333
E2357: Reference initialized with 'type1', needs lvalue of type 'type2' (C++) 333
E2358: Reference member 'member' needs a temporary for initialization (C++) 333
E2360: Invalid register combination (e.g. [BP+BX]) (C++) 334
E2361: 'specifier' has already been included (C++) 334
E2362: Repeat count needs an lvalue (C++) 334
E2363: Attempting to return a reference to local variable 'identifier' (C++) 334
E2364: Attempting to return a reference to a local object (C++) 334
E2365: Member pointer required on right side of .* or ->* (C++) 335
E2366: Can't inherit non-RTTI class from RTTI base OR E2367 Can't inherit RTTI class from non-RTTI 335
base (C++)
E2368: RTTI not available for expression evaluation (C++) 335
E2371: sizeof may not be applied to a bit field (C++) 335
E2372: sizeof may not be applied to a function (C++) 335
E2373: Bit field cannot be static (C++) 335
E2374: Function 'function' cannot be static (C++) 335
Stack overflow (C++) 335
E2376: statement missing (C++) 336
E2377: statement missing ) (C++) 336
E2378: do-while or for statement missing ; (C++) 336
E2379: Statement missing ; (C++) 336
E2380: Unterminated string or character constant (C++) 336
E2381: Structure size too large (C++) 336
E2382: Side effects are not allowed (C++) 336
E2383: Switch selection expression must be of integral type (C++) 336
E2433: Specialization after first use of template (C++) 337
E2384: Cannot call near class member function with a pointer of type 'type' (C++) 337
E2390: Type mismatch in parameter 'number' in template class name 'template' (C++) 337
E2391: Type mismatch in parameter 'parameter' in template class name 'template' (C++) 337
E2394: Too few arguments passed to template 'template' (C++) 337
E2395: Too many arguments passed to template 'template' (C++) 338
E2396: Template argument must be a constant expression (C++) 338
E2401: Invalid template argument list (C++) 338
E2400: Nontype template argument must be of scalar type (C++) 338
E2415: Template functions may only have 'type-arguments' (C++) 338
E2425: 'member' is not a valid template type member (C++) 338
E2428: Templates must be classes or functions (C++) 338

xviii
RAD Studio

E2432: 'template' qualifier must name a template class or function instance' (C++) 339
E2442: Two consecutive dots (C++) 339
E2443: Base class 'class' is initialized more than once (C++) 339
E2444: Member 'member' is initialized more than once (C++) 339
E2445: Variable 'identifier' is initialized more than once (C++) 339
E2446: Function definition cannot be a typedef'ed declaration (C++) 339
E2132: Templates and overloaded operators cannot have C linkage (C++) 339
E2447: 'identifier' must be a previously defined enumeration tag (C++) 340
E2448: Undefined label 'identifier' (C++) 340
E2449: Size of 'identifier' is unknown or zero (C++) 340
E2450: Undefined structure 'structure' (C++) 340
E2451: Undefined symbol 'identifier' (C++) 340
E2453: Size of the type 'identifier' is unknown or zero (C++) 340
E2452: Size of the type is unknown or zero (C++) 341
E2454: union cannot be a base type (C++) 341
E2455: union cannot have a base type (C++) 341
E2456: Union member 'member' is of type class with 'constructor' (or destructor, or operator =) (C++) 341
E2461: '%s' requires run-time initialization/finalization (C++) 341
E2464: 'virtual' can only be used with member functions (C++) 341
E2465: unions cannot have virtual member functions (C++) 342
E2466: void & is not a valid type (C++) 342
E2467: 'Void function' cannot return a value (C++) 342
E2468: Value of type void is not allowed (C++) 342
E2469: Cannot use tiny or huge memory model with Windows (C++) 342
E2006: CodeGuarded programs must use the large memory model and be targeted for Windows (C++) 342
E2269: The function 'function' is not available (C++) 342
E2124: Invalid function call (C++) 343
E2213: Invalid 'expression' in scope override (C++) 343
E2236: Missing 'identifier' in scope override (C++) 343
Pure virtual function called (C++) 343
E2095: String literal not allowed in this context (C++) 343
Unexpected termination during compilation [Module Seg#:offset] OR Unexpected termination during linking 343
[Module Seg#:offset] (C++)
E2012: Cannot take address of 'main' (C++) 344
E2016: Ambiguous override of virtual base member 'base_function': 'derived_function' (C++) 344
E2021: Array must have at least one element (C++) 344
E2023: Array of references is not allowed (C++) 344
E2032: Illegal use of closure pointer (C++) 344
E2040: Declaration terminated incorrectly (C++) 345

xix
RAD Studio

E2047: Bad 'directive' directive syntax (C++) 345


E2049: Class type 'type' cannot be marked as __declspec(delphireturn) (C++) 345
E2052: Dynamic function 'function' conflicts with base class 'class' (C++) 345
E2057: Exception specification not allowed here (C++) 345
E2058: Exception handling variable may not be used here (C++) 346
E2065: Using namespace symbol 'symbol' conflicts with intrinsic of the same name (C++) 346
E2067: 'main' must have a return type of int (C++) 346
E2073: Nothing allowed after pragma option pop (C++) 346
E2091: Functions cannot return arrays or functions (C++) 346
E2093: Operator 'operator' not implemented in type 'type' for arguments of the same type (C++) 346
E2094: Operator 'operator' not implemented in type 'type' for arguments of type 'type' (C++) 346
E2097: Explicit instantiation only allowed at file or namespace scope (C++) 347
E2098: Explicit specialization declarator "template<>" now required (C++) 347
E2099: Explicit specialization only allowed at file or namespace scope (C++) 347
E2101: 'export' keyword must precede a template declaration (C++) 347
E2103: Explicit instantiation must be used with a template class or function (C++) 347
E2106: Explicit specialization must be used with a template class or function (C++) 347
E2112: Unknown unit directive: 'directive' (C++) 347
E2118: Bit fields must have integral type (C++) 348
E2120: Cannot call 'main' from within the program (C++) 348
E2125: Compiler could not generate copy constructor for class 'class' OR Compiler could not generate 348
default constructor for class 'class' OR Compiler could not generate operator = for class 'class' (C++)
E2130: Circular property definition (C++) 348
E2131: Objects of type 'type' cannot be initialized with { } (C++) 348
E2148: Default argument value redeclared for parameter 'parameter' (C++) 348
E2149: Default argument value redeclared (C++) 349
E2151: Type mismatch in default value for parameter 'parameter' (C++) 349
E2157: Deleting an object requires exactly one conversion to pointer operator (C++) 349
E2173: Duplicate handler for 'type1', already had 'type2' (C++) 349
E2174: The name handler must be last (C++) 349
E2177: Redeclaration of #pragma package with different arguments (C++) 350
E2178: VIRDEF name conflict for 'function' (C++) 350
E2180: Dispid number already used by identifier (C++) 350
E2181: Cannot override a 'dynamic/virtual' with a 'dynamic/virtual' function (C++) 350
E2202: Goto into an exception handler is not allowed (C++) 350
E2205: Illegal type type in __automated section (C++) 350
E2242: Specifier requires Delphi style class type (C++) 351
E2247: 'member' is not accessible (C++) 351
E2248: Cannot find default constructor to initialize array element of type 'class' (C++) 351

xx
RAD Studio

E2251: Cannot find default constructor to initialize base class 'class' (C++) 352
E2252: 'catch' expected (C++) 352
E2253: Calling convention must be attributed to the function type, not the closure (C++) 352
E2261: Use of dispid with a property requires a getter or setter (C++) 353
E2262: '__except' or '__finally' expected following '__try' (C++) 353
E2270: > expected (C++) 353
E2273: 'main' cannot be declared as static or inline (C++) 353
E2281: Identifier1 requires definition of Identifier2 as a pointer type (C++) 353
E2289: __published or __automated sections only supported for Delphi classes (C++) 353
E2298: Cannot generate 'function' from template function 'template' (C++) 354
E2301: Cannot use templates in closure arguments -- use a typedef (C++) 354
E2307: Type 'type' is not a defined class with virtual functions (C++) 354
E2315: 'Member' is not a member of 'class', because the type is not yet defined (C++) 354
E2318: 'type' is not a polymorphic class type (C++) 354
E2323: Illegal number suffix (C++) 355
E2326: Use __declspec(spec1[, spec2]) to combine multiple __declspecs (C++) 355
E2328: Classes with properties cannot be copied by value (C++) 355
E2331: Number of allowable option contexts exceeded (C++) 355
E2332: Variable 'variable' has been optimized and is not available (C++) 355
E2476: Cannot overload 'function' (C++) 356
E2346: 'x' access specifier of property 'property' must be a member function (C++) 356
E2347: Parameter mismatch in access specifier 'specifier' of property 'property' (C++) 356
E2348: Storage specifier not allowed for array properties (C++) 356
E2351: Static data members not allowed in __published or __automated sections (C++) 357
E2353: Class 'classname' is abstract because of 'member = 0' (C++) 357
E2359: Reference member 'member' initialized with a non-reference parameter (C++) 357
E2369: Cannot use the result of a property assignment as an rvalue' (C++) 358
E2370: Simple type name expected (C++) 358
E2398: Template function argument 'argument' not used in argument types (C++) 358
E2419: Error while instantiating template 'template' (C++) 358
E2424: Template class nesting too deep: 'class' (C++) 358
E2457: Delphi style classes must be caught by reference (C++) 359
E2458: Delphi classes have to be derived from Delphi classes (C++) 359
E2459: Delphi style classes must be constructed using operator new (C++) 359
E2460: Delphi style classes require exception handling to be enabled (C++) 360
E2463: 'base' is an indirect virtual base class of 'class' (C++) 360
Null pointer assignment (C++) 360
E2268: Call to undefined function 'function' (C++) 360
E2375: Assembler stack overflow (C++) 360

xxi
RAD Studio

Initializing enumeration with type (C++) 360


<name> is not a valid identifier (C++) 361
Example for "Temporary used ..." error messages (C++) 361
Application is running (C++) 361
Printf/Scanf floating-point formats not linked (C++) 361
W8000: Ambiguous operators need parentheses (C++) 362
W8060: Possibly incorrect assignment (C++) 362
W8002: Restarting compile using assembly (C++) 362
W8003: Unknown assembler instruction (C++) 362
W8052: Base initialization without a class name is now obsolete (C++) 362
E2117: Bit fields must be signed or unsigned int (C++) 363
W8064: Call to function with no prototype (C++) 363
W8065: Call to function 'function' with no prototype (C++) 363
W8009: Constant is long (C++) 363
W8008: Condition is always true OR W8008 Condition is always false (C++) 363
W8012: Comparing signed and unsigned values (C++) 364
W8010: Continuation character \ found in // comment (C++) 364
W8080: 'identifier' is declared but never used (C++) 364
W8014: Declaration ignored (C++) 365
W8068: Constant out of range in comparison (C++) 365
W8016: Array size for 'delete' ignored (C++) 365
W8082: Division by zero (C++) 365
W8018: Assigning 'type' to 'enumeration' (C++) 365
W8006: Initializing 'identifier' with 'identifier' (C++) 366
W8001: Superfluous & with function (C++) 366
W8020: 'identifier' is declared as both external and static (C++) 366
W8007: Hexadecimal value contains more than three digits (C++) 366
W8024: Base class 'class1' is also a base class of 'class2' (C++) 366
W8022: 'function1' hides virtual function 'function2' (C++) 367
W8023: Array variable 'identifier' is near (C++) 367
W8061: Initialization is only partially bracketed (C++) 367
W8038: constant member 'identifier' is not initialized (C++) 367
W8071: Conversion may lose significant digits (C++) 367
W8043: Macro definition ignored (C++) 368
W8017: Redefinition of 'x' is not identical (C++) 368
W8079: Mixing pointers to different 'char' types (C++) 368
W8067: Both return and return with a value used (C++) 368
W8048: Use qualified name to access member type 'identifier' (C++) 368
W8039: Constructor initializer list ignored (C++) 368

xxii
RAD Studio

W8040: Function body ignored (C++) 369


W8042: Initializer for object 'x' ignored (C++) 369
W8044: #undef directive ignored (C++) 369
W8037: Non-const function 'function' called for const object (C++) 369
W8051: Non-volatile function 'function' called for volatile object (C++) 369
W8019: Code has no effect (C++) 370
W8057: Parameter 'parameter' is never used (C++) 370
W8070: Function should return a value (C++) 370
W8047: Declaration of static function function ignored (C++) 370
W8041: Negating unsigned value (C++) 370
W8054: Style of function definition is now obsolete (C++) 371
W8025: Ill-formed pragma (C++) 371
W8063: Overloaded prefix operator 'operator' used as a postfix operator (C++) 371
W8015: Declare 'type' prior to use in prototype (C++) 371
W8069: Nonportable pointer conversion (C++) 372
W8066: Unreachable code (C++) 372
W8029: Temporary used for parameter '???' (C++) 372
W8031: Temporary used for parameter 'parameter' OR W8029 Temporary used for parameter 'number' OR 372
W8030 Temporary used for parameter 'parameter' in call to 'function' OR W8032 Temporary used for
parameter 'number' in call to 'function' (C++)
W8032: Temporary used for parameter 2 in call to '???' (C++) 373
W8028: Temporary used to initialize 'identifier' (C++) 373
W8074: Structure passed by value (C++) 373
W8011: Nonportable pointer comparison (C++) 374
W8075: Suspicious pointer conversion (C++) 374
W8059: Structure packing size has changed (C++) 374
W8045: No declaration for function 'function' (C++) 374
W8073: Undefined structure 'structure' (C++) 375
W8013: Possible use of 'identifier' before definition (C++) 375
W8004: 'identifier' is assigned a value that is never used (C++) 375
W8081: Void functions may not return a value (C++) 375
W8078: Throw expression violates exception specification (C++) 376
W8021: Handler for 'type1' hidden by previous handler for 'type2' (C++) 376
W8056: Integer arithmetic overflow (C++) 376
W8035: User-defined message (C++) 376
W8049: Use '> >' for nested templates Instead of '>>' (C++) 376
W8026: Functions with exception specifications are not expanded inline (C++) 377
W8058: Cannot create pre-compiled header: 'reason' (C++) 377
W8046: Pragma option pop with no matching option push (C++) 377
W8050: No type OBJ file present; disabling external types option. (C++) 377

xxiii
RAD Studio

W8027: Functions containing 'statement' are not expanded inline (C++) 378
W8036: Non-ANSI keyword used: 'keyword' (C++) 378
W8053: 'ident' is obsolete (C++) 379
W8103: Path 'path' and filename 'filename' exceed maximum size of 'n' (C++) 379
W8062: Previous options and warnings not restored (C++) 379
W8055: Possible overflow in shift operation (C++) 379
W8072: Suspicious pointer arithmetic (C++) 379
W8033: Conversion to 'type' will fail for members of virtual base 'class' (C++) 380
W8034: Maximum precision used for member pointer type 'type' (C++) 380
E2537: Cannot create instance of abstract class (C++) 380
E2018: Cannot catch 'identifier' -- ambiguous base class 'identifier' (C++) 380
E2550: No arguments can follow a variadic template in an argument list (C++) 381
E2538: Static assert failed: '%s' (C++) 381
E2548: ... was unexpected; expression is not a variadic template pattern (C++) 381
E2543: Combination of options 'options' is not permitted (C++) 381
E2549: Operand is not a parameter pack (C++) 381
E2544: Function exception specifications do not match (C++) 381
E2536: Incomplete type cannot be part of a exception declaration (C++) 381
E2535: Incomplete type cannot be part of a throw specification (C++) 382
E2532: Constant in new expression requires an initializer (C++) 382
E2541: Attribute '%s' cannot be set (C++) 382
E2545: Enum underlying type must be an integral (C++) 382
E2546: Redeclaration of enum is not identical (C++) 382
E2533: Parameter mismatch (wanted typename) (C++) 382
E2534: Integral constant expression expected (C++) 382
E2531: Parameter is an incomplete type (C++) 383
E2539: Constant expression expected (C++) 383
E2547: ... expected (C++) 383
E2540: String literal expected (C++) 383
E2552: This feature is not (yet) supported (C++) 383
E2542: '%s' is marked 'final' and cannot be overriden (C++) 383
E2553: %s mismatch in redeclaration of '%s' (C++) 383
E2551: Return statement not allowed in __finally block (C++) 384
W8104: Local Static with constructor dangerous for multi-threaded apps (C++) 384
W8106: %s are deprecated (C++) 384
W8110: Duplicate '%s' attribute directive ignored (C++) 384
W8108: Constant in new expression requires an initializer (C++) 384
W8113: Inline function was declared with 'extern template' (C++) 384
W8109: Parameter '%s' is a dependent type (C++) 385

xxiv
RAD Studio

W8105: Reference/Constant member 'identifier' in class without constructors (C++) 385


W8107: Type name expected (C++) 385
W8112: Unresolved dependencies in expression (C++) 385
C++ Language Guide 385
C++ Specifics 385
Keywords, Alphabetical Listing 513
Keywords, By Category 579
Language Structure 586
Lexical Elements 660
The Preprocessor 687
C Runtime Library Reference 711
alloc.h 712
assert.h 730
conio.h 732
ctype.h 766
delayimp.h 787
direct.h 790
dirent.h 792
dir.h 799
dos.h 818
errno.h 831
except.h 838
fastmath.h 842
fcntl.h 844
float.h 853
io.h 864
limits.h 913
locale.h 915
malloc.h 920
math.h 921
mem.h 959
new.h 968
process.h 971
setjmp.h 993
share.h 996
signal.h 997
stdarg.h 1003
stddef.h 1004
stdio.h 1006

xxv
RAD Studio

stdlib.h 1080
string.h 1139
sys\stat.h 1186
sys\timeb.h 1190
sys\types.h 1192
time.h 1193
typeinfo.h 1211
utime.h 1213
values.h 1214

Win32 Developer's Guide 1217


Component Writer's Guide 1217
Creating a graphic component 1218
Creating events 1231
Creating methods 1241
Creating properties 1245
Customizing a grid 1258
Extending the IDE 1276
Handling messages 1298
Introduction to component creation 1310
Making a control data aware 1325
Making components available at design time 1339
Making a dialog box a component 1358
Modifying an existing component 1363
Object-oriented programming for component writers 1367
Using graphics in components 1376
Developing COM-based Applications 1381
COM basics 1382
Creating an Active Server Page 1400
Using ActiveX controls 1406
Creating COM clients 1418
Creating simple COM servers 1427
Working with type libraries 1441
Developing Database Applications 1469
Working with ADO components 1470
Connecting to databases 1495
Creating multi-tiered applications 1510
Creating reports with Rave Reports 1551
Designing database applications 1556
Understanding datasets 1573

xxvi
RAD Studio

Using the Borland Database Engine 1637


Using client datasets 1700
Using data controls 1743
Using decision support components 1779
Using provider components 1805
Using dbExpress Components 1821
Using XML in database applications 1840
Working with field components 1849
Programming with Delphi 1879
Building applications, components, and libraries 1879
Creating international applications 1920
Delphi programming fundamentals 1935
Deploying applications 1938
Developing the application user interface 1955
Exception handling 2014
Types of controls 2031
Understanding the component library 2053
Using the object model 2062
Using the VCL/RTL 2082
Working with components 2142
Working with controls 2149
Working with graphics and multimedia 2169
Working with packages and components 2208
Writing multi-threaded applications 2224
Writing Internet Applications 2243
Creating Internet server applications 2243
Using IntraWeb (VCL for the Web) 2254
Using Web Broker 2261
Using Web Services 2289
Using WebSnap 2310
Working with sockets 2335
Working with XML documents 2351

Index a

xxvii
1 RAD Studio

1 Concepts
Topics
Name Description
Debugging C++ Applications with CodeGuard Error Reporting ( see page 3) CodeGuard provides runtime debugging for C++ applications developed with
RAD Studio. CodeGuard reports errors that are not caught by the compiler
because they do not violate syntax rules. CodeGuard tracks runtime libraries with
full support for multithreaded applications.
Developing Database Applications for the Win32 Platform ( see page 13) The Borland Database Engine (BDE) has been deprecated, so it will not be
enhanced. For instance, BDE will never have Unicode support. You should not
undertake new development with BDE. Consider migrating your existing
database applications from BDE to dbExpress.
Database applications let users interact with the information that is stored in the
databases. Databases provide structure for the information, and allow it to be
shared among different applications.
Delphi provides support for relational database applications. Relational
databases organize information into tables, which contain rows (records) and
columns (fields). These tables can be manipulated by simple operations known
as... more ( see page 13)
Developing Interoperable Applications ( see page 29) RAD Studio provides wizards and classes to make it easy to implement
applications based on the Component Object Model (COM) from Microsoft. With
these wizards, you can create COM-based classes and components to use within
applications or you can create fully functional COM clients or servers that
implement COM objects, Automation servers (including Active Server Objects),
ActiveX controls, or ActiveForms.
Developing Reports for Your Win32 Applications ( see page 35) RAD Studio ships with Rave Reports from Nevrona. Using the report
components, you can build full-featured reports for your applications. You can
create solutions that include reporting capabilities which can be used and
customized by your customers. Additionally, the ComponentOne tools that ship
with RAD Studio include components for creating and generating reports.
Developing Applications with VCL Components ( see page 36) The Visual Component Library (VCL) is a set of visual components for the rapid
development of Windows applications in the Delphi language.
VCL contains a wide variety of visual, non-visual, and utility classes for tasks
such as building Windows applications, web applications, database applications,
and console applications.
Developing Web Applications with WebSnap ( see page 41) This section provides a conceptual background for building WebSnap
applications using RAD Studio. WebSnap makes it easier to build Web server
applications that deliver complex, data-driven Web pages. WebSnap's support
for multiple modules and for server-side scripting makes development and
maintenance easier for teams of developers and Web designers.
Please note that WebSnap is being deprecated in RAD Studio. Although
WebSnap is still documented in the online help, the WebSnap product is no
longer fully supported. As an alternative, you should begin using IntraWeb (VCL
for the Web). IntraWeb ( see page 2254) is documented in this online help. For
more documentation on VCL... more ( see page 41)

1
RAD Studio 1

Developing Web Services with Win32 Applications ( see page 44) Web Services are self-contained modular applications that can be published and
invoked over the Internet. Web Services provide well-defined interfaces that
describe the services provided. Unlike Web server applications that generate
Web pages for client browsers, Web Services are not designed for direct human
interaction. Rather, they are accessed programmatically by client applications.
This section gives an overview of web services and web services support.
Developing Windows Applications ( see page 45) Windows provides a traditional approach to developing user interfaces,
client/server applications, controls, and application logic. This section provides an
overview of Windows application development using RAD Studio for Win32 and
outlines the steps you would use to build a simple Windows project.

2
1.1 Debugging C++ Applications with RAD Studio CodeGuard Errors

1.1 Debugging C++ Applications with CodeGuard


Error Reporting
CodeGuard provides runtime debugging for C++ applications developed with RAD Studio. CodeGuard reports errors that are not
1
caught by the compiler because they do not violate syntax rules. CodeGuard tracks runtime libraries with full support for
multithreaded applications.

Topics
Name Description
CodeGuard Errors ( see page 3) CodeGuard reports four types of runtime errors.
CodeGuard Overview ( see page 9) CodeGuard provides runtime debugging for C++ applications developed with
RAD Studio. CodeGuard reports errors that are not caught by the compiler
because they do not violate syntax rules. CodeGuard tracks runtime libraries with
full support for multithreaded applications.
CodeGuard provides two principal types of coverage:

• Memory and Resource Use


• Function Call Validation
CodeGuard Warnings ( see page 10) CodeGuard can report situations where your application may access memory
beyond a buffer's maximum size. Warnings are available for three types of
runtime library functions.

1.1.1 CodeGuard Errors


CodeGuard reports four types of runtime errors.

Topics
Name Description
Access Errors ( see page 4) Access errors result from improper memory management.
When CodeGuard detects accesses to freed memory blocks or deleted objects, it
can identify where each block was allocated and deleted. Enable the Delay Free
option using the CodeGuard Configuration dialog box to use this feature.
The following are types of access errors:

• Access in freed memory


• Access in uninitialized stack
• Access in invalid stack
Exception Errors ( see page 5) When a system exception occurs, CodeGuard reports the runtime error using
information provided by the operating system. If possible, the CodeGuard log
shows where your application caused the exception. CodeGuard does not trap or
redirect the exception or otherwise interfere with normal program behavior.
The following exceptions illustrate how CodeGuard exception reporting:

• General Protection Fault


• Divide by zero
Function Failure Errors ( see page 6) CodeGuard reports function calls that fail, as indicated by their return value.
In the following example, the close function is given an invalid file handle, which
causes it to return a value indicating that it was unable to close a file.

3
CodeGuard Errors RAD Studio 1.1 Debugging C++ Applications with

Resource Errors ( see page 7) Resources are memory blocks (allocated with functions like malloc,
GlobalAlloc) and object arrays, such as file handles, stream handles,
modules, and items returned by new[].
The following runtime error examples illustrate how CodeGuard reports improper
use of resources:

• Bad parameter
• Reference to freed resource
• Resource type mismatch
1
• Resource leaks
• Resource from different RTL

1.1.1.1 Access Errors


Access errors result from improper memory management.

When CodeGuard detects accesses to freed memory blocks or deleted objects, it can identify where each block was allocated
and deleted. Enable the Delay Free option using the CodeGuard Configuration dialog box to use this feature.

The following are types of access errors:

• Access in freed memory


• Access in uninitialized stack
• Access in invalid stack
Access In Freed Memory
In the following example, CodeGuard identifies the line where an invalid access occurrs. CodeGuard then indicates where the
memory block was allocated and subsequently freed.
Error 00004. 0x100430 (Thread 0xFFF87283):
Access in freed memory: Attempt to access 19 byte(s) at 0x00B423DC.
strcpy(0x00B423DC, 0x004091CA ["Copy to free block"])
| lang.cpp line 106:
|
| free(buf_h);
|> strcpy(buf_h, "Copy to free block");
|
| //-----------------------//
Call Tree:
0x004011F1(=LANG.EXE:0x01:0001F1) lang.cpp#106
0x00407EE5(=LANG.EXE:0x01:006EE5)

The memory block (0x00B423DC) [size: 21 bytes] was allocated with malloc
| lang.cpp line 80:
| char * pad = (char *) malloc(200);
| // An array in the RTL heap.
|> char * buf_h = (char *) malloc(21);
| char * p;
| // A scratch buffer.
Call Tree:
0x004011A1(=LANG.EXE:0x01:0001A1) lang.cpp#80
0x00407EE5(=LANG.EXE:0x01:006EE5)

The memory block (0x00B423DC) was freed with free


| lang.cpp line 105:
| //-------------//
|
|> free(buf_h);
| strcpy(buf_h, "Copy to free block");

4
1.1 Debugging C++ Applications with RAD Studio CodeGuard Errors

|
Call Tree:
0x004011E5(=LANG.EXE:0x01:0001E5) lang.cpp#105
0x00407EE5(=LANG.EXE:0x01:006EE5)
Access In Uninitialized Stack
In the following example, the pointer p became invalid when getBadLocal returned from execution. No additional information is
provided because the stack frame for getBadLocal was automatically removed.
Error 00005. 0x120400 (Thread 0xFFF87283): 1
Access in uninitialized stack: Attempt to access 20 byte(s) at 0x0072FC88.
memcpy(0x0072FCC4, 0x0072FC88, 0x14 [20])
| lang.cpp line 112:
| //-----------------------//
| p = getBadLocal();
|> memcpy(buffer, p, 20);
|
| //-------------//
Call Tree:
0x00401208(=LANG.EXE:0x01:000208) lang.cpp#112
0x00407EE5(=LANG.EXE:0x01:006EE5)
Access In Invalid Stack
In the following example, an allocation was made for buf_s on the stack. However, the strcpy function writes just below the
beginning of the valid stack region. CodeGuard identifies this as an error even if the string is only one byte long.
Error 00002. 0x110400 (Thread 0xFFF87283):
Access in invalid stack: Attempt to access 22 byte(s) at 0x0072FD8F.
strcpy(0x0072FD8F, 0x00409188 ["This string is long!\n"])
| LANG.CPP line 93:
|
| // Stack underrun:
|> strcpy(buf_s -1, "This string is long!\n");
|
| // Global data overrun:
Call Tree:
0x004011C5(=LANG.EXE:0x01:0001C5) LANG.CPP#93
0x00407EED(=LANG.EXE:0x01:006EED)

1.1.1.2 Exception Errors


When a system exception occurs, CodeGuard reports the runtime error using information provided by the operating system. If
possible, the CodeGuard log shows where your application caused the exception. CodeGuard does not trap or redirect the
exception or otherwise interfere with normal program behavior.

The following exceptions illustrate how CodeGuard exception reporting:

• General Protection Fault


• Divide by zero
General Protection Fault
In the following example, CodeGuard provides information on a general protection fault (Intel system exception 0xD). In addition
to the location of the source code that caused the exception, the log shows where the memory was allocated and subsequently
freed. The reported incorrect value is a result of accessing a byte pattern that CodeGuard uses to identify invalid memory
locations.
Error 00003. 0x400003 (Thread 0x0090):
Exception 0xC0000005: Access violation at 0x80828082.
| gpfault.c line 32:
| {¬
| q = p[3];

5
CodeGuard Errors RAD Studio 1.1 Debugging C++ Applications with

|> *q = 1;
| }
| }
Call Tree:
0x004010E5(=GPFAULT.EXE:0x01:0000E5) gpfault.c#32
0x00406B29(=GPFAULT.EXE:0x01:005B29)

The bogus value (0x80828082) was most likely retrieved by accessing a(n)
memory block that has already been freed
The memory block (0x008322A4) [size: 16 bytes] was allocated with malloc
1 | gpfault.c line 17:
| int *q;
|
|> p = malloc(sizeof(*p) * 4);
|
| /* Initialize p */
Call Tree:
0x00401094(=GPFAULT.EXE:0x01:000094) gpfault.c#17
0x00406B29(=GPFAULT.EXE:0x01:005B29)

The memory block (0x008322A4) was freed with free


| gpfault.c line 17:
| int *q;
|
|> p = malloc(sizeof(*p) * 4);
|
| /* Initialize p */
Call Tree:
0x00401094(=GPFAULT.EXE:0x01:000094) gpfault.c#17
0x00406B29(=GPFAULT.EXE:0x01:005B29)
Divide By Zero
In the following example, CodeGuard identifies the location in source code where division by zero (Intel system exception 0x0)
occurred.
Error 00001. 0x400000 (Thread 0x008B):
Exception 0xC0000094:
| ZERODIV.C line 9:
| {¬
| x = 1;
|> return x / y;
| }
|
Call Tree:
0x0040109C(=ZERODIV.EXE:0x01:00009C) ZERODIV.C#9
0x00406321(=ZERODIV.EXE:0x01:005321)

1.1.1.3 Function Failure Errors


CodeGuard reports function calls that fail, as indicated by their return value.

In the following example, the close function is given an invalid file handle, which causes it to return a value indicating that it was
unable to close a file.
Error 00009. 0x820000 (r) (Thread 0xFFF840F1):
Function failure:
close(0x80868086 [-2138668922])=0xFFFFFFFF [-1]
| lang.cpp line 125:
| // uninitialized data usage //
| //--------------------------//
|> close(m->handle);
|
|
Call Tree:

6
1.1 Debugging C++ Applications with RAD Studio CodeGuard Errors

0x00401236(=LANG.EXE:0x01:000236) lang.cpp#125
0x00407EED(=LANG.EXE:0x01:006EED)

1.1.1.4 Resource Errors


Resources are memory blocks (allocated with functions like malloc, GlobalAlloc) and object arrays, such as file handles,
stream handles, modules, and items returned by new[].

The following runtime error examples illustrate how CodeGuard reports improper use of resources: 1
• Bad parameter
• Reference to freed resource
• Resource type mismatch
• Resource leaks
• Resource from different RTL
Bad Parameter
When a resource is passed to a function, CodeGuard checks the runtime arguments. CodeGuard notifies you if it detects a bad
parameter.
Error 00017. 0x310000 (Thread 0xFFF87283):
Bad parameter: A bad file handle (0xEA) has been passed to the function.
close(0xEA [234])
| lang.cpp line 170:
| // using a bad handle //
| //--------------------//
|> close(234);
|
| //----------------------//
Call Tree:
0x00401456(=LANG.EXE:0x01:000456) lang.cpp#170
0x00407EE5(=LANG.EXE:0x01:006EE5)
Reference To Freed Resource
In the following example, CodeGuard reports an attempt to read from a file that has already been closed. The CodeGuard log
shows where the file was opened and subsequently closed.
Error 00020. 0x310030 (Thread 0xFFF840F1):
Reference to freed resource:
read(0x3 [3], 0x0072FCC4, 0x5 [5])
| lang.cpp line 177:
| int i = open("lang.cpp", 0);
| close(i);
|> read (i, buffer, 5);
|
| //--------------//
Call Tree:
0x00401487(=LANG.EXE:0x01:000487) lang.cpp#177
0x00407EED(=LANG.EXE:0x01:006EED)

The file handle (0x00000003) [name: 'lang.cpp'] was opened with open
| lang.cpp line 175:
| // using a freed handle //
| //----------------------//
|> int i = open("lang.cpp", 0);
| close(i);
| read (i, buffer, 5);
Call Tree:
0x0040146C(=LANG.EXE:0x01:00046C) lang.cpp#175
0x00407EED(=LANG.EXE:0x01:006EED)

7
CodeGuard Errors RAD Studio 1.1 Debugging C++ Applications with

The file handle (0x00000003) was closed with close


| lang.cpp line 176:
| //----------------------//
| int i = open("lang.cpp", 0);
|> close(i);
| read (i, buffer, 5);
|
Call Tree:
0x00401477(=LANG.EXE:0x01:000477) lang.cpp#176
1 0x00407EED(=LANG.EXE:0x01:006EED)
Resource Type Mismatch
In the following example, a memory block that was allocated with the new[] operator, and should therefore be released with the
delete[] operator, is instead released with a call to the free function.
Error 00024. 0x350010 (Thread 0xFFF840F1):
Resource type mismatch: a(n) memory block was expected.
free(0x00B42464)
| lang.cpp line 188:
| //---------------//
| char * ss = new char[21];
|> free(ss);
|
| #ifdef __WIN32__
Call Tree:
0x0040149F(=LANG.EXE:0x01:00049F) lang.cpp#188
0x00407EED(=LANG.EXE:0x01:006EED)

The object array (0x00B42464) [size: 21 bytes] was created with new[]
| lang.cpp line 187:
| // type mismatch //
| //---------------//
|> char * ss = new char[21];
| free(ss);
|
Call Tree:
0x00401498(=LANG.EXE:0x01:000498) lang.cpp#187
0x00407EED(=LANG.EXE:0x01:006EED)
Resource Leaks
In the following example, memory has been allocated but is never freed.
The memory block (0x00B42310) [size: 200 bytes] was allocated with malloc
| lang.cpp line 78:
| // An array on the stack.
| char buf_s[21];
|> char * pad = (char *) malloc(200);
| // An array in the RTL heap.
| char * buf_h = (char *) malloc(21);
Call Tree:
0x00401199(=LANG.EXE:0x01:000199) lang.cpp#78
0x00407EE5(=LANG.EXE:0x01:006EE5)
Resource From Different RTL
CodeGuard reports an error if your application allocates, uses, or releases resources in different versions of the runtime library.
This can happen, as the following example illustrates, if you link with a static runtime library but call a DLL.

Note: CodeGuard detects resource type mismatches before it detects mixed versions of the RTL. When the two kinds of error
are combined, CodeGuard will not report the mixed RTLs until you correct the resource type mismatch.

Error 00001. 0x340010 (Thread 0x0062):


Resource from different RTL:

8
1.1 Debugging C++ Applications with RAD Studio CodeGuard Warnings

close(0x3 [3])
| testdll.cpp line 23:
| {¬
| MessageBox(NULL,"RTLMixHandle: DLL closing EXE handle", "TESTDLL.CPP", MB_OK );
|> close( handle );
| return 1;
| }
Call Tree:
0x0032115A(=testdll.dll:0x01:00015A) testdll.cpp#23
0x00401660(=WINAPI.EXE:0x01:000660) filescg.cpp#33
0x00401271(=WINAPI.EXE:0x01:000271) winapi.cpp#122 1
0x77EA15B3
0x00408B9A(=WINAPI.EXE:0x01:007B9A)

The file handle (0x00000003) [name: 'test2.dat'] was opened with open
| filescg.cpp line 32:
|
| MessageBox(NULL,"FilesMixCG: Mixing RTL file handles", "FILESCG.CPP", MB_OK );
|> i = open("test2.dat", O_CREAT, S_IREAD | S_IWRITE );
| RTLMixHandle( i );
| }
Call Tree:
0x00401657(=WINAPI.EXE:0x01:000657) filescg.cpp#32
0x00401271(=WINAPI.EXE:0x01:000271) winapi.cpp#122
0x77EA15B3
0x00408B9A(=WINAPI.EXE:0x01:007B9A)

1.1.2 CodeGuard Overview


CodeGuard provides runtime debugging for C++ applications developed with RAD Studio. CodeGuard reports errors that are not
caught by the compiler because they do not violate syntax rules. CodeGuard tracks runtime libraries with full support for
multithreaded applications.

CodeGuard provides two principal types of coverage:

• Memory and Resource Use


• Function Call Validation
Memory and Resource Use
CodeGuard checks for faulty memory use, improper memory allocation or deallocation, invalid file streams or handles, and
resource leaks caused by improper use of file streams or handles. CodeGuard verifies pointer dereferencing and pointer
arithmetic. CodeGuard can report an error if your program tries to access memory or resources that have already been released.

Function Call Validation


CodeGuard verifies function arguments and reports function failure as indicated by the return value of the function. It validates
Windows resource handles used in function calls.

See Also
CodeGuard Errors ( see page 3)

CodeGuard Warnings ( see page 10)

Using CodeGuard ( see page 48)

9
CodeGuard Warnings RAD Studio 1.1 Debugging C++ Applications with

1.1.3 CodeGuard Warnings


CodeGuard can report situations where your application may access memory beyond a buffer's maximum size. Warnings are
available for three types of runtime library functions.

1 Topics
Name Description
Memory Block Comparison Warnings ( see page 11) Each of the following functions has a parameter that determines the maximum
number of bytes it compares:

1. memcmp
2. memicmp
3. _fmemcmp
4. _fmemicmp
If the Warnings option is enabled for the functions listed
above, CodeGuard verifies that a comparison can be
performed for each memory block passed to the function.
If a memory block is too large, as determined by the
parameter passed to the function, CodeGuard generates
a warning.
If the Warnings option is disabled for the functions listed
above, CodeGuard checks the first byte in each memory
block passed to the function. If the memory block is
invalid, CodeGuard generates... more ( see page 11)
Pathname Merging and Splitting Warnings ( see page 11) Each of the following functions use constants defined in dir.h to determine the
maximum number of bytes to copy to or from a buffer:

1. fnmerge
2. fnsplit
3. getcurdir
String Comparison Warnings ( see page 11) Each of the following functions has a parameter that determines the maximum
number of bytes it compares:

• strncmp
• strnicmp
• strncmpi
• _fstrncmp
• _fstrnicmp
If the Warnings option is enabled for the functions listed,
CodeGuard verifies that a string comparison can be
performed for each buffer passed to the function. If the
buffer size is too large, as determined by the parameter
passed to the function, and the buffer is not
null-terminated, CodeGuard generates a warning.
If the Warnings option is disabled for the functions listed
above, CodeGuard checks the first byte in each memory
block passed to the function. If the... more ( see page 11)

10
1.1 Debugging C++ Applications with RAD Studio CodeGuard Warnings

1.1.3.1 Memory Block Comparison Warnings


Each of the following functions has a parameter that determines the maximum number of bytes it compares:

1. memcmp
2. memicmp
3. _fmemcmp 1
4. _fmemicmp
If the Warnings option is enabled for the functions listed above, CodeGuard verifies that a comparison can be performed for
each memory block passed to the function. If a memory block is too large, as determined by the parameter passed to the
function, CodeGuard generates a warning.
If the Warnings option is disabled for the functions listed above, CodeGuard checks the first byte in each memory block passed
to the function. If the memory block is invalid, CodeGuard generates an error message.

1.1.3.2 Pathname Merging and Splitting Warnings


Each of the following functions use constants defined in dir.h to determine the maximum number of bytes to copy to or from a
buffer:

1. fnmerge
2. fnsplit
3. getcurdir
fnmerge
If the Warnings option is enabled, the output buffer is validated against MAXPATH before fnmerge is called.

If the Warnings option is disabled, the size of the output buffer is validated against the null-terminated string length after
fnmerge is called.

fnsplit
If the Warnings option is enabled, the input buffers are validated against MAXDRIVE, MAXDIR, MAXFILE, and MAXEXT before
fnsplit is called.

If the Warnings option is disabled, the input buffers are validated against the length of the null-terminated string after fnsplit
is called.

getcurdir
If the Warnings option is enabled, the output buffer is validated against MAXDIR before getcurdir is called.

If the Warnings option is disabled, the output buffer is validated against the length of the null-terminated string after getcurdir
is called.

1.1.3.3 String Comparison Warnings


Each of the following functions has a parameter that determines the maximum number of bytes it compares:

• strncmp
• strnicmp
• strncmpi

11
CodeGuard Warnings RAD Studio 1.1 Debugging C++ Applications with

• _fstrncmp
• _fstrnicmp
If the Warnings option is enabled for the functions listed, CodeGuard verifies that a string comparison can be performed for
each buffer passed to the function. If the buffer size is too large, as determined by the parameter passed to the function, and
the buffer is not null-terminated, CodeGuard generates a warning.
If the Warnings option is disabled for the functions listed above, CodeGuard checks the first byte in each memory block passed
to the function. If the memory block is invalid, CodeGuard generates an error message.
1

12
1.2 Developing Database Applications for RAD Studio

1.2 Developing Database Applications for the


Win32 Platform
The Borland Database Engine (BDE) has been deprecated, so it will not be enhanced. For instance, BDE will never have
1
Unicode support. You should not undertake new development with BDE. Consider migrating your existing database applications
from BDE to dbExpress.

Database applications let users interact with the information that is stored in the databases. Databases provide structure for the
information, and allow it to be shared among different applications.

Delphi provides support for relational database applications. Relational databases organize information into tables, which contain
rows (records) and columns (fields). These tables can be manipulated by simple operations known as the relational calculus.

Topics
Name Description
dbGo Overview ( see page 14) dbGo provides the developers with a powerful and logical object model for
programmatically accessing, editing, and updating data from a wide variety of
data sources through OLE DB system interfaces. The most common usage of
dbGo is to query a table or tables in a relational database, retrieve and display
the results in an application, and perhaps allow users to make and save changes
to the data.
The ADO layer of an ADO-based application consists of the latest version of
Microsoft ADO, an OLE DB provider or ODBC driver for the data store access,
client software for the... more ( see page 14)
BDE Overview ( see page 15) Warning: The Borland Database Engine (BDE) has been deprecated, so it will
not be enhanced. For instance, BDE will never have Unicode support. You
should not undertake new development with BDE. Consider migrating your
existing database applications from BDE to dbExpress.
The Borland Database Engine (BDE) is a data-access mechanism that can be
shared by several applications. The BDE defines a powerful library of API calls
that can create, restructure, fetch data from, update, and otherwise manipulate
local and remote database servers. The BDE provides a uniform interface to
access a wide variety of database servers, using drivers... more ( see page 15)
dbExpress Components ( see page 16) dbExpress is a set of lightweight database components that provide fast access
to SQL database servers. For each supported database, dbExpress provides a
driver framework that adapts the server-specific software to a set of uniform
dbExpress interfaces. When you deploy a database application that uses
dbExpress, you include a DLL(the server-specific driver) with the application files
you build.
dbExpress lets you access databases using unidirectional datasets.
Unidirectional datasets are designed for quick lightweight access to database
information, with minimal overhead. Like other datasets, they can send an SQL
command to the database server, and if the command returns a set... more (
see page 16)
Getting Started with InterBase Express ( see page 17) InterBase Express (IBX) is a set of data access components that provide a
means of accessing data from InterBase databases. The InterBase
Administration Components, which require InterBase, are described after the
InterBase data access components.

13
dbGo Overview RAD Studio 1.2 Developing Database Applications for

dbExpress 4 Feature Overview ( see page 22) dbExpress's top level framework and metadata support has been rewritten in
Delphi for RAD Studio 2007. It has new, richer metadata support.
The DbxClient driver remotes the dbExpress 4 framework interface over a
network based transport.
This document discusses the following features:

• dbExpress Framework
• dbExpress Metadata Improvements
• DBXClient Driver
1
• DBXDynalink Driver
• DBTest
Blackfish SQL Overview ( see page 24) The design and implementation of Blackfish SQL emphasizes database
performance, scalability, ease of use, and a strong adherence to industry
standards. Blackfish SQL capabilities include the following:

• Industry standards compliance


• Entry level SQL-92
• Unicode storage of character data
• Unicode-based collation key support for sorting and
indexing
• dbExpress 4 drivers for win32 Delphi and C++
• ADO.NET 2.0 providers for .NET
• JDBC for Java
• JavaBean data access components for Java
• XA/JTA Distributed transactions for Java
• High performance and scalability for demanding online
transaction processing (OLTP) and decision support
system (DSS) applications
• Delphi, C#, and VB.NET stored procedures and triggers...
more ( see page 24)
dbExpress Framework ( see page 26) The dbExpress framework (DBX framework) is a set of abstract classes provided
in the unit DBXCommon. Applications can interface with the framework in several
ways: using the framework directly for both native and managed applications,
and using the dbExpress VCL components that are layered on top of the
framework for both native and managed applications.
Although many applications interface with dbExpress drivers via the dbExpress
VCL components, the DBX framework offers a convenient, lighter weight option
to communicate with a database driver. You can also create a database driver for
dbExpress by extending the frameworks's DBXCommon abstract... more ( see
page 26)
dbExpress Framework Compatibility ( see page 27) Some dbExpress software developed prior to the dbExpress driver framework
(DBX driver framework) has been modified to work with the DBX driver
framework. As a result of these changes, some compatibility issues arise.

1.2.1 dbGo Overview


dbGo provides the developers with a powerful and logical object model for programmatically accessing, editing, and updating
data from a wide variety of data sources through OLE DB system interfaces. The most common usage of dbGo is to query a
table or tables in a relational database, retrieve and display the results in an application, and perhaps allow users to make and
save changes to the data.

The ADO layer of an ADO-based application consists of the latest version of Microsoft ADO, an OLE DB provider or ODBC

14
1.2 Developing Database Applications for RAD Studio BDE Overview

driver for the data store access, client software for the specific database system used (in the case of SQL databases), a
database back-end system accessible to the application (for SQL database systems), and a database. All of these must be
accessible to the ADO-based application for it to be fully functional.

The dbGo category of the Tool Palette hosts the dbGo components. These components let you connect to an ADO data store,
execute commands, and retrieve data from tables in databases using the ADO framework. The components require the latest
version of ADO to be installed on the host computer. Additionally, client software for the target database system (such as
Microsoft SQL Server) must be installed, as well as an OLE DB driver or ODBC driver specific to the particular database system.
1
Most dbGo components have direct counterparts in the components available for other data access mechanisms: a database
connection component, TADOConnection, and various types of datasets. In addition, dbGo includes TADOCommand, a
simple component that is not a dataset but which represents an SQL command to be executed on the ADO data store.

The main dbGo components are:

Components Function
TADOConnection A database connection component that establishes a connection with an ADO data store.
Multiple ADO dataset and command components can share this connection to execute commands,
retrieve data, and operate on metadata.
TRDSConnection A database connection component to marshal data in multi-tier database applications that are built using
ADO-based application servers.
TADODataSet Primary dataset used for retrieving and operating on data.
TADODataSet can retrieve data from a single or multiple tables, can connect directly to a data store, or
use a TADOConnection component
TADOTable A table-type dataset for retrieving and operating on a recordset produced by a single database table.
TADOTable can connect directly to a data store or use a TADOConnection component
TADOQuery A query-type dataset for retrieving and operating on a recordset produced by a valid SQL statement.
TADOQuery can also execute Data Definition Language (DDL) SQL statements. It can connect directly to
a data store or use a TADOConnection component.
TADOStoredProc A stored procedure-type dataset for executing stored procedures.
TADOStoredProc executes stored procedures that may or may not retrieve data. It can connect directly to
a data store or use a TADOConnection component.
TADOCommand A simple component for executing commands (SQL statements that do not return result sets).
TADOCommand can be used with a supporting dataset component, or retrieve a dataset from a table. It
can connect directly to a data store or use a TADOConnection component

See Also
Working with dbGo Components ( see page 1494)

1.2.2 BDE Overview


Warning: The Borland Database Engine (BDE) has been deprecated, so it will not be enhanced. For instance, BDE will never
have Unicode support. You should not undertake new development with BDE. Consider migrating your existing database
applications from BDE to dbExpress.

The Borland Database Engine (BDE) is a data-access mechanism that can be shared by several applications. The BDE defines
a powerful library of API calls that can create, restructure, fetch data from, update, and otherwise manipulate local and remote
database servers. The BDE provides a uniform interface to access a wide variety of database servers, using drivers to connect
to different databases. The components on the BDE category of the Tool Palette enable you to connect to database information

15
dbExpress Components RAD Studio 1.2 Developing Database Applications for

using the BDE.

When deploying BDE-based applications, you must include the BDE with your application. While this increases the size of the
application and the complexity of deployment, the BDE can be shared with other BDE-based applications and provides a broader
range of support for database manipulation. Although you can use the API of the BDE directly in your application, the
components on the BDE category of the Tool Palette wrap most of this functionality for you.

The main BDE components are:

1 Components Function
TTable Retrieves data from a physical database table via the BDE and supplies it to one or more data-aware
components through a DataSource component. Conversely, it also sends data received from a
component to a physical database via the BDE.
TQuery Uses SQL statements to retrieve data from a physical database table via the BDE and supplies it to
one or more data-aware components through a TDataSource component. Conversely, it uses SQL
statements to send data from a component to a physical database via the BDE.
TStoredProc Enables an application to access server stored procedures. It sends data received from a component
to a physical database via the BDE.
TDatabase Sets up a persistent connection to a database, especially a remote database requiring a user login and
password.
TSession Provides global control over a group of database components. A default TSession component is
automatically created for each database application. You must use the TSession component only if
you are creating a multithreaded database application. Each database thread requires its own session
component.
TBatchMove Copies a table structure or its data. It can be used to move entire tables from one database format to
another.
TUpdateSQL Lets you use cached updates support with read-only datasets.
TNestedTable Retrieves the data in a nested dataset field and supplies it to data-aware controls through a
datasource component.

See Also
Using BDE ( see page 60)

Borland Database Engine ( see page 1946)

1.2.3 dbExpress Components


dbExpress is a set of lightweight database components that provide fast access to SQL database servers. For each supported
database, dbExpress provides a driver framework that adapts the server-specific software to a set of uniform dbExpress
interfaces. When you deploy a database application that uses dbExpress, you include a DLL(the server-specific driver) with the
application files you build.

dbExpress lets you access databases using unidirectional datasets. Unidirectional datasets are designed for quick lightweight
access to database information, with minimal overhead. Like other datasets, they can send an SQL command to the database
server, and if the command returns a set of records, retrieve those records. Unidirectional datasets do not buffer data in memory,
which makes them faster and less resource-intensive than other types of dataset. However, because there are no buffered
records, unidirectional datasets are also less flexible than other datasets.

dbExpress connections, tables, views, and stored procedures that show up in a data tree view support drag & drop with native
and managed vcl forms.

16
1.2 Developing Database Applications for RAD Studio Getting Started with InterBase Express

The dbExpress category of the Tool Palette contains components that use dbExpress to access database information. They
are:

Components Function
TSQLConnection Encapsulates a dbExpress connection to a database server
TSQLDataSet Represents any data available through dbExpress, or sends commands to a database
accessed through dbExpress
TSQLQuery A query-type dataset that encapsulates an SQL statement and enables applications to access 1
the resulting records, if any
TSQLTable A table-type dataset that represents all of the rows and columns of a single database table
TSQLStoredProc A stored procedure-type dataset that executes a stored procedure defined on a database
server
TSQLMonitor Intercepts messages that pass between an SQL connection component and a database
server and saves them in a string list
TSimpleDataSet A client dataset that uses an internal TSQLDataSet and TDataSetProvider for fetching data
and applying updates

See Also
Using dbExpress ( see page 72)

Using dbExpress Datasets ( see page 1823)

Configuring TSQL Connection ( see page 53)

Using Data Explorer to get Connection Information ( see page 52)

1.2.4 Getting Started with InterBase Express


InterBase Express (IBX) is a set of data access components that provide a means of accessing data from InterBase databases.
The InterBase Administration Components, which require InterBase, are described after the InterBase data access components.

IBX components
The following components are located on the InterBase tab of the component palette.

TIBTable

TIBQuery

TIBStoredProc

TIBDatabase

TIBTransaction

TIBUpdateSQL

TIBDataSet

TIBSQL

TIBDatabaseInfo

TIBSQLMonitor

17
Getting Started with InterBase Express RAD Studio 1.2 Developing Database Applications for

TIBEvents

TIBExtract

TIBCustomDataSet

Though they are similar to BDE components in name, the IBX components are somewhat different. For each component with a
BDE counterpart, the sections below give a discussion of these differences.
1
There is no simple migration from BDE to IBX applications. Generally, you must replace BDE components with the comparable
IBX components, and then recompile your applications. However, the speed you gain, along with the access you get to the
powerful InterBase features make migration well worth your time.

IBDatabase

Use a TIBDatabase component to establish connections to databases, which can involve one or more concurrent transactions.
Unlike BDE, IBX has a separate transaction component, which allows you to separate transactions and database connections.

To set up a database connection:

1. Drop an IBDatabase component onto a form or data module.


2. Fill out the DatabaseName property. For a local connection, this is the drive, path, and filename of the database file. Set the
Connected property to true.
3. Enter a valid username and password and click OK to establish the database connection.
Warning: Tip: You can store the username and password in the IBDatabase component's Params property by setting the
LoginPrompt property to false after logging in. For example, after logging in as the system administrator and setting the
LoginPrompt property to false, you may see the following when editing the Params property:

user_name=sysdba
password=masterkey
IBTransaction

Unlike the Borland Database Engine, IBX controls transactions with a separate component, TIBTransaction. This powerful
feature allows you to separate transactions and database connections, so you can take advantage of the InterBase two-phase
commit functionality (transactions that span multiple connections) and multiple concurrent transactions using the same
connection.

Use an IBTransaction component to handle transaction contexts, which might involve one or more database connections. In
most cases, a simple one database/one transaction model will do.

To set up a transaction:

1. Set up an IBDatabase connection as described above.


2. Drop an IBTransaction component onto the form or data module
3. Set the DefaultDatabase property to the name of your IBDatabase component.
4. Set the Active property to true to start the transaction.
IBX dataset components
There are a variety of dataset components from which to choose with IBX, each having their own characteristics and task
suitability:
IBTable
Use an TIBTable component to set up a live dataset on a table or view without having to enter any SQL statements.
IBTable components are easy to configure:

18
1.2 Developing Database Applications for RAD Studio Getting Started with InterBase Express

1. Add an IBTable component to your form or data module.


2. Specify the associated database and transaction components.
3. Specify the name of the relation from the TableName drop-down list.
4. Set the Active property to true.
IBQuery
Use an TIBQuery component to execute any InterBase DSQL statement, restrict your result set to only particular columns and
rows, use aggregate functions, and join multiple tables. 1
IBQuery components provide a read-only dataset, and adapt well to the InterBase client/server environment. To set up an
IBQuery component:
1. Set up an IBDatabase connection as described above.
2. Set up an IBTransaction connection as described above.
3. Add an IBQuery component to your form or data module.
4. Specify the associated database and transaction components.
5. Enter a valid SQL statement for the IBQuery's SQL property in the String list editor.
6. Set the Active property to true
IBDataSet
Use an TIBDataSet component to execute any InterBase DSQL statement, restrict your result set to only particular columns and
rows, use aggregate functions, and join multiple tables. IBDataSet components are similar to IBQuery components, except
that they support live datasets without the need of an IBUpdateSQL component.
The following is an example that provides a live dataset for the COUNTRY table in employee.gdb:
1. Set up an IBDatabase connection as described above.
2. Specify the associated database and transaction components.
3. Add an IBDataSet component to your form or data module.
4. Enter SQL statements for the following properties:

SelectSQL SELECT Country, Currency FROM Country


RefreshSQL SELECT Country, Currency FROM Country WHERE Country = :Country
ModifySQL UPDATE Country SET Country = :Country, Currency = :Currency WHERE Country = :Old_Country
DeleteSQL DELETE FROM Country WHERE Country = :Old_Country
InsertSQL INSERT INTO Country (Country, Currency) VALUES (:Country, :Currency)

1. Set the Active property to true.


2.
Note: Note: Parameters and fields passed to functions are case-sensitive in dialect 3. For example,

FieldByName(EmpNo)
would return nothing in dialect 3 if the field was 'EMPNO'.

IBStoredProc

Use TIBStoredProc for InterBase executable procedures: procedures that return, at most, one row of information. For stored
procedures that return more than one row of data, or "Select" procedures, use either IBQuery or IBDataSet components.

IBSQL

19
Getting Started with InterBase Express RAD Studio 1.2 Developing Database Applications for

Use an TIBSQL component for data operations that need to be fast and lightweight. Operations such as data definition and
pumping data from one database to another are suitable for IBSQL components.

In the following example, an IBSQL component is used to return the next value from a generator:

1. Set up an IBDatabase connection as described above.


2. Put an IBSQL component on the form or data module and set its Database property to the name of the database.
3. Add an SQL statement to the SQL property string list editor, for example:
1 SELECT GEN_ID(MyGenerator, 1) FROM RDB$DATABASE
IBUpdateSQL

Use an TIBUpdateSQL component to update read-only datasets. You can update IBQuery output with an IBUpdateSQL
component:

1. Set up an IBQuery component as described above.


2. Add an IBUpdateSQL component to your form or data module.
3. Enter SQL statements for the following properties: DeleteSQL, InsertSQL, ModifySQL, and RefreshSQL.
4. Set the IBQuery component's UpdateObject property to the name of the IBUpdateSQL component.
5. Set the IBQuery component's Active property to true.
IBSQLMonitor
Use an TIBSQLMonitor component to develop diagnostic tools to monitor the communications between your application and the
InterBase server. When the TraceFlags properties of an IBDatabase component are turned on, active TIBSQLMonitor
components can keep track of the connection's activity and send the output to a file or control.
A good example would be to create a separate application that has an TIBSQLMonitor component and a Memo control. Run this
secondary application, and on the primary application, activate the TraceFlags of the IBDatabase component. Interact with the
primary application, and watch the second's memo control fill with data.
IBDatabaseInfo
Use an TIBDatabaseInfo component to retrieve information about a particular database, such as the sweep interval, ODS
version, and the user names of those currently attached to this database.
For example, to set up an IBDatabaseInfo component that displays the users currently connected to the database:
1. Set up an IBDatabase connection as described above.
2. Put an IBDatabaseInfo component on the form or data module and set its Database property to the name of the database.
3. Put a Memo component on the form.
4. Put a Timer component on the form and set its interval.
5. Double click on the Timer's OnTimer event field and enter code similar to the following:
Memo1.Text := IBDatabaseInfo.UserNames.Text; // Delphi example
Memo1->Text = IBDatabaseInfo->UserNames->Text; // C++ example
IBEvents

Use an IBEvents component to register interest in, and asynchronously handle, events posted by an InterBase server.

To set up an IBEvents component:

1. Set up an IBDatabase connection as described above.


2. Put an IBEvents component on the form or data module and set its Database property to the name of the database.
3. Enter events in the Events property string list editor, for example:
IBEvents.Events.Add('EVENT_NAME'); // Delphi example
IBEvents->Events->Add("EVENT_NAME"); // C++ Example
1. 4. Set the Registered property to true.

20
1.2 Developing Database Applications for RAD Studio Getting Started with InterBase Express

2. InterBase Administration Components


If you have InterBase installed, you can use the InterBase Administration components, which allow you to use access the
powerful InterBase Services API calls.
The components are located on the InterBase Admin tab of the IDE and include:

TIBConfigService

TIBBackupService

TIBRestoreService
1
TIBValidationService

TIBStatisticalService

TIBLogService

TIBSecurityService

TIBLicensingService

TIBServerProperties

TIBInstall

TIBUnInstall

Note: You must install InterBase to use these features.

IBConfigService

Use an TIBConfigService object to configure database parameters, including page buffers, async mode, reserve space, and
sweep interval.

IBBackupService

Use an TIBBackupService object to back up your database. With IBBackupService, you can set such parameters as the blocking
factor, backup file name, and database backup options.

IBRestoreService

Use an TIBRestoreService object to restore your database. With IBRestoreService, you can set such options as page buffers,
page size, and database restore options.

IBValidationService

Use an TIBValidationService object to validate your database and reconcile your database transactions. With the
IBValidationService, you can set the default transaction action, return limbo transaction information, and set other database
validation options.

IBStatisticalService

Use an TIBStatisticalService object to view database statistics, such as data pages, database log, header pages, index pages,
and system relations.

IBLogService

Use an TIBLogService object to create a log file.

IBSecurityService

Use an TIBSecurityService object to manage user access to the InterBase server. With the IBSecurityService, you can create,
delete, and modify user accounts, display all users, and set up work groups using SQL roles.

21
dbExpress 4 Feature Overview RAD Studio 1.2 Developing Database Applications for

IBLicensingService

Use an TIBLicensingService component to add or remove InterBase software activation certificates.

IBServerProperties

Use an TIBServerProperties component to return database server information, including configuration parameters, and version
and license information.

IBInstall
1
Use an TIBInstall component to set up an InterBase installation component, including the installation source and destination
directories, and the components to be installed.

IBUnInstall

Use an TIBUnInstall component to set up an uninstall component.

1.2.5 dbExpress 4 Feature Overview


dbExpress's top level framework and metadata support has been rewritten in Delphi for RAD Studio 2007. It has new, richer
metadata support.

The DbxClient driver remotes the dbExpress 4 framework interface over a network based transport.

This document discusses the following features:

• dbExpress Framework
• dbExpress Metadata Improvements
• DBXClient Driver
• DBXDynalink Driver
• DBTest
dbExpress Framework
VCL

The dbExpress VCL component's implementation has changed with minimal change to the API. Most applications are not
affected by changes to the dbExpress VCL. However, there are some new methods, properties, events, constants, and enums.

dbExpress Metadata Improvements


New metadata providers for 9 different database backends are written completely in Delphi. Full source code to all metadata
providers is included in the product.

Metadata read and write capabilities


Each provider is composed of a metadata reader and metadata writer implementation contained inside the dbExpress driver
packages. The separate metadata readers and writers that were in the DbxReadOnlyMetaData and DbxMetaData packages no
longer exist.

Provider based approach


The metadata providers are detached from the driver, so that one metadata provider can be used for multiple driver
implementations as long as the database backend is the same. Data Explorer also takes advantage of metadata providers to
provide metadata support for other database drivers.

The provider is not bound to a driver, but to a database back end. There is a new property called

22
1.2 Developing Database Applications for RAD Studio dbExpress 4 Feature Overview

TDBXPropertyNames.MetaDataPackageLoader in the dbxdrivers.ini files that can be set to a TDBXCommandFactory object.


This command factory implementation creates a TDBXCommand that can execute metadata commands. This approach allows
multiple driver implementations for a specific database backend to use the same metadata provider. Data Explorer also takes
advantage of this architecture to provide dbExpress 4 structured metadata for drivers from other vendors. The decoupling of
driver and metadata provider also benefits "thin" driver implementations. If metadata commands can be serviced on a server,
there is no need to have the metadata provider logic on the client.

Provider source directory


1
All database source is now contained in the following installation location:
C:\Program FIles \ CodeGear\ RAD Studio \ 6.0 \ source \ database

Reading metadata
The unit DBXMetaDataNames has been provided to read metadata. The dbExpress class TDBXMetaDataCommands provides a
set of constants to read various types of metadata. Set the TDBXCommand.CommandType property to
TDBXCommandTypes.DBXMetadata and set TDBXCommand.Text to one of the constants in TDBXMetaDataCommands to
acquire the designated metadata. TDBXCommand.ExecuteQuery returns a TDBXReader to access the metadata. The new
classes in DBXMetaDataNames describe and provide access to this metadata's columns.

Writing metadata
Support for creating SQL dialect sensitive CREATE, ALTER, and DROP statements is provided in Data Explorer. dbExpress
also exposes a DbxMetaDataProvider class that surfaces this capability for applications. This slightly increases the size of
application, since the metadata writers must be included. The ability to generically create tables is useful for many applications.
The interface allows you to describe what a table and its columns look like and pass this description to the
TdbxMetaDataProvider.CreateTable method. Here is a simple example that shows how to create a table with an int32 column
named "C1", a decimal with a precision of 10 and scale of 2 named "C2", and a character based column with a precision of 32
named "C3".
var MetaDataTable: TDBXMetaDataTable; DataGenerator: TDbxDataGenerator; Command:
TDBXCommand; Row: Integer; begin MetaDataTable := TDBXMetaDataTable.Create;
MetaDataTable.TableName := 'QCXXX_TABLE';
MetaDataTable.AddColumn(TDBXInt32Column.Create('C1'));
MetaDataTable.AddColumn(TDBXDecimalColumn.Create('C2', 10, 2));
MetaDataTable.AddColumn(TDBXUnicodeCharColumn.Create('C3', 32));
MetaDataProvider.CreateTable(MetaDataTable); end

Deployment
For information about deploying database applications, see dapdeployingdatabaseapplications.xml ( see page 1948).

Compatibility
The VCL components in the SqlExpr unit still work with drivers that provide the more limited dbExpress 3 metadata. However,
Data Explorer only works with dbExpress 4 metadata.

Note that Delphi includes metadata for 9 different database backends. Thus any dbExpress driver implementation for the 9
backends supported can reuse the metadata provider with their driver implementation.

DBXClient Driver
DBXClient is a thin dbExpress 4 driver that remotes the dbExpress 4 framework interface over a pluggable network based
transport. In this release, a TCP/IP transport is supported. The driver uses a JSON/RPC (Java Script Object Notation) based
streaming protocol.

The DBXClient is implemented in 100% Object Pascal. Its source code is included in the product.

23
Blackfish SQL Overview RAD Studio 1.2 Developing Database Applications for

Connectivity
DBXClient can connect to Blackfish SQL and DataSnap. Blackfish SQL is a Delphi version of JBuilder's JDataStore. DataSnap
provides a middle-tier application server that contains and manages remote data modules. DataSnap has been enhanced to
provide a very general connection mechanism between components in different tiers.

To use the DBXClient driver with Blackfish SQL or DataSnap, add the DBXClient unit to the uses clause.

1 Deployment
DBXClient needs no database client library installed when you deploy your application. DBXClient is 100% Delphi and can be
directly linked into your application as a single .exe file.

For further information about deploying database applications, see dapdeployingdatabaseapplications.xml ( see page 1948).

DBTest
This is a collection of classes that extend the capabilities of Dunit to facilitate database testing. The qcreport and cts sample
Dunit tests provide good examples of how to make use of DBTest. TestCaseExtension contains non-database related
extensions to Dunit and the DBXTest unit contains database related extensions.

Command line properties


New units have been added to the DbxDynalinkDriver package for all 8 of Dynalink drivers:

Test selection
-s:<TestName> command line can be used to execute just a single method in a Dunit test case. This is useful for debugging a
single bug. See the TestCaseExtension unit.

Convenience methods
There are several methods for creating default connection and metadata provider. See the DBXTest unit.

Data generator
There is a simple, extensible data generator. See the DBXDataGenerator unit.

See Also
dbExpress Framework ( see page 26)

TDBXMetaDataCommands

1.2.6 Blackfish SQL Overview


The design and implementation of Blackfish SQL emphasizes database performance, scalability, ease of use, and a strong
adherence to industry standards. Blackfish SQL capabilities include the following:

• Industry standards compliance


• Entry level SQL-92
• Unicode storage of character data
• Unicode-based collation key support for sorting and indexing
• dbExpress 4 drivers for win32 Delphi and C++
• ADO.NET 2.0 providers for .NET

24
1.2 Developing Database Applications for RAD Studio Blackfish SQL Overview

• JDBC for Java


• JavaBean data access components for Java
• XA/JTA Distributed transactions for Java
• High performance and scalability for demanding online transaction processing (OLTP) and decision support system (DSS)
applications
• Delphi, C#, and VB.NET stored procedures and triggers for Windows
• Java-stored procedures and triggers 1
• Zero-administration, single assembly or single-jar deployment
• Database incremental backup and failover
Blackfish SQL DataStore
Blackfish SQL is the name of the product, its tools, and of the file format. Within this product, there is a datastore package that
includes a DataStore class, as well as several additional classes that have DataStore as part of their names.

Blackfish SQL Compatibility


Blackfish SQL for Windows and Blackfish SQL for Java are highly compatible with one another. The database file format is
binary-compatible between Blackfish SQL for Windows and Blackfish SQL for Java. In addition, database clients and servers are
interchangeable. Windows clients can connect to Java servers and Java clients can connect to Windows servers.

Because the Blackfish SQL for Windows implementation is more recent, some Blackfish SQL for Java features are not yet
supported. The following features are not supported:

• ISQL SQL Command Line Interpreter


• High Availability features, including incremental backup and failover
• Graphical tooling for administrative capabilities
• Access to file and object streams
• Tracking and resolving of row-level insert, update and delete operations
• Access to the Blackfish SQL File System directory
Blackfish SQL Connectivity
This section provides an overview of the connection drivers provided for Blackfish SQL for Windows and Blackfish SQL for Java,
respectively. For instructions on using the drivers to connect to a Blackfish SQL database, see the Blackfish SQL Developer's
Guide, Establishing Connections section

Blackfish SQL for Windows Connectivity


Blackfish SQL for Windows provides the following connection drivers:

• DBXClient: This is a win32 dbExpress 4 database driver that enables win32 Delphi and C++ applications to connect to a
remote Blackfish SQL for Windows or Blackfish SQL for Java server.
• Local ADO.NET 2.0 Provider: This is a 100% managed code driver that enables .NET applications to connect to a local
Blackfish SQL for Windows server. The local ADO.NET driver executes in the same process as the BlackFishSQL database
kernel, for greater performance.
• Remote ADO.NET 2.0 Provider: This is a 100% managed code driver that enables .NET applications to acquire a remote
connection to either a Blackfish SQL for Windows or Blackfish SQL for Java server.

Blackfish SQL for Java Connectivity


Blackfish SQL for Java provides the following JDBC connection drivers:

• Local JDBC driver: This is a 100% managed code driver that enables Java applications to connect to a local Blackfish SQL

25
dbExpress Framework RAD Studio 1.2 Developing Database Applications for

for Java server. The local JDBC driver executes in the same process as the BlackFishSQL database kernel, for greater
performance.
• Remote JDBC driver: This is a 100% managed code driver that enables Java applications to acquire a remote connection to
either a Blackfish SQL for Windows or Blackfish SQL for Java server.
See Also
Blackfish SQL Developer's Guide: Preface

1.2.7 dbExpress Framework


The dbExpress framework (DBX framework) is a set of abstract classes provided in the unit DBXCommon. Applications can
interface with the framework in several ways: using the framework directly for both native and managed applications, and using
the dbExpress VCL components that are layered on top of the framework for both native and managed applications.

Although many applications interface with dbExpress drivers via the dbExpress VCL components, the DBX framework offers a
convenient, lighter weight option to communicate with a database driver. You can also create a database driver for dbExpress by
extending the frameworks's DBXCommon abstract base classes. The DBX framework provides most commonly needed
database driver functionality for a "set" oriented database application, yet provides a simple interface.

Here are some of the key features of the DBX framework:

• The driver framework is written entirely in Delphi and allows drivers to be written in Delphi.
• It uses strongly typed data access instead of pointers. For instance, it uses String types rather than pointers to strings.
• The driver framework is single sourced. You can compile the source with the native DCC32 compiler.
• The framework has only Abstract base classes that are used for drivers, connections, commands, readers, and so on.
• The framework uses exception based error handling rather than returning error codes.
Capabilities
There are two categories of drivers that extend the classes in DBXCommon: DBXDynaLink and DBXDirect. These drivers differ
from each other in the way they are loaded and the capabilities they provide to an application. These are described in greater
detail later.

You can also extend the DBX framework to write delegation drivers, which provide an extra layer between the application and
the actual driver. Delegate drivers are useful for connection pooling, driver profiling, tracing, and auditing. Another possible
application of driver delegation is to create a thread safe driver delegate. Such a delegate could provide thread synchronized
access to all public methods.

Absolute thread safety is left to applications using dbExpress. However, some thread safety issues are best handled by the
dbExpress framework. dbExpress thread safe operations include loading and unloading drivers, and connection creation. As
mentioned earlier, a delegate driver can be created to make the entire public interface of dbExpress thread safe if needed.

A dbExpress 4 driver can statically or dynamically link drivers built as Delphi packages. The easiest way to link a driver package
is to just include it in the "uses" clause. The driver loader also loads packages specified in a config or ini file using the
LoadPackage method. This allows dynamic loading of drivers that are never specified in a uses clause of any of the application's
units. Note that the LoadPackage approach can only be employed for applications built to use packages.

dbExpress 4 driver writers should examine the initialization sections of the DBXDynalink and DBXTrace units in the source code
provided with dbExpress. These sections register themselves with a singleton unit called the ClassRegistry. The ClassRegistry is
used by the dbExpress 4 driver loader to instantiate driver loader classes by name (a String). The ClassRegistry is a simple,
lightweight mechanism for registering and instantiating a class by name.

26
1.2 Developing Database Applications for RAD Studio dbExpress Framework Compatibility

DBXDynalink Drivers
DBXDynalink is used for existing dbExpress 3 drivers as well as new drivers. It is compiled as a native Delphi package.
DBXDynalink loads native dbExpress drivers that implement a more primitive "native" interface called DBXExports. The
DBXExports interface is a small collection of "flat" export methods. DBXExports's source is included with dbExpress.
DBXExports provides a more strongly typed API than the dbExpress 3's COM based interface. This allows methods to be added
in future product generations without breaking compatibility with older implementations of the DBXExports interface.

DBXAdapter is a dbExpress 4 compliant driver that adapts the DBXExports interface to the older dbExpress 3 COM interface. 1
Newer native drivers can be written by implementing DBXExports directly.

Because the DBXExports interface is designed to be implemented using any native language (Delphi or C++), it uses more
primitive, non-exception based error handling. DBXDynalink maps error codes to a DBXCommon exception.

The DBXDynalink unit contains a dbExpress 4 driver. This driver delegates to non-Delphi drivers that implement the
DBXDynalinkExport flat export interface. DBXTrace is a delegate driver used for tracing. The dbExpress VCL uses
DBXCommon, DBXDynalink and DbxTrace as "default" drivers. However, this can be changed for statically linked applications
without modifying dbExpress VCL source code (SQLExpr.pas). SQLExpr.pas uses the unit DBXDefaultDrivers. The
DBXDefaultDrivers unit only contains a uses clause. The DBXDefaultDrivers uses clause contains DBXCommon, DBXDynalink,
and DBXTrace. DBXCommon must always be used. However, a statically linked application could remove DBXTrace and
replace DBXDynalink with a different driver.

DBXDirect Drivers
A DBXDirect driver is any driver that is implemented by extending the DBXCommon abstract base classes. These classes are
written in Delphi for native implementations.

Strictly speaking, all DBX framework drivers are a form of DBXDirect driver. However DBXDynalink and DBXRemote provide a
more "indirect" linkage to driver implementations.

See Also
dbExpress Framework Compatibility ( see page 27)

Deploying dbExpress Database Applications ( see page 1942)

1.2.8 dbExpress Framework Compatibility


Some dbExpress software developed prior to the dbExpress driver framework (DBX driver framework) has been modified to
work with the DBX driver framework. As a result of these changes, some compatibility issues arise.

General
dbExpress 2.5 drivers cannot be used with the DBX framework.

The dbExpress framework does not provide 100% compatibility with dbExpress 3.

dbExpress 3 drivers can be used with the DBX framework. The DBX framework driver loader automatically detects dbExpress 3
drivers and uses the DBXAdapter driver (dbxadapter30.dll) to make a dbExpress 3 driver look like a dbExpress 4 driver.

Here is a list of known compatibility issues:

• Static driver linkage. You cannot statically link dbExpress drivers into an executable.
• SqlExpr.TSQLConnection provided protected access to the Connection member that was of type TISQLConnection only in
the native version of SqlExpr.pas. This was omitted from the managed version due to the complexity of how PInvoke was
used in the managed version of the dbExpress VCL. SqlExpr.TSQLConnection now provides protected access to a
TDBXConnection instead. This protected connection is accessible to both native and managed applications.

27
dbExpress Framework Compatibility RAD Studio 1.2 Developing Database Applications for

• The event for trace monitoring is slightly different because it is based on the DBX driver framework.
• The DBXadapter driver can adapt dbExpress 3 drivers to dbExpress 4, but not dbExpress 2.5 drivers.
VCL issues
Most applications using dbExpress VCL components should work without modification. However, there are some localized
changes to VCL components due to VCL now interfacing to the more object oriented DBX driver framework instead of the C-like
COM-based dbExpress 3 driver interface.

1 In addition, the API has changed slightly for two of the VCL components: TSQLConnection and TSQLDataSet. Some data
structures have also changed. A summary of the API changes follows.

Note: Because of API changes, you must recompile SqlExpr.pas, which is provided with the product. The DBXpress unit has
been deprecated.

• TSQLConnection. The Commit method has been deprecated in favor of the new CommitFreeAndNil method. The Rollback
method has been deprecated in favor of the new RollbackFreeAndNil and RollbackIncompleteFreeAndNil methods. The
SetTraceCallbackEvent method has been replaced by SetTraceEvent. The StartTransaction method has been deprecated in
favor of the new BeginTransaction method. The MetaData property contains an instance of the new class
TDBXDatabaseMetaData instead of TISQLMetaData. The SQLConnection property has been replaced by DBXConnection,
which contains an instance of the new class TDBXConnection. The TraceCallbackEventproperty now contains a
TDBXTraceEvent.
• TSQLDataSet. A new property DbxCommandType has been added, which contains one of the constant strings in the
TDBXCommandTypes class.
• Data structures. TTransactionItem has been deprecated, replaced by the new TDBXTransaction class. TSQLDriverOption,
TSQLConnectionOption, TSQLCommandOption, TSQLCursorOption, TSQLMetaDataOption, and TSQLObjectType are
obsolete. TSTMTParamType has been replaced by the TDBXParameterDirections class. TSQLTraceFlag has been replaced
by TDBXTraceFlags. SQLTRACEDesc is replaced by TDBXTraceInfo.
See Also
dbExpress Framework ( see page 26)

Deploying dbExpress Database Applications ( see page 1942)

28
1.3 Developing Interoperable Applications RAD Studio Developing COM Applications

1.3 Developing Interoperable Applications


RAD Studio provides wizards and classes to make it easy to implement applications based on the Component Object Model
(COM) from Microsoft. With these wizards, you can create COM-based classes and components to use within applications or
you can create fully functional COM clients or servers that implement COM objects, Automation servers (including Active Server 1
Objects), ActiveX controls, or ActiveForms.

Topics
Name Description
Developing COM Applications ( see page 29) Delphi provides wizards and classes to make it easy to implement applications
based on the Component Object Model (COM) from Microsoft. With these
wizards, you can create COM-based classes and components to use within
applications or you can create fully functional COM clients and servers that
implement COM objects, Automation servers (including Active Server Objects),
ActiveX controls, or ActiveForms.
This topic covers:

• COM Technologies Overview


• COM Interfaces
• COM Servers
• COM Clients

1.3.1 Developing COM Applications


Delphi provides wizards and classes to make it easy to implement applications based on the Component Object Model (COM)
from Microsoft. With these wizards, you can create COM-based classes and components to use within applications or you can
create fully functional COM clients and servers that implement COM objects, Automation servers (including Active Server
Objects), ActiveX controls, or ActiveForms.

This topic covers:

• COM Technologies Overview


• COM Interfaces
• COM Servers
• COM Clients
COM Technologies Overview
COM is a language-independent software component model that enables interaction between software components and
applications running on a Windows platform. The most important aspect of COM is that it enables communication between
components, between applications, and between clients and servers through clearly defined interfaces. Interfaces provide a way
for clients to ask a COM component which features it supports at runtime. To provide additional features for your component,
you simply add an additional interface for those features.

Applications can access the interfaces of COM components that exist on the same computer as the application or that exist on
another computer on the network using a mechanism called Distributed COM (DCOM).

COM is both a specification and an implementation. The COM specification defines how objects are created and how they
communicate with each other. According to this specification, COM objects can be written in different languages, run in different

29
Developing COM Applications RAD Studio 1.3 Developing Interoperable Applications

process spaces and on different platforms. As long as the objects conform to the written specification, they can communicate.
This allows you to integrate legacy code as a component with new components implemented in object-oriented languages.

The COM implementation is built into the Win32 subsystem, which provides a number of core services that support the
specification. The COM library contains a set of standard interfaces that define the core functionality of a COM object, and a
small set of API functions for creating and managing COM objects.

When you use Delphi wizards and VCL objects in your application, you are using Delphi’s implementation of the COM
specification. In addition, Delphi provides some wrappers for COM services for those features that it does not implement directly
1 (such as Active Documents). You can find these wrappers defined in the ComObj unit and the API definitions in the AxCtrls
unit.

Note: Delphi’s interfaces and language follow the COM specification. Delphi implements objects conforming to the COM spec
using a set of classes called the Delphi ActiveX framework (DAX). These classes are found in the AxCtrls, OleCtrls, and
OleServer units. In addition, the Delphi interface to the COM API is in ActiveX.pas and ComSvcs.pas.

COM Interfaces
COM clients communicate with objects through COM interfaces. Interfaces are groups of logically or semantically related
routines which provide communication between a provider of a service (server object) and its clients.

For example, every COM object must implement the basic interface, IUnknown. Through a routine called QueryInterface in
IUnknown, clients can request other interfaces implemented by the server.

Objects can have multiple interfaces, where each interface implements a feature. An interface provides a way to tell the client
what service it provides, without providing implementation details of how or where the object provides this service.

Key aspects of COM interfaces are as follows:

• Once published, interfaces do not change. You can rely on an interface to provide a specific set of functions. Additional
functionality is provided by additional interfaces.
• By convention, COM interface identifiers begin with a capital I and a symbolic name that defines the interface, such as
IMalloc or IPersist.
• Interfaces are guaranteed to have a unique identification, called a Globally Unique Identifier (GUID), which is a 128-bit
randomly generated number. Interface GUIDs are called Interface Identifiers (IIDs). This eliminates naming conflicts between
different versions of a product or different products.
• Interfaces are language independent. You can use any language to implement a COM interface as long as the language
supports a structure of pointers, and can call a function through a pointer, either explicitly or implicitly.
• Interfaces are not objects themselves, they provide a way to access an object. Therefore, clients do not access data directly,
they access data through an interface pointer. Windows 2000 adds another layer of indirection, known as an interceptor,
through which it provides COM+ features such as just-in-time activation and object pooling.
• Interfaces are always inherited from the base interface, IUnknown.
• Interfaces can be redirected by COM through proxies to enable interface method calls to call between threads, processes,
and networked machines, all without the client or server objects ever being aware of the redirection.

The IUnknown interface


All COM objects must support the fundamental interface, called IUnknown, a typedef to the base interface type IInterface.
IUnknown contains the following routines:

• QueryInterface: Provides pointers to other interfaces that the object supports.


• AddRef and Release: Simple reference counting methods that keep track of the object’s lifetime so that an object can delete
itself when the client no longer needs its service.
Clients obtain pointers to other interfaces through the IUnknown method, QueryInterface. QueryInterface knows about
every interface in the server object and can give a client a pointer to the requested interface. When receiving a pointer to an

30
1.3 Developing Interoperable Applications RAD Studio Developing COM Applications

interface, the client is assured that it can call any method of the interface.
Objects track their own lifetime through the IUnknown methods, AddRef and Release, which are simple reference counting
methods. As long as the reference count of an object is nonzero, the object remains in memory. Once the reference count
reaches zero, the interface implementation can safely dispose of the underlying object.

COM Interface Pointers


An interface pointer is a pointer to an object instance that points, in turn, to the implementation of each method in the interface.
The implementation is accessed through an array of pointers to these methods, which is called a vtable. Vtables are similar to
1
the mechanism used to support virtual functions in Delphi. Because of this similarity, the compiler can resolve calls to methods
on the interface the same way it resolves calls to methods on Delphi classes.

The vtable is shared among all instances of an object class, so for each object instance, the object code allocates a second
structure that contains its private data. The client’s interface pointer, then, is a pointer to the pointer to the vtable.

In Windows 2000 and subsequent versions of Windows, when an object is running under COM+, another level of indirection is
provided between the interface pointer and the vtable pointer. The interface pointer available to the client points at an interceptor,
which in turn points at the vtable. This allows COM+ to provide such services as just-in-time activation, where the server can be
deactivated and reactivated dynamically in a way that is opaque to the client. To achieve this, COM+ guarantees that the
interceptor behaves as if it were an ordinary vtable pointer.

COM Servers
A COM server is an application or a library that provides services to a client application or library. A COM server consists of one
or more COM objects, where a COM object is a set of properties and methods.

Clients do not know how a COM object performs its service; the object’s implementation remains hidden. An object makes its
services available through its interfaces as described previously.

In addition, clients do not need to know where a COM object resides. COM provides transparent access regardless of the
object’s location.

When a client requests a service from a COM object, the client passes a class identifier (CLSID) to COM. A CLSID is simply a
GUID that identifies a COM object. COM uses this CLSID, which is registered in the system registry, to locate the appropriate
server implementation. Once the server is located, COM brings the code into memory, and has the server create an object
instance for the client. This process is handled indirectly, through a special object called a class factory (based on interfaces)
that creates instances of objects on demand.

As a minimum, a COM server must perform the following:

• Register entries in the system registry that associate the server module with the class identifier (CLSID).
• Implement a class factory object, which creates another object of a particular CLSID.
• Expose the class factory to COM.
• Provide an unloading mechanism through which a server that is not servicing clients can be removed from memory.
COM Clients
COM clients are applications that make use of a COM object implemented by another application or library. The most common
types are Automation controllers, which control an Automation server and ActiveX containers, which host an ActiveX control.

There are two types of COM clients, controllers and containers. Controllers launch the server and interact with it through its
interface. They request services from the COM object or drive it as a separate process. Containers host visual controls or objects
that appear in the container’s user interface. They use predefined interfaces to negotiate display issues with server objects. It is
impossible to have a container relationship over DCOM; for example, visual controls that appear in the container's user interface
must be located locally. This is because the controls are expected to paint themselves, which requires that they have access to
local GDI resources.

The task of writing these two types of COM client is remarkably similar: The client application obtains an interface for the server

31
Developing COM Applications RAD Studio 1.3 Developing Interoperable Applications

object and uses its properties and methods. Delphi makes it easier for you to develop COM clients by letting you import a type
library or ActiveX control into a component wrapper so that server objects look like other VCL components. Delphi lets you wrap
the server CoClass in a component on the client, which you can even install on the Component palette. Samples of such
component wrappers appear on two pages of the Component palette, sample ActiveX wrappers appear on the ActiveX page,
and sample Automation objects appear on the Servers page.

Even if you do not choose to wrap a server object in a component wrapper and install it on the Component palette, you must
make its interface definition available to your application. To do this, you can import the server’s type information.
1 Clients can always query the interfaces of a COM object to determine what it is capable of providing. All COM objects allow
clients to request known interfaces. In addition, if the server supports the IDispatch interface, clients can query the server for
information about what methods the interface supports. Server objects have no expectations about the client using its objects.
Similarly, clients don’t need to know how an object provides the services, they simply rely on server objects to provide the
services they describe in their interfaces.

COM Extensions
As COM has evolved, it has been extended beyond the basic COM services. COM serves as the basis for other technologies
such as Automation, ActiveX controls, Active Documents, and Active Directories. In addition, when working in a large, distributed
environment, you can create transactional COM objects. Prior to Windows 2000, these objects were not an architectural part of
COM, but ran in the Microsoft Transaction Server (MTS) environment. As of Windows 2000, this support is integrated into
COM+. Delphi provides wizards to easily implement applications that use the above technologies in the Delphi environment.

Automation Servers
Automation refers to the ability of an application to control the objects in another application programmatically, such as a macro
that can manipulate more than one application at the same time. The server object being manipulated is called the Automation
object, and the client of the Automation object is referred to as an Automation controller. Automation can be used on in-process,
local, and remote servers.

Automation is defined by two major points:

• The Automation object defines a set of properties and commands, and describes their capabilities through type descriptions.
In order to do this, it must have a way to provide information about its interfaces, the interface methods, and the arguments to
those methods. Typically, this information is available in a type library. The Automation server can also generate type
information dynamically when queried via its IDispatch interface.
• Automation objects make their methods accessible so that other applications can use them. For this, they implement the
IDispatch interface. Through this interface an object can expose all of its methods and properties. Through the primary
method of this interface, the object’s methods can be invoked, once having been identified through type information.
Developers often use Automation to create and use non-visual OLE objects that run in any process space, because the
Automation IDispatch interface automates the marshaling process. Automation does, however, restrict the types that you
can use.

Active X Controls
Delphi wizards allow you to easily create ActiveX controls. ActiveX is a technology that allows COM components, especially
controls, to be more compact and efficient. This is especially necessary for controls that are intended for Intranet applications,
which need to be downloaded by a client before they are used.

ActiveX controls are visual controls that run only as in-process servers, and can be plugged into an ActiveX control container
application. They are not complete applications in themselves, but can be thought of as already written OLE controls that are
reusable in various applications. ActiveX controls have a visible user interface, and rely on predefined interfaces to negotiate I/O
and display issues with their host containers.

ActiveX controls make use of Automation to expose their properties, methods, and events. Features of ActiveX controls include
the ability to fire events, bind to data sources, and support licensing.

One use of ActiveX controls is on a Web site as interactive objects in a Web page. As such, ActiveX is a standard that targets

32
1.3 Developing Interoperable Applications RAD Studio Developing COM Applications

interactive content for the World Wide Web, including the use of ActiveX Documents used for viewing non-HTML documents
through a Web browser. For more information about ActiveX technology, see the Microsoft ActiveX Web site.

Active Documents
Active Documents (previously referred to as OLE documents) are a set of COM services that support linking and embedding,
drag-and-drop, and visual editing. Active Documents can seamlessly incorporate data or objects of different formats, such as
sound clips, spreadsheets, text, and bitmaps.

Unlike ActiveX controls, Active Documents are not limited to in-process servers; they can be used in cross-process applications. 1
Unlike Automation objects, which are almost never visual, Active Document objects can be visually active in another application.
Thus, Active Document objects are associated with two types of data: presentation data, used for visually displaying the object
on a display or output device, and native data, used to edit an object.

Active Document objects can be document containers or document servers. While Delphi does not provide an automatic wizard
for creating Active Documents, you can use the VCL class, TOleContainer, to support linking and embedding of existing Active
Documents.

You can also use TOleContainer as a basis for an Active Document container. To create objects for Active Document servers,
use the COM object wizard and add the appropriate interfaces, depending on the services the object needs to support. For more
information about creating and using Active Document servers, see the Microsoft ActiveX Web site.

Note: While the specification for Active Documents has built-in support for marshaling in cross-process applications, Active
Documents do not run on remote servers because they use types that are specific to a system on a given machine such as
window handles, menu handles, and so on.

Transactional Objects
Delphi uses the term "transactional objects" to refer to objects that take advantage of the transaction services, security, and
resource management supplied by Microsoft Transaction Server (MTS) (for versions of Windows prior to Windows 2000) or
COM+ (for Windows 2000 and later). These objects are designed to work in a large, distributed environment.

The transaction services provide robustness so that activities are always either completed or rolled back. The server never
partially completes an activity. The security services allow you to expose different levels of support to different classes of clients.
The resource management allows an object to handle more clients by pooling resources or keeping objects active only when
they are in use. To enable the system to provide these services, the object must implement the IObjectControl interface. To
access the services, transactional objects use an interface called IObjectContext, which is created for them by MTS or
COM+.

Under MTS, the server object must be built into a DLL library, which is then installed in the MTS runtime environment. That is,
the server object is an in-process server that runs in the MTS runtime process space. Under COM+, this restriction does not
apply because all COM calls are routed through an interceptor. To clients, the difference between MTS and COM+ is transparent.

MTS or COM+ servers group transactional objects that run in the same process space. Under MTS, this group is called an MTS
package, while under COM+ it is called a COM+ application. A single machine can be running several different MTS packages
(or COM+ applications), where each one is running in a separate process space.

To clients, the transactional object may appear like any other COM server object. The client does not need know about
transactions, security, or just-in-time activation unless it is initiating a transaction itself.

Both MTS and COM+ provide a separate tool for administering transactional objects. This tool lets you configure objects into
packages or COM+ applications, view the packages or COM+ applications installed on a computer, view or change the attributes
of the included objects, monitor and manage transactions, make objects available to clients, and so on. Under MTS, this tool is
the MTS Explorer. Under COM+ it is the COM+ Component Manager.

33
Developing COM Applications RAD Studio 1.3 Developing Interoperable Applications

Type Libraries
Type libraries provide a way to get more type information about an object than can be determined from an object’s interface. The
type information contained in type libraries provides needed information about objects and their interfaces, such as what
interfaces exist on what objects (given the CLSID), what member functions exist on each interface, and what arguments those
functions require.

You can obtain type information either by querying a running instance of an object or by loading and reading type libraries. With
1 this information, you can implement a client which uses a desired object, knowing specifically what member functions you need,
and what to pass those member functions.

Clients of Automation servers, ActiveX controls, and transactional objects expect type information to be available. All of Delphi’s
wizards generate a type library automatically, although the COM object wizard makes this optional. You can view or edit this type
information by using the Type Library Editor.

See Also
Using COM Wizards ( see page 79)

34
1.4 Developing Reports for Your Win32 RAD Studio Using Rave Reports in RAD Studio

1.4 Developing Reports for Your Win32


Applications
RAD Studio ships with Rave Reports from Nevrona. Using the report components, you can build full-featured reports for your
1
applications. You can create solutions that include reporting capabilities which can be used and customized by your customers.
Additionally, the ComponentOne tools that ship with RAD Studio include components for creating and generating reports.

Topics
Name Description
Using Rave Reports in RAD Studio ( see page 35) The RAD Studio environment supports the integration of report objects in your
applications. This integration allows you to create a report using the Rave
Reports Designer directly from within the RAD Studio IDE. Your application users
can create and display their own reports, or display existing reports.

1.4.1 Using Rave Reports in RAD Studio


The RAD Studio environment supports the integration of report objects in your applications. This integration allows you to create
a report using the Rave Reports Designer directly from within the RAD Studio IDE. Your application users can create and display
their own reports, or display existing reports.

Creating New Reports in RAD Studio


You can include reports in RAD Studio just as you would other 3rd-party components. The report is stored as a separate Rave
Report object. You can reference the report in other applications that need to call or generate that report. When you create a
new application, you can include the report object by adding a reference to it in the Project Manager. Rave Reports also provide
the capability to connect your report object to a datasource, which allows your application to build the report dynamically, based
on current database information.

See Also
Adding Rave Reports to RAD Studio ( see page 81)

35
VCL Overview RAD Studio 1.5 Developing Applications with VCL

1.5 Developing Applications with VCL


Components
1 The Visual Component Library (VCL) is a set of visual components for the rapid development of Windows applications in the
Delphi language.

VCL contains a wide variety of visual, non-visual, and utility classes for tasks such as building Windows applications, web
applications, database applications, and console applications.

Topics
Name Description
VCL Overview ( see page 36) This section introduces:

• VCL Architecture
• VCL Components
• Working With Components
Using TEncoding for Unicode Files ( see page 38)
Components Available Only on Specific OS ( see page 39) Some VCL components are specific to an operating system (such as Vista) and
thus will not work on other operating systems. For example, the design time
components TFileOpenDialog and TFileSaveDialog are specific to Vista. Some
components are designed to work with themes either enabled or disabled. (To
enable or disable themes, check or uncheck the Enable runtime themes box on
the Project Options Application dialog box.)
In the following table, note that Windows Server 2003 is treated as Windows XP,
and Windows Server 2008 is treated as Vista.
Components Available Only for Certain Operating Systems

1.5.1 VCL Overview


This section introduces:

• VCL Architecture
• VCL Components
• Working With Components
VCL Architecture
VCL is an acronym for the Visual Component Library, a set of visual components for rapid development of Windows applications
in the Delphi language. VCL contains a wide variety of visual, non-visual, and utility classes for tasks such as Windows
application building, web applications, database applications, and console applications. All classes descend from
System::TObject. System::TObject introduces methods that implement fundamental behavior like construction, destruction, and
message handling.

VCL Components
Components are a subset of the component library that descend from the class TComponent. You can place components on a
form or data module and manipulate them at designtime. Using the Object Inspector, you can assign property values without
writing code. Most components are either visual or nonvisual, depending on whether they are visible at runtime. Some
components appear on the Component Palette.

36
1.5 Developing Applications with VCL RAD Studio VCL Overview

Visual Components
Visual components, such as TForm and TSpeedButton, are called controls and descend from TControl. Controls are used in GUI
applications, and appear to the user at runtime. TControl provides properties that specify the visual attributes of controls, such as
their height and width.

NonVisual Components
Nonvisual components are used for a variety of tasks. For example, if you are writing an application that connects to a database, 1
you can place a TDataSource component on a form to connect a control and a dataset used by the control. This connection is
not visible to the user, so TDataSource is nonvisual. At designtime, nonvisual components are represented by an icon. This
allows you to manipulate their properties and events just as you would a visual control.

Other VCL Classes


Classes that are not components (that is, classes that descend from System::TObject but not TComponent) are also used for a
variety of tasks. Typically, these classes are used for accessing system objects (such as a file or the clipboard) or for transient
tasks (such as storing data in a list). You cannot create instances of these classes at designtime, although they are sometimes
created by the components that you add in the Form Designer.

Working With Components


Many components are provided in the IDE on the Component Palette. You select components from the Component Palette
and place them onto a form or data module. You design the user interface of an application by arranging the visual components
such as buttons and list boxes on a form. You can also place nonvisual components, such as data access components, on either
a form or a data module. At first, Delphi’s components appear to be just like any other classes. But there are differences between
components in Delphi and the standard class hierarchies that many programmers work with. Some differences are:

• All Delphi components descend from TComponent.


• Components are most often used as is. They are changed through their properties, rather than serving as base classes to be
subclassed to add or change functionality. When a component is inherited, it is usually to add specific code to existing event
handling member functions.
• Components can only be allocated on the heap, not on the stack.
• Properties of components contain runtime type information.
• Components can be added to the Component Palette in the IDE and manipulated on a form.
Components often achieve a better degree of encapsulation than is usually found in standard classes. For example, consider a
dialog box containing a button. In a Windows program developed using VCL components, when a user clicks the button, the
system generates a WM_LBUTTONDOWN message. The program must catch this message (typically in a switch statement, a
message map, or a response table) and send it to a routine that will execute in response to the message. Most Windows
messages (VCL applications) are handled by Delphi components. When you want to respond to a message or system event,
you only need to provide an event handler.

Using Events
Almost all the code you write is executed, directly or indirectly, in response to events. An event is a special kind of property that
represents a runtime occurrence, often a user action. The code that responds directly to an event, called an event handler, is a
Delphi procedure.

The Events page of the Object Inspector displays all events defined for a given component. Double-clicking an event in the
Object Inspector generates a skeleton event handling procedure, which you can fill in with code to respond to that event. Not all
components have events defined for them.

Some components have a default event, which is the event the component most commonly needs to handle. For example, the
default event for a button is OnClick. Double-clicking on a component with a default event in the Form Designer will generate a
skeleton event handling procedure for the default event.

37
Using TEncoding for Unicode Files RAD Studio 1.5 Developing Applications with VCL

You can reuse code by writing event handlers that respond to more than one event. For example, many applications provide
speed buttons that are equivalent to drop down menu commands. When a button performs the same action as a menu
command, you can write a single event handler and then assign it to the OnClick event for both the button and the menu item by
setting the event handler in the Object Inspector for both the events you want to respond to.

This is the simplest way to reuse event handlers. However, action lists, and in the VCL, action bands, provide powerful tools for
centrally organizing the code that responds to user commands. Action lists can be used in cross-platform applications; action
bands cannot.
1
Setting Component Properties
To set published properties at design time, you can use the Object Inspector and, in some cases, property editors. To set
properties at runtime, assign their values in your application source code.

When you select a component on a form at design time, the Object Inspector displays its published properties and, when
appropriate, allows you to edit them.

When more than one component is selected, the Object Inspector displays all properties—except Name—that are shared by the
selected components. If the value for a shared property differs among the selected components, the Object Inspector displays
either the default value or the value from the first component selected. When you change a shared property, the change applies
to all selected components.

Changing code-related properties, such as the name of an event handler, in the Object Inspector automatically changes the
corresponding source code. In addition, changes to the source code, such as renaming an event handler method in a form class
declaration, are immediately reflected in the Object Inspector.

See Also
Building a VCL Forms Application ( see page 99)

Building a VCL Forms "Hello world" Application ( see page 101)

Organizing Actions for Toolbars and Menus ( see page 1992)

1.5.2 Using TEncoding for Unicode Files


Reading and Writing in the Old Format
Many Delphi applications will need to continue to interact with other applications or datasources, many of which can only handle
data in ANSI or ASCII. For this reason, the defaults for the TStrings methods will write the files ANSI encoded based on the
active code page and will read the files based on whether or not the file contains a Byte Order Mark (BOM).

If a BOM is found, it will read the data encoded as the BOM indicates. If no BOM is found, it will read it as ANSI and up-convert
based on the current active codepage.

All your files written with pre-RAD Studio 2009 versions of Delphi will still be read in, with the caveat that as long as you read
with the active codepage the same as with what was written. Likewise, any file written with RAD Studio 2009 with an ASCII
encoding should be readable with the pre-RAD Studio 2009 version.

Any file written with RAD Studio 2009 with any other encoding will generate a BOM and will not be readable with a the pre-RAD
Studio 2009 version. At this point, only the most common BOM formats are detected (UTF16 Little-Endian, UTF16 Big-Endian
and UTF8).

Using the new encodings


You may want to read/write text data using the TStrings class a loss-less Unicode format, be that Little-Endian UTF16,
Big-Endian UTF16, UTF8, UTF7 so on. The TEncoding class is very similar in methods and functionality that you can find in the

38
1.5 Developing Applications with VCL RAD Studio Components Available Only on Specific OS

System.Text.Encoding class in the .NET Framework.


var
S: TStrings;
begin
S: TStringList.Create();
{ ... }
S.SaveToFile('config.txt', TEncoding UTF8);
Without the extra parameter, ‘config.txt’ would simply be converted and written out as ANSI encoded based on the current active
codepage. You do not need to change the read code since TStrings will automatically detect the encoding based on the BOM 1
and do the right thing.

If you wanted to force the file to read and write using a specific codepage, you can create an instance of TMBCSEncoding and
pass in the code page you want to use into the constructor. Then you use that instance to read and write the file, since the
specific codepage may not match the user’s active codepage.

The same thing holds for these classes in that the data will be read and written as ANSI data. Since INI files have always been
traditionally ANSI (ASCII) encoded, it may not make sense to convert these. It will depend on the needs of your application. If
you do wish to change to use a Unicode format, we will offer ways to use the TEncoding classes to accomplish that as well.

In all the above cases, the internal storage will be Unicode and any data manipulation you do with string will continue to function
as expected. Conversions will automatically happen when reading and writing the data.

Here is a list of codepage identifiers (MSDN).:

The following list shows the overload methods that accept a TEncoding parameter:

• WriteNode (Outline.TOutlineNode)
• LoadFromFile (Outline.TOutlineNode)
• LoadFromStream (Outline.TOutlineNode)
• SaveToFile (Outline.TOutlineNode)
• SaveToStream (Outline.TOutlineNode)
• LoadFromFile (Classes.TStrings)
• LoadFromStream (Classes.TStrings)
• SaveToFile (Classes.TStrings)
• SaveToStream (Classes.TStrings)
• Create (Classes.TStringStream)
• Create (Classes.TStreamReader)
• Create (Classes.TStreamWriter)

1.5.3 Components Available Only on Specific OS


Some VCL components are specific to an operating system (such as Vista) and thus will not work on other operating systems.
For example, the design time components TFileOpenDialog and TFileSaveDialog are specific to Vista. Some components are
designed to work with themes either enabled or disabled. (To enable or disable themes, check or uncheck the Enable runtime
themes box on the Project Options Application dialog box.)

In the following table, note that Windows Server 2003 is treated as Windows XP, and Windows Server 2008 is treated as Vista.

Components Available Only for Certain Operating Systems

39
Components Available Only on Specific OS RAD Studio 1.5 Developing Applications with VCL

Component Windows Windows XP Windows Vista


2000
CheckBox, Checked, and FixedWidth properties for THeaderSection No No Yes
CheckBoxes, NoSizing and OverFlow properties to THeaderControl No No Yes
Group support for TListView No Yes Yes
ImageList support for TButton No Yes Yes
1
Platform Default Style for ActionMenus/ActionToolBars Yes, Yes, XP style Yes, Vista style
standard
style
Support of transparent PNGs in TImage Yes Yes Yes
TBalloonHints, Vista style No Yes, with themes Yes
enabled
TButton.ElevationRequired No No Yes
TButton.CommandLink No No Yes
TButton.SplitButton No No Yes
TComboBox.TextHint No No Yes
TEdit.TextHint No No Yes
TGlassFrame No No Yes
TImageList.ColorDepth := cd32Bit No Yes, with themes Yes, with themes
enabled enabled
TLabel.GlowSize (only on TGlassFrame) No No Yes
TLinkLabel No (plain text Yes, with themes Yes, with themes
only) enabled enabled
TListView collapsible groups No No Yes
TProgessBar colors and progress automatically set for state by the No Yes, with themes Yes
engines enabled
TProgressBar.SmoothReverse No No Yes
TStaticText support HTML links in the textfield. AllowLInks property No Yes, with themes Yes
enabled
TTaskDialog No No Yes

See Also
Building a VCL Forms Application ( see page 99)

Building a VCL Forms "Hello world" Application ( see page 101)

40
1.6 Developing Web Applications with RAD Studio Win32 Web Applications Overview

1.6 Developing Web Applications with WebSnap


This section provides a conceptual background for building WebSnap applications using RAD Studio. WebSnap makes it easier
to build Web server applications that deliver complex, data-driven Web pages. WebSnap's support for multiple modules and for
server-side scripting makes development and maintenance easier for teams of developers and Web designers. 1
Please note that WebSnap is being deprecated in RAD Studio. Although WebSnap is still documented in the online help, the
WebSnap product is no longer fully supported. As an alternative, you should begin using IntraWeb (VCL for the Web). IntraWeb
( see page 2254) is documented in this online help. For more documentation on VCL for the Web, go to
http://www.atozed.com/intraweb/docs/.

Topics
Name Description
Win32 Web Applications Overview ( see page 41) This section covers:

• Web Application Support


• Web Broker Overview
• Web Snap Overview
• Debugging With the Web Application Debugger
For more detailed information on web applications, please
see the Win32 Developers Guide in the Reference section
of this Help system.

1.6.1 Win32 Web Applications Overview


This section covers:

• Web Application Support


• Web Broker Overview
• Web Snap Overview
• Debugging With the Web Application Debugger
For more detailed information on web applications, please see the Win32 Developers Guide in the Reference section of this Help
system.
Win32 Web Application Support
The following types of web applications will be supported in RAD Studio.

• ISAPI
• CGI
• Web Application Debugger
Apache web applications are not supported for this release.

ISAPI
Selecting this type of application sets up your project as a DLL, with the exported methods expected by the Web server. It adds
the library header to the project file, and the required entries to the uses list and exports clause of the project file.

41
Win32 Web Applications Overview RAD Studio 1.6 Developing Web Applications with

CGI
Selecting this type of application sets up your project as a console application, and adds the required entries to the uses clause
of the project file.

Web Application Debugger


Selecting this type of application sets up an environment for developing and testing Web server applications. This type of
1 application is not intended for deployment.

Web Broker Overview


Web Broker components, located on the Internet tab of the Component Palette, enable you to create event handlers that are
associated with a specific Uniform Resource Identifier (URI). When processing is complete, you can construct HTML or XML
documents within your program and transfer them to the client. You can use Web Broker components for cross-platform
application development.

Frequently, the content of Web pages is drawn from databases. You can use Internet components to automatically manage
connections to databases, allowing a single DLL to handle multiple simultaneous, thread-safe, database connections.

Web Snap Overview


Note: WebSnap is being deprecated in RAD Studio. Although WebSnap is still documented in the online help, the WebSnap
product is no longer fully supported. As an alternative, you should begin using IntraWeb (VCL for the Web). IntraWeb ( see
page 2254) is documented in this online help. For more documentation on VCL for the Web, go to
http://www.atozed.com/intraweb/docs/.

WebSnap augments Web Broker with additional components, wizards, and views, making it easier to build Web server
applications that deliver complex, data-driven Web pages. WebSnap's support for multiple modules and for server-side scripting
makes development and maintenance easier for teams of developers and Web designers. WebSnap allows HTML design
experts on your team to make a more effective contribution to Web server development and maintenance.

The final product of the WebSnap development process includes a series of scriptable HTML page templates. These pages can
be changed using HTML editors that support embedded script tags, like Microsoft FrontPage, or even a text editor. Changes can
be made to the templates as needed, even after the application is deployed. There is no need to modify the project source code
at all, which saves valuable development time. WebSnap’s multiple module support can be used to divide your application into
smaller pieces during the coding phases of your project, so that developers can work more independently.

Debugging With the Web Application Debugger


The Web Application Debugger provides an easy way to monitor HTTP requests, responses, and response times. The Web
Application Debugger takes the place of the Web server. Once you have debugged your application, you can convert it to one of
the supported types of Web application and install it with a commercial Web server.

To use the Web Application Debugger, you must first create your Web application as a Web Application Debugger executable.
Whether you are using Web Broker or WebSnap, the wizard that creates your Web server application includes this as an option
when you first begin the application. This creates a Web server application that is also a COM server. The first time you run your
application, it registers your COM server so that the Web Application Debugger can access it. Before you can run the Web
Application Debugger, you will need to run bin\serverinfo.exe once to register the ServerInfo application.

Launching your application with the Web Application Debugger


Once you have developed your Web server application, you can run and debug it using the Web Application Debugger. You can
set breakpoints in it just like any other executable. When you run your application, it displays the console window of the COM
server that is your Web server application. Once you start your application and run the Web App Debugger, the ServerInfo page
is displayed in your default browser, and you can select your application from a drop-down list. Once you have selected your
application, click the Go button. This launches your application in the Web Application Debugger, which provides you with details
on request and response messages that pass between your application and the Web Application Debugger.

42
1.6 Developing Web Applications with RAD Studio Win32 Web Applications Overview

Converting your application to another type of Web server application after debugging
When you have finished debugging your Web server application with the Web Application Debugger, you will need to convert it
to another type that can be installed on a commercial Web server.

See Also
Building a WebSnap Application ( see page 148)

Building a WebSnap "Hello world" Application ( see page 149) 1


Debugging a WebSnap Application Using the Web Application Debugger ( see page 150)

Converting Your Application to Another Type of Web Server Application ( see page 2245)

Using IntraWeb ( see page 2254)

43
Web Services Overview RAD Studio 1.7 Developing Web Services with Win32

1.7 Developing Web Services with Win32


Applications
1 Web Services are self-contained modular applications that can be published and invoked over the Internet. Web Services
provide well-defined interfaces that describe the services provided. Unlike Web server applications that generate Web pages for
client browsers, Web Services are not designed for direct human interaction. Rather, they are accessed programmatically by
client applications. This section gives an overview of web services and web services support.

Topics
Name Description
Web Services Overview ( see page 44) Web Service applications are server implementations that do not require clients
to use a specific platform or programming language. These applications define
interfaces in a language-neutral document, and they allow multiple
communication mechanisms.
Web Services are designed to work using Simple Object Access Protocol
(SOAP). SOAP is a standard lightweight protocol for exchanging information in a
decentralized, distributed environment. SOAP uses XML to encode remote
procedure calls and typically uses HTTP as a communications protocol.
Web Service applications use a Web Service Definition Language (WSDL)
document to publish information on interfaces that are available and how to call
them. On... more ( see page 44)

1.7.1 Web Services Overview


Web Service applications are server implementations that do not require clients to use a specific platform or programming
language. These applications define interfaces in a language-neutral document, and they allow multiple communication
mechanisms.

Web Services are designed to work using Simple Object Access Protocol (SOAP). SOAP is a standard lightweight protocol for
exchanging information in a decentralized, distributed environment. SOAP uses XML to encode remote procedure calls and
typically uses HTTP as a communications protocol.

Web Service applications use a Web Service Definition Language (WSDL) document to publish information on interfaces that
are available and how to call them. On the server side, your application can publish a WSDL document that describes your Web
Service. On the client side, a wizard or command-line utility can import a published WSDL document, providing you with the
interface definitions and connection information you need. If you already have a WSDL document that describes the Web service
you want to implement, you can generate the server-side code when you import the WSDL document.

See Also
Using Web Services ( see page 2291)

44
1.8 Developing Windows Applications RAD Studio Windows Overview

1.8 Developing Windows Applications


Windows provides a traditional approach to developing user interfaces, client/server applications, controls, and application logic.
This section provides an overview of Windows application development using RAD Studio for Win32 and outlines the steps you
would use to build a simple Windows project. 1
Topics
Name Description
Windows Overview ( see page 45) The Windows platform provides several ways to help you create and build
applications. The most common types of Windows applications are:

• GUI Applications
• Console Applications
• Service Applications
• Packages and DLLs

1.8.1 Windows Overview


The Windows platform provides several ways to help you create and build applications. The most common types of Windows
applications are:

• GUI Applications
• Console Applications
• Service Applications
• Packages and DLLs
GUI Applications
A graphical user interface (GUI) application is designed using graphical components such as windows, menus, dialog boxes, and
other features that make the application easy to use. When you compile a GUI application, an executable file with start-up code
is created from your source files. The executable usually provides the basic functionality of your program. Simple programs often
consist of only an executable file. You can extend the application by calling DLLs, packages, and other support files from the
executable.

The RAD Studio IDE offers two application UI models:

• Single Document Interface (SDI)


• Multiple Document Interface (MDI)

Single Document Interface


A SDI application normally contains a single document view.

Multiple Document Interface


In an MDI application, more than one document or child window can be opened within a single parent window. This is common in
applications such as spreadsheets or word processors.

45
Windows Overview RAD Studio 1.8 Developing Windows Applications

MDI applications require more planning and are more complex to design than SDI applications. MDI applications spawn child
windows that reside within the client window; the main form contains child forms. For instance, you need to set the FormStyle
property of the TForm object to specify whether a form is a child (fsMDIChild) or main form (fsMDIForm). It is a best practice to
define a base class for your child forms and derive each child form from this class. Otherwise, you will have to reset the form
properties of the child. MDI applications often include a Window pop-up on the main menu that has items such as Cascade and
Tile for viewing multiple windows in various styles. When a child window is minimized, its icon is located in the MDI parent form.

Console Applications
1 Console applications are 32-bit programs that run in a console window without a graphical interface. These applications typically
do not require much user input and perform a limited set of functions. Any application that contains {$APPTYPE CONSOLE} in
the code opens a console window of its own.

Service Applications
Service applications take requests from client applications, process those requests, and return the information to the client
applications. Service applications typically run in the background without much user input. A Web, FTP, or an email server is an
example of a service application.

Creating Packages and DLLs


Dynamic link libraries (DLLs) are modules of compiled code that work in conjunction with an executable to provide functionality to
an application. You can create DLLs in cross-platform programs.

Packages are special DLLs used by Delphi applications, the IDE, or both. The two types of packages are runtime and
designtime. Runtime packages provide functionality to a program while that program is running. Designtime packages extend the
functionality of the IDE.

For most applications, packages provide greater flexibility and are easier to create than DLLs. However,here are a few situations
where DLLs would work better than packages:

• Your code module will be called from non-Delphi applications.


• You are extending the functionality of a Web server.
• You are creating a code module to be used by third-party developers.
• Your project is an OLE container.
You cannot pass Delphi runtime type information (RTTI) across DLLs or from a DLL to an executable. If you pass an object from
one DLL to another DLL or to an executable, you will not be able to use the is or as operators with the passed object. This is
because the is and as operators need to compare RTTI. If you need to pass objects from a library, use packages instead of
DLLs, because packages can share RTTI. Similarly, you should use packages instead of DLLs in Web Services because they
rely on Delphi RTTI.
See Also
Building a Windows Application ( see page 89)

Building a Windows “Hello World” Console Application ( see page 88)

Building a VCL Forms “Hello World” Application ( see page 101)

46
2 RAD Studio

2 Procedures
This section provides how-to information for various areas of RAD Studio development.

Topics
Name Description
CodeGuard Procedures ( see page 48) Use these procedures to debug your C++ applications with CodeGuard.
Database Procedures ( see page 50) This topic describes how to use the database components in the Tool Palette,
like dbGo components, dbExpress components, BDE components, and
DataSnap components.
Interoperable Applications Procedures ( see page 79) Delphi provides wizards and classes to make it easy to implement applications
2
based on the Component Object Model (COM) from Microsoft. The simplest
COM objects are servers that expose properties and methods (and possibly
events) through a default interface that clients can call. The COM Object Wizard
builds a lightweight COM object whose default interface descends from
IUnknown or that implements an interface already registered on your system.
This wizard provides the most flexibility in the types of COM objects you can
create.
Reporting Procedures ( see page 81) This topic provides how-to information on using reporting solutions.
VCL Procedures ( see page 82) This section provides how-to information on developing VCL for Win32
applications.
WebSnap Procedures ( see page 147) This section provides how-to information on developing WebSnap applications.
Please note that WebSnap is being deprecated in RAD Studio. Although
WebSnap is still documented in the online help, the WebSnap product is no
longer fully supported. As an alternative, you should begin using IntraWeb (VCL
for the Web). IntraWeb ( see page 2254) is documented in this online help. For
more documentation on VCL for the Web, go to
http://www.atozed.com/intraweb/docs/.
Web Services Procedure ( see page 153) This section provides how-to information on developing and using web services.

47
Using CodeGuard RAD Studio 2.1 CodeGuard Procedures

2.1 CodeGuard Procedures


Use these procedures to debug your C++ applications with CodeGuard.

Topics
Name Description
Using CodeGuard ( see page 48) This procedure describes how to use CodeGuard when debugging a C++
application.

2.1.1 Using CodeGuard


This procedure describes how to use CodeGuard when debugging a C++ application.

To run a C++ application with CodeGuard reporting


1. Enable the CodeGuard reporting tool.
2. Enable CodeGuard compiler options for your project.
3. Choose Run Run to run your application.
During the execution of your application, CodeGuard runtime errors appear in the Message view.

2 CodeGuard also generates an error log named <project_name>.cgl that lists any errors it finds. The error log is located in
the same directory as your executable.
Note: If you suspect that your program accesses a freed memory block but CodeGuard does not report an error, increase the
value of Maximum memory block size
or Delay queue length on the Resource Options page of the Configure CodeGuard dialog box.

To enable the CodeGuard reporting tool


1. Choose Tools CodeGuard Configuration to display the CodeGuard Configuration dialog box.
2. Verify that CodeGuard is enabled.
3. Click OK.
Note: If you change any CodeGuard settings in the CodeGuard Configuration
dialog box, CodeGuard generates a .cgi configuration file with the same name and directory as your project file.

To enable CodeGuard compiler options for your project


1. Choose Project Options C++ Compiler Debugging to display the CodeGuard compiler options.
2. Check Enable all CodeGuard options to enable full CodeGuard coverage.
3. Click OK.
4. Rebuild your project.
Note: If you compile and link your project in separate steps, remember to include the CodeGuard library (cg32.lib
) before including other libraries.
See Also
CodeGuard Overview ( see page 9)

48
2.1 CodeGuard Procedures RAD Studio Using CodeGuard

CodeGuard Configuration dialog box

49
RAD Studio 2.2 Database Procedures

2.2 Database Procedures


This topic describes how to use the database components in the Tool Palette, like dbGo components, dbExpress components,
BDE components, and DataSnap components.

Topics
Name Description
Accessing Schema Information ( see page 51) The schema information or metadata includes information about what tables and
stored procedures are available on the server and the information about these
tables and stored procedures (like the fields of a table, the indexes that are
defined, and the parameters a stored procedure uses).
Using Data Explorer to Obtain Connection Information ( see page 52) Before you have a connection, you can use Data Explorer to assemble
connection strings.
Configuring TSQL Connection ( see page 53) The first step when working with a unidirectional dataset is to connect it to a
database server. At designtime, once a dataset has an active connection to a
database server, the Object Inspector can provide drop-down lists of values for
other properties. For example, when representing a stored procedure, you must
have an active connection before the Object Inspector can list what stored
procedures are available on the server. The connection to a database server is
represented by a separate TSQLConnection component. You work with
TSQLConnection like any other database connection component.
Connecting to the Application Server using DataSnap Components ( see page A client application uses one or more connection components in the DataSnap
55) category of the Tool Palette to establish and maintain a connection to an
application server.
Debugging dbExpress Applications using TSQLMonitor ( see page 55) While you are debugging your database application, you can monitor the SQL
messages that are sent to and from the database server through your connection
component, including those that are generated automatically for you (for example
2 by a provider component or by the dbExpress driver).
Executing the Commands using TSQLDataSet ( see page 56) You can use a unidirectional dataset even if the query or stored procedure it
represents does not return any records. Such commands include statements that
use Data Definition Language (DDL) or Data Manipulation Language (DML)
statements other than SELECT statements. The language used in commands is
server-specific, but usually compliant with the SQL-92 standard for the SQL
language. The SQL command you execute must be acceptable to the server you
are using. Unidirectional datasets neither evaluate the SQL nor execute it, but
pass the command to the server for execution.
Fetching the Data using TSQLDataSet ( see page 57)
Specifying the Data to Display using TSQLDataSet ( see page 58)
Specifying the Provider using TLocalConnection or TConnectionBroker ( see Client datasets are specialized datasets that hold all the data in memory. They
page 59) use a provider to supply them with data and apply updates when they cache
updates from a database server or another dataset, represent the data in an XML
document, and store the data in the client portion of a multi-tiered application.
Using BDE ( see page 60)
Using DataSnap ( see page 60) A multi-tiered client/server application is partitioned into logical units, called tiers,
which run in conjunction on separate machines. Multi-tiered applications share
data and communicate with one another over a local-area network or even over
the Internet. They provide many benefits, such as centralized business logic and
thin client applications.
Multi-tiered applications use the components on the DataSnap category in the
Tool Palette. DataSnap provides multi-tier database capability to Delphi
applications by allowing client applications to connect to providers in an
application server.
Using TBatchMove (BDE) ( see page 61) TBatchMove copies a table structure or its data. It can be used to move entire
tables from one database format to another.

50
2.2 Database Procedures RAD Studio Accessing Schema Information

Connecting to Databases with TDatabase ( see page 62) TDatabase sets up a persistent connection to a database, especially a remote
database requiring a user login and password. TDatabase is especially important
because it permits control over database transaction processing with the BDE
when connected to a remote SQL database server. Use TDatabase when a
BDE-based database application requires:

• Persistent database connections


• Customized database server logins
• Transaction control
• Application-specific BDE aliases
Using TQuery (Procedure) ( see page 63) TQuery is a query-type dataset that encapsulates an SQL statement and
enables applications to access the resulting records.
Using TSQLQuery ( see page 65) TSQLQuery represents a query that is executed using dbExpress. TSQLQuery
can represent the results of a SELECT statement or perform actions on the
database server using statements such as INSERT, DELETE, UPDATE, ALTER
TABLE, and so on. You can add a TSQLQuery component to a form at design
time, or create one dynamically at runtime.
Using TSQLStoredProc (Procedure) ( see page 66) TSQLStoredProc represents a stored procedure that is executed using
dbExpress. TSQLStoredProc can represent the result set if the stored procedure
returns a cursor. You can add a TSQLStoredProc component to a form at
design time, or create one dynamically at runtime.
Using TSQLTable ( see page 66) TSQLTable represents a database table that is accessed using dbExpress.
TSQLTable generates a query to fetch all of the rows and columns in a table you
specify. You can add a TSQLTable component to a form at designtime, or create
one dynamically at runtime.
Managing Database Sessions Using TSession ( see page 67) A session provides global connection over a group of database components. A
default TSession component is automatically created for each database
application. You must use TSession component only if you are creating a
multithreaded database application. Each database thread requires its own
session components.
Using TSimpleDataSet ( see page 68) TSimpleDataSet is a special type of client dataset designed for simple two-tiered
applications. Like a unidirectional dataset, it can use an SQL connection
component to connect to a database server and specify an SQL statement to 2
execute on that server. Like other client datasets, it buffers data in memory to
allow full navigation and editing support.
Using TSimpleObjectBroker ( see page 69) If you have multiple COM-based servers that your client application can choose
from, you can use an Object Broker to locate an available server system.
Using TStoredProc ( see page 69) TStoredProc is a stored procedure-type dataset that executes a stored procedure
that is defined on a database server.
Using TTable (Procedure) ( see page 70) TTable is a table-type dataset that represents all of the rows and columns of a
single database table.
Using TUpdateSQL to Update a Dataset ( see page 72) When the BDE-enabled dataset represents a stored procedure or a query that is
not “live”, it is not possible to apply updates directly from the dataset. Such
datasets may also cause a problem when you use a client dataset to cache
updates.
Using dbExpress ( see page 72)
Adding a New Connection to the Data Explorer ( see page 73) You can add new connections to the Data Explorer, which persist as long as the
connection object exists.
Browsing a Database in the Data Explorer ( see page 74) Once you have a live connection, you can use the Data Explorer to browse
database objects.
Executing SQL in the Data Explorer ( see page 74) You can write, edit, and execute SQL in an SQL Window, which is available from
within the Data Explorer.
Modifying Connections in the Data Explorer ( see page 75) You can modify connections in a variety of ways from the Data Explorer.
Connecting to a Database using the dbExpress Driver Framework ( see page This procedure tells how to use the dbExpress driver framework to connect to a
76) database and read its records. In the sample code, the dbExpress ini files
contain all the information about the particular database connection, such as
driver, user name, password, and so on.

2.2.1 Accessing Schema Information


The schema information or metadata includes information about what tables and stored procedures are available on the server

51
Using Data Explorer to Obtain Connection RAD Studio 2.2 Database Procedures

and the information about these tables and stored procedures (like the fields of a table, the indexes that are defined, and the
parameters a stored procedure uses).

To access schema information


1. To populate a unidirectional dataset with metadata from the database server, call SetSchemaInfo method to indicate what
data you want to see.
2. Set the type of schema information parameter of SetSchemaInfo method.
3. Set the name of table or stored procedure parameter of SetSchemaInfo method.
4. To fetch data after using the dataset for metadata, do one of the following:
• Set the CommandText property to specify the query, table, or stored procedure from which you want to fetch data.
• Set the type of schema information to stNoSchema and call SetSchemaInfo method.
Note: If you choose the second option, the dataset fetches the data specified by the CommandText property.

See Also
dbExpress Components ( see page 16)

Configuring TSQLConnection ( see page 53)

Specifying Display Data ( see page 58)

Fetching the Data ( see page 57)

Executing the Commands ( see page 56)

Debugging dbExpress Applications ( see page 55)


2
Using TSQLTable ( see page 66)

Using TSQLStoredProc ( see page 66)

Using TSQLQuery ( see page 65)

Using TSimpleDataSet ( see page 68)

Using Unidirectional Datasets ( see page 1823)

2.2.2 Using Data Explorer to Obtain Connection Information


Before you have a connection, you can use Data Explorer to assemble connection strings.

To browse database providers


1. Choose View Data Explorer or click the Data Explorer tab in the Project Manager.
2. Expand a provider node under dbExpress to expose the list of available database providers.
3. Expand the second–level provider node to view the list of potential connections.

To get connection information


1. In the Data Explorer list of providers, right-click a second–level provider.
2. In the context menu, click Modify Connection. The Modify Connection dialog is displayed.
3. In the Modify Connection dialog, click Advanced. The Advanced Properties dialog is displayed, containing a scrollable list

52
2.2 Database Procedures RAD Studio Configuring TSQL Connection

of connection properties. The left column contains connection string keys; the right column contains their values.

To format a connection string


1. In the Advanced Properties dialog, enter values in the right-hand column for the connection properties named in the left
column.
2. The text field at the bottom of the Advanced Properties dialog contains the resulting connection string text. Drag the cursor
over the connection string text to select the connection string text. Copy the text. You can then paste this connection string
wherever you want.
See Also
Browsing a Database in the Data Explorer ( see page 74)

Adding a New Connection ( see page 73)

Modifying Connections ( see page 75)

2.2.3 Configuring TSQL Connection


The first step when working with a unidirectional dataset is to connect it to a database server. At designtime, once a dataset has
an active connection to a database server, the Object Inspector can provide drop-down lists of values for other properties. For
example, when representing a stored procedure, you must have an active connection before the Object Inspector can list what
stored procedures are available on the server. The connection to a database server is represented by a separate
TSQLConnection component. You work with TSQLConnection like any other database connection component.

Metaprocedure: Configuring a TSQL Connection 2


1. Choose File New Other. The New Items dialog appears.
2. In the New Items dialog, select Delphi Projects and double-click VCL Forms Application. The Windows Designer
displays.
3. From the dbExpress category of the Tool Palette, drag a TSQLConnection component to the form.
4. Identify the driver (see steps below).
5. Specify connection parameters (see steps below).
6. Identify a database connection (see steps below).
7. Display and use the dbExpress Connection Editor (see steps below).

To identify the driver


1. Select the TSQLConnection component.
2. In the Object Inspector, set the DriverName property, to an installed dbExpress driver.
3. Identify the files associated with the driver name. Select any of the following:
• The dbExpress driver
• The dynamic link library
Note: The relationship between the dbExpress driver or dynamic link library and the database name is stored in a file called
dbxdrivers.ini
, which is updated when you install a dbExpress driver. The SQL connection component looks the dbExpress driver and the
dynamic-link library up in dbxdrivers.ini when given the value of DriverName. When you set the DriverName property,
TSQLConnection automatically sets the LibraryName and VendorLib properties to the names of the associated dlls. Once
LibraryName and VendorLib have been set, your application does not need to rely on dbxdrivers.ini.

53
Configuring TSQL Connection RAD Studio 2.2 Database Procedures

To specify a connection parameter


1. Double-click on the Params property in the Object Inspector to edit the parameters using Value List Editor at designtime.
2. Use the Params.Values property to assign values to individual parameters at run time.

To identify a database connection


1. Set the ConnectionName property to a valid connection name. This automatically sets the DriverName and Params
properties.
2. Edit the Params property to change the saved set of parameter values.
3. Set the LoadParamsOnConnect property to True to develop your application using one database and deploy it using another.
This causes TSQLConnection to automatically set DriverName and Params to the values associated with ConnectionName
in dbxconnections.ini when the connection is opened.
4. Call the LoadParamsFromIniFile method. This method sets DriverName and Params to the values associated with
ConnectionName in dbxconnections.ini (or in another file that you specify). You might choose to use this method if you
want to then override certain parameter values before opening the connection.

To display the Connection Editor


1. Double-click the TSQLConnection component. The dbExpress Connection Editor appears, with a drop-down drivers list, a
list of connection names for the currently selected driver, and a connection parameters table for the currently selected
connection name.
2. From the Driver Name drop-down list, select a driver to indicate the connection to use.
3. From the Connection Name list, select a connection name.
4. Choose the configuration that you want.

2 5. Click the Test Connection button to check for a valid configuration.

To define and modify connections using the Connection Editor


1. To edit the currently selected named connections in dbxconnections.ini, edit the parameter values in the parameter
table.
2. Click OK. The new parameter values are saved to dbxconnections.ini.
3. Click the Add Connection button to define a new connection. The New Connection dialog appears.
4. In the New Connection dialog box, set the Driver Name and the Connection Name.
5. Click OK.
6. Click the Delete Connection button to delete the currently selected named connection from dbxconnections.ini.
7. Click the Rename Connection button to change the name of the currently selected named connection.
See Also
dbExpress Components ( see page 16)

Specifying Display Data ( see page 58)

Fetching the Data ( see page 57)

Executing the Commands ( see page 56)

Accessing Schema Information ( see page 51)

Debugging dbExpress Applications ( see page 55)

Using TSQLTable ( see page 66)

Using TSQLStoredProc ( see page 66)

54
2.2 Database Procedures RAD Studio Debugging dbExpress Applications using

Using TSQLQuery ( see page 65)

Using TSimpleDataSet ( see page 68)

Using Unidirectional Datasets ( see page 1823)

2.2.4 Connecting to the Application Server using DataSnap


Components
A client application uses one or more connection components in the DataSnap category of the Tool Palette to establish and
maintain a connection to an application server.

To connect to the application server using DataSnap components


1. Identify the protocol for communicating with the application server.
2. Locate the server machine.
3. Identify the application server on the server machine.
4. If you are not using SOAP, identify the server using the ServerName or ServerGUID property.
5. Manage server connections.
See Also
Connecting to the Application Server ( see page 1517)

Using TLocalConnection or TConnectionBroker ( see page 59)


2
Using TSimpleObjectBroker ( see page 69)

2.2.5 Debugging dbExpress Applications using TSQLMonitor


While you are debugging your database application, you can monitor the SQL messages that are sent to and from the database
server through your connection component, including those that are generated automatically for you (for example by a provider
component or by the dbExpress driver).

To debug dbExpress applications


1. Choose File New Other. The New Items dialog appears.
2. In the New Items dialog, select Delphi Projects and double-click VCL Forms Application. The Windows Designer
displays.
3. To monitor SQL commands, from the dbExpress category of the Tool Palette, drag a TSQLMonitor component to the form.
4. Set the SQLConnection property of the TSQLMonitor to the TSQLConnection component.
5. Set the Active property of the TSQLMonitor to True.

To use a callback to monitor SQL commands


1. Use the SetTraceEvent method of the TSQLConnection component.
2. Set the TDBXTraceEvent event parameter.
The dbExpress driver triggers the event every time the SQL connection component passes a command to the server or the

55
Executing the Commands using RAD Studio 2.2 Database Procedures

server returns an error message.


Warning: Do not call SetTraceEvent if the TSQLConnection
object has an associated TSQLMonitor component. TSQLMonitor uses the callback mechanism to work, and
TSQLConnection can only support one callback at a time.
See Also
dbExpress Components ( see page 16)

Configuring TSQLConnection ( see page 53)

Specifying Display Data ( see page 58)

Fetching the Data ( see page 57)

Executing the Commands ( see page 56)

Accessing Schema Information ( see page 51)

Using Unidirectional Datasets ( see page 1823)

2.2.6 Executing the Commands using TSQLDataSet


You can use a unidirectional dataset even if the query or stored procedure it represents does not return any records. Such
commands include statements that use Data Definition Language (DDL) or Data Manipulation Language (DML) statements other
than SELECT statements. The language used in commands is server-specific, but usually compliant with the SQL-92 standard
for the SQL language. The SQL command you execute must be acceptable to the server you are using. Unidirectional datasets
2 neither evaluate the SQL nor execute it, but pass the command to the server for execution.

To execute commands
1. Choose File New Other. The New Items dialog appears.
2. In the New Items dialog, select Delphi Projects and double-click VCL Forms Application. The Windows Designer
displays.
3. From the dbExpress category of the Tool Palette, drag a TSQLDataSet component to the form.
4. Specify the command to execute.
5. Execute the command.
6. Create and modify server metadata.

To specify the command to execute


1. Set the CommandType and CommandText properties in the Object Inspector to specify the command for a TSQLDataSet.
2. Set the SQL property in the Object Inspector to specify the SQL statement to pass to the server for a TSQLQuery .
3. Set the StoredProcName property in the Object Inspector to specify the name of the stored procedure to execute for a
TSQLStoredProc .

To execute the command


1. If the dataset is an instance of a TSQLDataSet or a TSQLQuery, call the ExecSQL method.
2. If the dataset is an instance of a TSQLStoredProc, call the ExecProc method.
Tip: If you are executing the query or stored procedure multiple times, it is a good idea to set the Prepared property to True.

56
2.2 Database Procedures RAD Studio Fetching the Data using TSQLDataSet

To create and modify server metadata


1. To create tables in a database, use the CREATE TABLE statement.
2. To create new indexes for those tables, use the CREATE INDEX statement.
3. To add various metadata objects, use CREATE DOMAIN, CREATE VIEW, CREATE SCHEMA, and CREATE PROCEDURE
statements.
4. To delete any of the above metadata objects, use DROP TABLE, DROP VIEW, DROP DOMAIN, DROP SCHEMA, and
DROP PROCEDURE.
5. To change the structure of a table, use the ALTER TABLE statement.
See Also
dbExpress Components ( see page 16)

Configuring TSQLConnection ( see page 53)

Specifying Display Data ( see page 58)

Fetching the Data ( see page 57)

Accessing Schema Information ( see page 51)

Debugging dbExpress Applications ( see page 55)

Using TSQLTable ( see page 66)

Using TSQLStoredProc ( see page 66)

Using TSQLQuery ( see page 65)

Using Unidirectional Datasets ( see page 1823) 2

2.2.7 Fetching the Data using TSQLDataSet


To fetch the data
1. Choose File New Other. The New Items dialog appears.
2. In the New Items dialog, select Delphi Projects and double-click VCL Forms Application. The Windows Designer
displays.
3. From the dbExpress category of the Tool Palette, drag a TSQLDataSet component to the form.
4. To fetch the data for a unidirectional dataset, do one of the following:
• In the Object Inspector, set the Active property to True.
• Call the Open method at runtime.
Tip: Use GetMetadata property to selectively fetch metadata on a database object. Set GetMetadata to False if you are
fetching a dataset for read-only purposes.

5. Set its Prepared property to True to prepare the dataset explicitly.


6. Call the NextRecordSet method to fetch multiple sets of records.
Note: NextRecordSet returns a newly created TCustomSQLDataSet component that provides access to the next set of
records. That is, the first time you call NextRecordSet, it returns a dataset for the second set of records. Calling
NextRecordSet returns a third dataset, and so on, until there are no more sets of records. When there are no additional
datasets, NextRecordSet does not return anything.

57
Specifying the Data to Display using RAD Studio 2.2 Database Procedures

See Also
dbExpress Components ( see page 16)

Specifying Display Data ( see page 58)

Fetching the Data

Executing the Commands ( see page 56)

Accessing Schema Information ( see page 51)

Debugging dbExpress Applications ( see page 55)

Using TSQLTable ( see page 66)

Using TSQLStoredProc ( see page 66)

Using TSQLQuery ( see page 65)

Using Unidirectional Datasets ( see page 1823)

2.2.8 Specifying the Data to Display using TSQLDataSet


To specify the data to display
1. Choose File New Other. The New Items dialog appears.
2. In the New Items dialog, select Delphi Projects and double-click VCL Forms Application. The Windows Designer
2 displays.
3. From the dbExpress category of the Tool Palette, drag a TSQLDataSet component to the form.
4. For TSQLDataSet, specify the type of unidirectional dataset by CommandType property in the Object Inspector.
5. Specify whether information comes from results of query, a database table, or a stored procedure.

To display results from a query


1. Set the CommandType property to ctQuery for a TSQLDataSet.
2. For TSQLQuery, drag a TSQLQuery component from the Tool Palette to the form.
3. Set the SQL property to the query you want to assign.
4. Select TSQLDataSet.
5. Click the CommandText property. The CommandText Editor opens.
6. In the CommandText Editor, set the SQL property to the text of the query statement.
Note: When you specify the query, it can include parameters, or variables, the values of which can be varied at design time
or runtime. Parameters can replace data values that appear in the SQL statement. SQL defines queries such as UPDATE
queries that perform actions on the server but do not return records.

To display records in a table


1. In the Object Inspector, set the CommandType property to ctTable. TSQLDataSet generates a query based on the values of
two properties: CommandText that specifies the name of the database table that the TSQLDataSet object should represent
and SortFieldNames that lists the names of any fields to use to sort the data, in the order of significance
2. Drag a TSQLTable component to the form.
3. In the Object Inspector , set the TableName property to the table you want.
4. Set the IndexName property to the name of an index defined on the server or set the IndexFieldNames property to a

58
2.2 Database Procedures RAD Studio Specifying the Provider using

semicolon-delimited list of field names to specify the order of fields in the dataset.

To display the results of a stored procedure


1. In the Object Inspector, set the CommandType property to ctStoredProc.
2. Specify the name of the stored procedure as the value of the CommandText property.
3. Set the StoredProcName property to the name of the stored procedure for TSQLStoredProc.
Note: After you have identified a stored procedure, your application may need to enter values for any input parameters of the
stored procedure or retrieve the values of output parameters after you execute the stored procedure.
See Also
dbExpress Components ( see page 16)

Configuring TSQLConnection ( see page 53)

Fetching the Data ( see page 57)

Executing the Commands ( see page 56)

Accessing Schema Information ( see page 51)

Debugging dbExpress Applications ( see page 55)

Using TSQLTable ( see page 66)

Using TSQLStoredProc ( see page 66)

Using TSQLQuery ( see page 65)

Using TSimpleDataSet ( see page 68)

Using Unidirectional Datasets ( see page 1823) 2

2.2.9 Specifying the Provider using TLocalConnection or


TConnectionBroker
Client datasets are specialized datasets that hold all the data in memory. They use a provider to supply them with data and apply
updates when they cache updates from a database server or another dataset, represent the data in an XML document, and store
the data in the client portion of a multi-tiered application.

To specify the provider


1. Choose File New Other. The New Items dialog appears.
2. In the New Items dialog, select Delphi Projects and double-click VCL Forms Application. The Windows Designer
displays.
3. From the DataSnap category of the Tool Palette, drag a TConnectionBroker component to the form if the provider is on a
remote application server.
4. In the Object Inspector, set the ConnectionBroker property of your client dataset to the TConnectionBroker component to
the form.
5. From the DataSnap category of the Tool Palette, drag a TLocalConnection component to the form if the provider is in the
same application as the client dataset.
6. Set the RemoteServer property of your client dataset to the TLocalConnection component to the form.

59
Using DataSnap RAD Studio 2.2 Database Procedures

See Also
Using DataSnap ( see page 60)

Connecting To Application Server ( see page 55)

Using TSimpleObjectBroker ( see page 69)

2.2.10 Using BDE


To use BDE
1. Choose File New Other. The New Items dialog box opens.
2. In the New Items dialog, select Delphi Projects and double-click VCL Forms Application. The Windows Designer
displays.
3. From the BDE category of the Tool Palette, drag a TTable component to the form. This will encapsulate the full structure of
data in an underlying database table.
4. From the BDE category of the Tool Palette, drag a TQuery component to the form. This will encapsulate an SQL statement
and enables applications to access the resulting records.
5. From the BDE category of the Tool Palette, drag a TStoredProc component to the form. This will execute a stored procedure
that is defined on a database server.
6. From the BDE category of the Tool Palette, drag a TBatchMove component to the form. This will copy a table structure or its
data.
7. From the BDE category of the Tool Palette, drag a TUpdateSQL component to the form. This will provide a way to update
2 the underlying datasets.
See Also
BDE Overview ( see page 15)

Using TDatabase ( see page 62)

Using TSession ( see page 67)

Using TTable ( see page 70)

Using TQuery ( see page 63)

Using TStoredProc ( see page 69)

Using TBatchMove ( see page 61)

Using TUpdateSQL ( see page 72)

2.2.11 Using DataSnap


A multi-tiered client/server application is partitioned into logical units, called tiers, which run in conjunction on separate machines.
Multi-tiered applications share data and communicate with one another over a local-area network or even over the Internet. They
provide many benefits, such as centralized business logic and thin client applications.

Multi-tiered applications use the components on the DataSnap category in the Tool Palette. DataSnap provides multi-tier
database capability to Delphi applications by allowing client applications to connect to providers in an application server.

60
2.2 Database Procedures RAD Studio Using TBatchMove (BDE)

To build multi-tiered database applications using DataSnap


1. Choose File New Other. The New Items dialog appears.
2. In the New Items dialog, select Delphi Projects and double-click VCL Forms Application. The Windows Designer
displays.
3. From the DataSnap category of the Tool Palette, drag a TDCOMConnection component to the form. This will establish a
DCOM connection to a remote server in a multi-tiered database application.
4. From the DataSnap category of the Tool Palette, drag a TSocketConnection component to the form. This will establish a
TCP/IP connection to a remote server in a multi-tiered database application.
5. From the DataSnap category of the Tool Palette, drag a TSimpleObjectBroker component to the form. This will locate a
server for a connection component from a list of available application servers.
6. From the DataSnap category of the Tool Palette, drag a TWebConnection component to the form. This will establish an
HTTP connection to a remote server in a multi-tiered database application.
7. From the DataSnap category of the Tool Palette, drag a TConnectionBroker component to the form. This will centralize all
connections to the application server so that applications do not need major rewriting when changing the connection protocol.
8. From the DataSnap category of the Tool Palette, drag a TSharedConnection component to the form. This will connect to a
child remote data module when the application server is built using multiple remote data modules.
9. From the DataSnap category of the Tool Palette, drag a TLocalConnection component to the form. This will provide access
to IAppServer methods that would otherwise be unavailable, and make it easier to scale up to a multi-tiered application at a
later time. It acts like a connection component for providers that reside in the same application.
See Also
Connecting To Application Server ( see page 55)

Deploying Multi-tiered Database Applications (DataSnap) ( see page 1952)


2
Using TLocalConnection or TConnectionBroker ( see page 59)

Using TSimpleObjectBroker ( see page 69)

2.2.12 Using TBatchMove (BDE)


TBatchMove copies a table structure or its data. It can be used to move entire tables from one database format to another.

To use TBatchMove
1. Choose File New Other. The New Items dialog appears.
2. In the New Items dialog, select Delphi Projects and double-click VCL Forms Application. The Windows Designer
displays.
3. Create a batch move component.
4. Specify a batch move mode.
5. Map data types.
6. Execute a batch move.
7. Handle batch move errors.
See Also
Using TBatchMove ( see page 1683)

Using TTable ( see page 70)

61
Connecting to Databases with TDatabase RAD Studio 2.2 Database Procedures

Using TQuery ( see page 63)

Using TStoredProc ( see page 69)

Using Update Objects to Update a Dataset ( see page 1692)

Using TSession ( see page 67)

2.2.13 Connecting to Databases with TDatabase


TDatabase sets up a persistent connection to a database, especially a remote database requiring a user login and password.
TDatabase is especially important because it permits control over database transaction processing with the BDE when
connected to a remote SQL database server. Use TDatabase when a BDE-based database application requires:

• Persistent database connections


• Customized database server logins
• Transaction control
• Application-specific BDE aliases

To connect to databases with TDatabase


1. Choose File New Other. The New Items dialog appears.
2. In the New Items dialog, select Delphi Projects and double-click VCL Forms Application. The Windows Designer
displays.

2 3. Associate a database component with a session.


4. Identify the database.
5. Open a connection using TDatabase.

To associate a database component with a session


1. From the BDE category of the Tool Palette, drag a TDatabase component to the form.
2. Drag a TSession component to the form.
3. In the Object Inspector, set the SessionName property of the TSession component. SessionName is set to “Default," which
means it is associated with the default session component that is referenced by the global Session variable.
4. Add a TSession component for each session if you use multiple sessions.
5. Set the SessionName property of the TDatabase component to the SessionName property of the TSession component to
associate your dataset with a session component.
6. Read the Session property to access the session component with which the database is associated at runtime. If
SessionName is blank or “Default," the Session property references the same TSession instance referenced by the global
Session variable.
Session enables applications to access the properties, methods, and events of a database component’s parent session
component without knowing the session’s actual name. If you are using an implicit database component, the session for that
database component is the one specified by the dataset’s SessionName property.

To identify the database


1. In the drop-down lists for dataset components, specify the alias name or the name of an existing BDE alias for a database
component.
Note: This clears any value already assigned to DriverName. Alternatively, you can specify a driver name instead of an alias
when you create a local BDE alias for a database component using the DatabaseName property. Specifying the driver name

62
2.2 Database Procedures RAD Studio Using TQuery (Procedure)

clears any value already assigned to AliasName. To provide your own name for a database connection, set the
DatabaseName. To specify a BDE alias at designtime, assign a BDE driver.

2. Create a local BDE alias.


3. Double-click a database component. The Database editor opens.
4. In the Name edit box in the properties editor, enter the same name as specified by the DatabaseName property.
5. In the Alias name combo box, enter an existing BDE alias name or choose from existing aliases in the drop-down list.
6. To create or edit connection parameters at designtime, do one of the following:
• Use the Database Explorer or BDE Administration utility.
• Double-click the Params property in the Object Inspector to invoke the Value List editor.
• Double-click a database component in a data module or form to invoke the Database editor.
Note: All of these methods edit the Params property for the database component. When you first invoke the Database
Properties
editor, the parameters for the BDE alias are not visible. To see the current settings, click Defaults. The current parameters
are displayed in the Parameter overrides memo box. You can edit existing entries or add new ones. To clear existing
parameters, click Clear. Changes you make take effect only when you click OK.

To open a connection using TDatabase


1. In the Params property of a TDatabase component, configure the ODBC driver for your application.
2. To connect to a database using TDatabase, set the Connected property to True or call the Open method.
Note: Calling TDatabase. Rollback does not call TDataSet. Cancel for any data sets associated with the database.
See Also 2
BDE Overview ( see page 15)

Using TSession ( see page 67)

Using TTable ( see page 70)

Using TQuery ( see page 63)

Using TStoredProc ( see page 69)

Using TBatchMove ( see page 61)

Using TUpdateSQL ( see page 72)

2.2.14 Using TQuery (Procedure)


TQuery is a query-type dataset that encapsulates an SQL statement and enables applications to access the resulting records.

To use TQuery
1. Choose File New Other. The New Items dialog appears.
2. In the New Items dialog, select Delphi Projects and double-click VCL Forms Application. The Windows Designer
displays.
3. Associate the dataset with database and session connections.
4. Create heterogeneous queries.

63
Using TQuery (Procedure) RAD Studio 2.2 Database Procedures

5. Obtain an editable result set.


6. Update read-only result sets.

To associate a dataset with database and session connections


1. From the BDE category of the Tool Palette, drag a TDatabase component to the form.
2. Drag a TSession component to the form.
3. Set the DatabaseName property of the TDatabase component to associate a BDE-enabled dataset with a database. For the
TDatabase component, database name is the value of the DatabaseName property of the database component.
4. Specify a BDE alias as the value of DatabaseName if you want to use an implicit database component and the database has
a BDE alias.
Note: A BDE alias represents a database plus configuration information for that database. The configuration information
associated with an alias differs by database type (Oracle, Sybase, InterBase, Paradox, dBASE, and so on).

5. In the Object Inspector, set the DatabaseName to specify the directory where the database tables are located if you want to
use an implicit database component for a Paradox or dBASE database.
6. Use the default session to control all database connections in your application.
7. Set the SessionName property of the TSession component to associate your dataset with an explicitly created session
component .
Note: Whether you use the default session or explicitly specify a session using the SessionName property, you can access
the session associated with a dataset by reading the DBSession property. If you use a session component, the SessionName
property of a dataset must match the SessionName property for the database component with which the dataset is
associated.

2 To create mixed queries


1. Define separate BDE aliases for each database accessed in the query using the BDE Administration tool or the SQL explorer.
2. Leave the DatabaseName property of the TQuery component blank. The names of the databases used will be specified in the
SQL statement.
3. Set the SQL property to the SQL statement you want to execute.
4. Precede each table name in the statement with the BDE alias for the database of the table, enclosed in colons. This whole
reference is then enclosed in quotation marks.
5. Set the Params property to any parameters for the query.
6. Write a Prepare method to prepare the query for execution prior to executing it for the first time.
7. Write an Open or ExecSQL method depending on the type of query you are executing.
8. Use a TDatabase component as an alternative to using a BDE alias to specify the database in a mixed query.
9. Configure the TDatabase to the database, set the TDatabase. DatabaseName to an unique value, and use that value in the
SQL statement instead of a BDE alias name.

To obtain an editable result set


1. Set RequestLive property of the TQuery component to True.
2. If the query contains linked fields, treat the result set as a read-only result set, and update it.
If an application requests a live result set, but the SELECT statement syntax does not allow it, the BDE returns either a read-only
result set for queries made against Paradox or dBASE, or an error code for SQL queries made against a remote server.

To update read-only result sets


1. If all updates are applied to a single database table, indicate the underlying table to update in an OnGetTableName event
handler.

64
2.2 Database Procedures RAD Studio Using TSQLQuery

2. Set the query’s UpdateObject property to the TUpdateSQL object you are using to have more control over applying updates.
3. Set the DeleteSQL, InsertSQL, and ModifySQL properties of the update object to the SQL statements that perform the
appropriate updates for your query’s data.
If you are using the BDE to cache updates, you must use an update object.
See Also
BDE Overview ( see page 15)

Using TDatabase ( see page 62)

Using TSession ( see page 67)

Using TTable ( see page 70)

Using TStoredProc ( see page 69)

Using TBatchMove ( see page 61)

Using TUpdateSQL ( see page 72)

2.2.15 Using TSQLQuery


TSQLQuery represents a query that is executed using dbExpress. TSQLQuery can represent the results of a SELECT
statement or perform actions on the database server using statements such as INSERT, DELETE, UPDATE, ALTER TABLE,
and so on. You can add a TSQLQuery component to a form at design time, or create one dynamically at runtime.

To use TSQLQuery 2
1. From the dbExpress category of the Tool Palette, drag a TSQLQuery component to the form.
2. In the Object Inspector, set its Name property to a unique value appropriate to your application.
3. Set the SQLConnection property.
4. Click the ellipsis button next to the SQL property of the TSQLQuery component. The String List editor opens.
5. In the String List editor, type the query statement you want to execute.
6. If the query data is to be used with visual data controls, add a data source component to the form.
7. Set the DataSet property of the data source component to the query-type dataset.
8. To activate the query component, set the Active property to True or call the Open method at runtime.
See Also
dbExpress Components ( see page 16)

Configuring TSQLConnection ( see page 53)

Specifying Display Data ( see page 58)

Fetching the Data ( see page 57)

Executing the Commands ( see page 56)

Accessing Schema Information ( see page 51)

Using TSQLTable ( see page 66)

Using TSQLStoredProc ( see page 66)

Using TSimpleDataSet ( see page 68)

65
Using TSQLTable RAD Studio 2.2 Database Procedures

Using Unidirectional Datasets ( see page 1823)

2.2.16 Using TSQLStoredProc (Procedure)


TSQLStoredProc represents a stored procedure that is executed using dbExpress. TSQLStoredProc can represent the result
set if the stored procedure returns a cursor. You can add a TSQLStoredProc component to a form at design time, or create one
dynamically at runtime.

To use TSQLStoredProc
1. From the dbExpress category of the Tool Palette, drag a TSQLStoredProc component to the form.
2. In the Object Inspector, set its Name property to a unique value appropriate to your application.
3. Set the SQLConnection property.
4. Set the StoredProcName property to specify the stored procedure to execute.
5. If the stored procedure returns a cursor to be used with visual data controls, add a data source component to the form.
6. Set the DataSet property of the data source component to the stored procedure-type dataset.
7. Provide input parameter values for the stored procedure, if necessary.
8. To execute the stored procedure that returns a cursor, use the Active property or call the Open method.
9. Process any results.
See Also

2 dbExpress Components ( see page 16)

Configuring TSQLConnection ( see page 53)

Specifying Display Data ( see page 58)

Fetching the Data ( see page 57)

Executing the Commands ( see page 56)

Accessing Schema Information ( see page 51)

Using TSQLTable ( see page 66)

Using TSQLQuery ( see page 65)

Using TSimpleDataSet ( see page 68)

Using Unidirectional Datasets ( see page 1823)

2.2.17 Using TSQLTable


TSQLTable represents a database table that is accessed using dbExpress. TSQLTable generates a query to fetch all of the
rows and columns in a table you specify. You can add a TSQLTable component to a form at designtime, or create one
dynamically at runtime.

To use TSQLTable
1. Choose File New Other. The New Items dialog displays.

66
2.2 Database Procedures RAD Studio Managing Database Sessions Using

2. In the New Items dialog, select Delphi Projects and double-click VCL Forms Application. The Windows Designer
displays.
3. From the dbExpress category of the Tool Palette, drag a TSQLTable component to the form.
4. In the Object Inspector, set its Name property to a unique value appropriate to your application.
5. Set the SQLConnection property
6. Set the TableName property to the name of the table in the database.
7. Add a data source component to the form.
8. Set the DataSet property of the data source component to the the name of the dataset.
See Also
dbExpress Components ( see page 16)

Configuring TSQLConnection ( see page 53)

Specifying Display Data ( see page 58)

Fetching the Data ( see page 57)

Executing the Commands ( see page 56)

Accessing Schema Information ( see page 51)

Using TSQLStoredProc ( see page 66)

Using TSQLQuery ( see page 65)

Using TSimpleDataSet ( see page 68)

Using Unidirectional Datasets ( see page 1823)


2

2.2.18 Managing Database Sessions Using TSession


A session provides global connection over a group of database components. A default TSession component is automatically
created for each database application. You must use TSession component only if you are creating a multithreaded database
application. Each database thread requires its own session components.

To manage database sessions


1. Choose File New Other. The New Items dialog appears.
2. In the New Items dialog, select Delphi Projects and double-click VCL Forms Application. The Windows Designer
displays.
3. Activate a session.
4. Specify default database connection behavior.
5. Manage database connections.
6. Work with password-protected Paradox and dBASE tables.
7. Work with BDE aliases.
8. Retrieve information about a session.
9. Create, Name, and Manage additional sessions.
See Also
Managing Database Sessions ( see page 1664)

67
Using TSimpleObjectBroker RAD Studio 2.2 Database Procedures

Using TTable ( see page 70)

Using TQuery ( see page 63)

Using TStoredProc ( see page 69)

Using TDatabase ( see page 62)

Using TBatchMove ( see page 61)

Using TUpdateSQL ( see page 72)

2.2.19 Using TSimpleDataSet


TSimpleDataSet is a special type of client dataset designed for simple two-tiered applications. Like a unidirectional dataset, it
can use an SQL connection component to connect to a database server and specify an SQL statement to execute on that
server. Like other client datasets, it buffers data in memory to allow full navigation and editing support.

To use TSQLStoredProc
1. From the dbExpress category of the Tool Palette, drag a TSimpleDataSet component to the form.
2. Set its Name property to a unique value appropriate to your application.
3. From the dbExpress section of the Tool Palette, drag a TSQLConnection component on the form.
4. Select TSimpleDataSet component. Set the Connection property to TSQLConnection component.
5. To fetch data from the server, do any of the following:
2
• Set CommandType to ctQuery and set CommandText to an SQL statement you want to execute on the server.
• Set CommandType to ctStoredProc and set CommandText to the name of the stored procedure you want to execute.
• Set CommandType to ctTable and set CommandText to the name of the database tables whose records you want to use.
6. If the stored procedure returns a cursor to be used with visual data controls, add a data source component to the form.
7. Set the DataSet property of the data source component to the TSimpleDataSet object.
8. To activate the dataset, use the Active property or call the Open method.
9. If you executed a stored procedure, use the Params property to retrieve any output parameters.
See Also
dbExpress Components ( see page 16)

Configuring TSQLConnection ( see page 53)

Specifying Display Data ( see page 58)

Fetching the Data ( see page 57)

Executing the Commands ( see page 56)

Accessing Schema Information ( see page 51)

Using TSQLTable ( see page 66)

Using TSQLStoredProc ( see page 66)

Using TSQLQuery ( see page 65)

Using Unidirectional Datasets ( see page 1823)

68
2.2 Database Procedures RAD Studio Using TStoredProc

2.2.20 Using TSimpleObjectBroker


If you have multiple COM-based servers that your client application can choose from, you can use an Object Broker to locate an
available server system.

To use TSimpleObjectBroker
1. Choose File New Other. The New Items dialog appears.
2. In the New Items dialog, select Delphi Projects and double-click VCL Forms Application. The Windows Designer
displays.
3. From the DataSnap category of the Tool Palette, choose the connection component depending on the kind of connection you
want.
4. From the Tool Palette, drag a TSimpleObjectBroker to the form.
5. In the Object Inspector, set the ObjectBroker property of the connection component that you chose in Step 3 to use this
broker.
Warning: Do not use the ObjectBroker property with SOAP connections.
See Also
Using DataSnap ( see page 60)

Connecting To Application Server ( see page 55)

Using TLocalConnection or TConnectionBroker ( see page 59)


2

2.2.21 Using TStoredProc


TStoredProc is a stored procedure-type dataset that executes a stored procedure that is defined on a database server.

To use TStoredProc
1. Choose File New Other. The New Items dialog appears.
2. In the New Items dialog, select Delphi Projects and double-click VCL Forms Application. The Windows Designer
displays.
3. Associate a dataset with database and session connections.
4. Bind the parameters.

To associate a dataset with database and session connections


1. From the BDE category of the Tool Palette, drag a TDatabase component to the form.
2. To associate a BDE-enabled dataset with a database, set the DatabaseName property. For TDatabase component, database
name is the value of the DatabaseName property of the database component.
3. Drag a TSession component to the form.
4. To control all database connections in your application, use the default session.
5. In the Object Inspector, set the SessionName property of the TSession component to associate your dataset with an
explicitly created session component.
Note: If you use a session component, the SessionName property of a dataset must match the SessionName property for the

69
Using TTable (Procedure) RAD Studio 2.2 Database Procedures

database component with which the dataset is associated.

To bind parameters
1. From the BDE category of the Tool Palette, drag a TStoredProc component to the form.
2. Set the ParamBindMode property to default pbByName to specify how parameters should be bound to the parameters on the
server.
3. View the stored procedure source code of a server in the SQL Explorer if you want to set ParamBindMode to pbByNumber.
4. Determine the correct order and type of parameters.
5. Specify the correct parameter types in the correct order.
Note: Some servers also support binding parameters by ordinal value, the order in which the parameters appear in the stored
procedure. In this case the order in which you specify parameters in the parameter collection editor is significant. The first
parameter you specify is matched to the first input parameter on the server, the second parameter is matched to the second
input parameter on the server, and so on. If your server supports parameter binding by ordinal value, you can set
ParamBindMode to pbByNumber
.
See Also
BDE Overview ( see page 15)

Using TTable ( see page 70)

Using TQuery ( see page 63)

Using TBatchMove ( see page 61)

Using TUpdateSQL ( see page 72)


2

2.2.22 Using TTable (Procedure)


TTable is a table-type dataset that represents all of the rows and columns of a single database table.

To use TTable
1. Choose File New Other. The New Items dialog appears.
2. In the New Items dialog, select Delphi Projects and double-click VCL Forms Application. The Windows Designer
displays.
3. Associate the dataset with the database and session connections.
4. Specify the table type for local tables and control read/write access to local tables.
5. Specify a dBASE index file.
6. Rename local tables.
7. Import data from another table.

To associate a dataset with database and session connections


1. From the BDE category of the Tool Palette, drag a TDatabase component to the form.
2. Drag a TSession component to the form.
3. To associate a BDE-enabled dataset with a database, in the Object Inspector, set the DatabaseName property of the
TDatabase component . For a TDatabase component, the database name is the value of the DatabaseName property of the
database component.

70
2.2 Database Procedures RAD Studio Using TTable (Procedure)

4. Use the default session to control all database connections in your application.
5. Set the SessionName property of the TSession component to associate your dataset with an explicitly created session
component.
If you use a session component, the SessionName property of a dataset must match the SessionName property for the
database component with which the dataset is associated.

To specify the TableType and control read/write access


1. From the BDE category of the Tool Palette, drag a TTable component to the form.
2. In the Object Inspector, set the TableType property if an application accesses Paradox, dBASE, FoxPro, or comma-delimited
ASCII text tables. BDE uses the TableType property to determine the table’s type.
3. Set TableType to ttDefault if your local Paradox, dBASE, and ASCII text tables use the file extensions like, .DB, .DBF, and
.TXT.
4. For other extensions, set TableType to ttParadox for Paradox, ttDBase for dBASE, ttFoxPro for FoxPro, and ttASCII for
Comma-delimited ASCII text respectively.
5. Set the table component’s Exclusive property to True before opening the table to gain sole read/write access.
Note: If the table is already in use when you attempt to open it, exclusive access is not granted. You can attempt to set
Exclusive on SQL tables, but some servers do not support exclusive table-level locking. Others may grant an exclusive lock,
but permit other applications to read data from the table.

To specify a dBASE index file


1. Set the IndexFiles property to the name of the non-production index file or list the files with a .NDX extension.
2. Specify one index in the IndexName property to have it actively sorting the dataset.
3. At designtime, click the ellipsis button in the IndexFiles property. The Index Files editor opens. 2
4. To add a non-production index file or file with .NDX extension, click the Add button in the Index Files dialog and select the file
from the Open dialog.
Note: For each non-production index file or .NDX file, repeat Steps 3 and 4.

5. After adding all desired indexes, click the OK button in the Index Files editor.
Note: To do steps 3-5 at runtime, access the IndexFiles property using properties and methods of string lists.

To rename local tables


1. To rename a Paradox or dBASE table at design time, right-click the table component. A drop-down context menu opens.
2. From the context menu, select Rename Table.
3. To rename a Paradox or dBASE table at runtime, call the table’s RenameTable method.

To import data from another table


1. Use the BatchMove method of a table component to import data, copy, update, append records from another table into this
table, or delete records from a table.
2. Set the name of the table from which to import data, and a mode specification that determines which import operation to
perform.
See Also
BDE Overview ( see page 15)

Using TDatabase ( see page 62)

Using TSession ( see page 67)

71
Using dbExpress RAD Studio 2.2 Database Procedures

Using TQuery ( see page 63)

Using TStoredProc ( see page 69)

Using TBatchMove ( see page 61)

Using TUpdateSQL ( see page 72)

2.2.23 Using TUpdateSQL to Update a Dataset


When the BDE-enabled dataset represents a stored procedure or a query that is not “live”, it is not possible to apply updates
directly from the dataset. Such datasets may also cause a problem when you use a client dataset to cache updates.

To update a dataset using an update object


1. From the Tool Palette, add a TUpdateSQL component to the same form as the BDE-enabled dataset.
2. In the Object Inspector, set the UpdateObject property of the BDE-enabled dataset component’s to the TUpdateSQL
component in the form.
3. Set the ModifySQL, InsertSQL, and DeleteSQL properties of the update object to specify the SQL statements needed to
perform updates.
4. Close the dataset.
5. Set the dataset component’s CachedUpdates property to True or link the dataset to the client dataset using a dataset
provider.
6. Reopen the dataset.
2 7. Create SQL statements for update components.
8. Use multiple update objects.
9. Execute the SQL statements.
See Also
Using Update Objects to Update a Dataset ( see page 1692)

Using TTable ( see page 70)

Using TQuery ( see page 63)

Using TStoredProc ( see page 69)

Using TBatchMove ( see page 61)

Using TSession ( see page 67)

2.2.24 Using dbExpress


To build a database applications using dbExpress
1. Connect to the database server and configure a TSQL connection.
2. Specify the data to display.
3. Fetch the data.
4. Execute the commands.

72
2.2 Database Procedures RAD Studio Browsing a Database in the Data Explorer

5. Access the schema information.


6. Debug dbExpress application using TSQLMonitor.
7. Use TSQLTable to represent a table on a database server that is accessed via TSQLConnection.
8. Use TSQLQuery to execute an SQL command on a database server that is accessed via TSQLConnection.
9. Use TSQLStoredProc to execute a stored procedure on a database server that is accessed via TSQLConnection.
See Also
dbExpress Components ( see page 16)

Configuring TSQLConnection ( see page 53)

Specifying Display Data ( see page 58)

Fetching the Data ( see page 57)

Executing the Commands ( see page 56)

Accessing Schema Information ( see page 51)

Debugging dbExpress Applications ( see page 55)

Using TSQLTable ( see page 66)

Using TSQLStoredProc ( see page 66)

Using TSQLQuery ( see page 65)

Using TSimpleDataSet ( see page 68)

Using dbExpress Datasets ( see page 1823)


2

2.2.25 Adding a New Connection to the Data Explorer


You can add new connections to the Data Explorer, which persist as long as the connection object exists.

To add a new connection


1. Choose View Data Explorer. This displays the Data Explorer.
2. Select a provider from the tree list.
3. Right-click to display a pop-up menu.
4. Choose Add New Connection. This displays the Add New Connection dialog.
5. Enter the name of the new connection.
6. Click OK.

To modify connection settings


1. Right-click your connection and scroll down to modify a connection. A Modify Connection dialog appears.
2. Enter your connection settings and click OK.
See Also
Browsing a Database ( see page 74)

Executing SQL in the Data Explorer ( see page 74)

Modifying Connections ( see page 75)

73
Executing SQL in the Data Explorer RAD Studio 2.2 Database Procedures

2.2.26 Browsing a Database in the Data Explorer


Once you have a live connection, you can use the Data Explorer to browse database objects.

To browse database objects


1. Choose View Data Explorer.
2. Expand a provider node to expose the list of available connections.
3. Expand a connection node to view the list of database objects (tables, views, and procedures).
Note: If you receive an error because your connection is not live, you should refresh your provider, and/or modify your
connection.

To retrieve data from the database


1. Expand a connection in the Data Explorer.
2. Double-click a table name or view name to retrieve data. This operation returns a result set into a tabbed Data Explorer page
in the Code Editor.
Tip: You can also select a table in the Data Explorer
and right-click to display a pop-up menu with a Retrieve Data From Table command.

To run a stored procedure


2 1. Choose View Data Explorer.
2. Expand a connection in the Data Explorer and locate a stored procedure.
3. Double-click the stored procedure to view its parameters. The parameters open in a separate page on the design surface.
4. Edit input parameters as necessary.
5. Click the Execute button in the top left corner of the page to execute the procedure. The result set appears in a datagrid.
Tip: You can also select a procedure in the Data Explorer
and right-click to display a pop-up menu with an Execute command.
See Also
Adding a New Connection ( see page 73)

Executing SQL in the Data Explorer ( see page 74)

Modifying Connections ( see page 75)

2.2.27 Executing SQL in the Data Explorer


You can write, edit, and execute SQL in an SQL Window, which is available from within the Data Explorer.

To open a SQL Window


1. Choose View Data Explorer.
2. Select a connection.

74
2.2 Database Procedures RAD Studio Modifying Connections in the Data Explorer

3. Right-click the connection and choose SQL Window. This opens a tabbed SQL Window in the Code Editor.

To execute SQL
1. Enter a valid SQL statement or stored procedure name in the multi-line text box at the top of the SQL Window.
2. Click Execute SQL. If the SQL statement or stored procedure is valid, the result set appears in the bottom pane of the SQL
Window.
Note: The SQL statement or stored procedure must operate against the current connection and its target database. You
cannot execute SQL against a database to which you are not connected.

3. Click Clear All SQL to clear the SQL statement or stored procedure from the multi-line text box.
See Also
Browsing a Database ( see page 74)

Adding a New Connection ( see page 73)

Modifying Connections ( see page 75)

2.2.28 Modifying Connections in the Data Explorer


You can modify connections in a variety of ways from the Data Explorer.

To modify connections
1. Choose View Data Explorer. 2
2. Select a provider.
3. Right-click to display a pop-up menu to view your options.

To refresh a connection
1. Choose View Data Explorer.
2. Select a provider.
3. Right-click to display a pop-up menu.
4. Choose Refresh. This operation reinitializes all connections defined for the selected provider.

To delete a connection
1. Choose View Data Explorer.
2. Select a connection.
3. Right-click to display a pop-up menu.
4. Choose Delete Connection. This displays a confirmation message that asks if you want to delete the connection.
5. Click OK.

To modify a connection
1. Choose View Data Explorer.
2. Select a connection.
3. Right-click to display a pop-up menu.
4. Choose Modify Connection. This displays the Connections Editor dialog.

75
Connecting to a Database using the RAD Studio 2.2 Database Procedures

5. Make changes to the appropriate values in the editor.


6. Click OK.

To close a connection
1. Choose View Data Explorer.
2. Select a connection.
3. Right-click to display a pop-up menu.
4. Choose Close Connection. If the connection is open, this operation closes it.
Note: If the Close Connection
command is disabled in the menu, the connection is not open.

To rename a connection
1. Choose View Data Explorer.
2. Select a connection.
3. Right-click to display a pop-up menu.
4. Choose Rename Connection. This displays Rename Connection dialog.
5. Enter a new name.
6. Click OK. The Data Explorer displays the connection with its new name.
See Also
Browsing a Database ( see page 74)

2 Executing SQL in the Data Explorer ( see page 74)

Adding a New Connection ( see page 73)

2.2.29 Connecting to a Database using the dbExpress Driver


Framework
This procedure tells how to use the dbExpress driver framework to connect to a database and read its records. In the sample
code, the dbExpress ini files contain all the information about the particular database connection, such as driver, user name,
password, and so on.

To connect to a database and read its records


1. Configure the connections ini file with the information about the database you are connecting to. This includes setting the
driver name, user name, password, and so on.
2. Obtain a TDBXConnectionFactory, which is returned by TDBXConnectionFactory.GetConnectionFactory.
3. Get a TDBXConnectionobject returned by TDBXConnectionFactory.GetConnection.
4. Open the database connection by calling TDBXConnection.Open on the TDBXConnection instance.
5. Get a TDBXCommandobject by calling TDBXConnection.CreateCommand on the TDBXConnection instance.
6. Set the TDBXCommand's Textproperty to the desired SQL command. Call TDBXCommand.Prepare on the TDBXCommand
instance.
7. Execute the SQL query by calling TDBXCommand.ExecuteQuery, which returns a TDBXReader instance.
8. Read the first database record by calling TDBXReader.Next. Call this method to retrieve successive database records.

76
2.2 Database Procedures RAD Studio Connecting to a Database using the

9. Get whatever information you want from the database. For instance, TDBXReader.GetColumnCount returns the number of
database columns. The TDBXReader properties ValueTypeand Value contain the data type and value for a given column
number in the current record.
// This sample connects to a database using the ini files.
// These files must be configured for the database.
// Once connected, the sample reads values and displays the
// ANSI values for the first 100 records in a listbox.

// Get a TDBXConnection using a TDBXConnectionFactory.


// ConnectionName = section in the connections ini file.
class function TForm1.BuildConnectionFromConnectionName(
ConnectionName: WideString): TDBXConnection;
var
ConnectionFactory: TDBXConnectionFactory;
ConnectionProps: TDBXProperties;
begin
ConnectionFactory := TDBXConnectionFactory.GetConnectionFactory;
ConnectionProps := ConnectionFactory.GetConnectionProperties(ConnectionName);
Result := ConnectionFactory.GetConnection(ConnectionProps,
ConnectionProps.Values[TDBXPropertyNames.UserName],
ConnectionProps.Values[TDBXPropertyNames.Password] );
end;

procedure Connect;
var
connection: TDBXConnection;
command: TDBXCommand;
reader: TDBXReader;
value: TDBXValue;
valueType: TDBXValueType;
colCountStr: string;
i, j: Integer; 2
numCols: integer;
ListBox1: TListBox;

const
sqlCommand = 'select * from employee';

begin
// Open connection to DB.
connection := BuildConnectionFromConnectionName('ConnectionName');
connection.Open;

// Get command
command := connection.CreateCommand();
command.Text := sqlCommand;

// Execute query
command.Prepare;
reader := command.ExecuteQuery;

// Get values from DB


if reader.Next then
begin
numCols := reader.GetColumnCount;
Str(numCols, colCountStr);
ListBox1.Items.Add('Number of columns = ' + colCountStr);
j := 1;
repeat
for i := 0 to reader.GetColumnCount - 1 do
begin
valueType := reader.ValueType[i];
if valueType.DataType = TDBXDataTypes.AnsiStringType then

77
Connecting to a Database using the RAD Studio 2.2 Database Procedures

begin
value := reader.Value[i];
ListBox1.Items.Add(valueType.Name + ' = ' +
value.GetString);
end
else
ListBox1.Items.Add(valueType.Name);
end;
Inc(j);
until (j > 100) or not reader.Next;

reader.Next;
end;

// Free resources
command.Free;
end;

78
2.3 Interoperable Applications Procedures RAD Studio Using COM Wizards

2.3 Interoperable Applications Procedures


Delphi provides wizards and classes to make it easy to implement applications based on the Component Object Model (COM)
from Microsoft. The simplest COM objects are servers that expose properties and methods (and possibly events) through a
default interface that clients can call. The COM Object Wizard builds a lightweight COM object whose default interface
descends from IUnknown or that implements an interface already registered on your system. This wizard provides the most
flexibility in the types of COM objects you can create.

Topics
Name Description
Using COM Wizards ( see page 79) RAD Studio provides wizards that help you create COM projects and COM
objects. These wizards are available for both Delphi and C++ projects. The
following COM wizards are available in the list for
File New Other <personality> ActiveX:

• Active Form
• Active Server Object
• ActiveX Control
• ActiveX Library
• Automation Object
• COM Object
• COM+ Event Object
2
• COM+ Subscription Object
• Property Page
• Transactional Object
• Type Library
Two other related wizards are available from the
File New Other <personality> Multitier list:
• Remote Data Module
• Transactional Data Module

2.3.1 Using COM Wizards


RAD Studio provides wizards that help you create COM projects and COM objects. These wizards are available for both Delphi
and C++ projects. The following COM wizards are available in the list for File New Other <personality> ActiveX:

• Active Form
• Active Server Object
• ActiveX Control
• ActiveX Library
• Automation Object
• COM Object

79
Using COM Wizards RAD Studio 2.3 Interoperable Applications Procedures

• COM+ Event Object


• COM+ Subscription Object
• Property Page
• Transactional Object
• Type Library
Two other related wizards are available from the File New Other <personality> Multitier list:
• Remote Data Module
• Transactional Data Module

To use a COM wizard


1. Choose File New Other. The New Items dialog box displays.
2. In the Item Categories tree, click the ActiveX folder beneath your chosen personality, either C++Builder Projects or Delphi
Projects.
3. In the ActiveX folder, double-click ActiveX Library. This creates a Dynamic Link Library [DLL] project that you can use to
host in-process ActiveX Objects.
4. Choose File New Other again.
5. Do either one of the following:
• To display the COM wizards, click the same ActiveX folder that you clicked in step 2.
• To display the multitier wizards, click the Multitier folder in your selected personality.
6. Double-click the wizard that you want to use.
Note: To create a client application to interact with the server created by a COM wizard, use the Import Component wizard or
2 the TLIBIMP utility.
If your application implements more than one COM object, you should specify the same instancing for all of them.
See Also
Overview of COM Technologies ( see page 1385)

80
2.4 Reporting Procedures RAD Studio Adding Rave Reports to RAD Studio

2.4 Reporting Procedures


This topic provides how-to information on using reporting solutions.

Topics
Name Description
Adding Rave Reports to RAD Studio ( see page 81) Rave Reports offers a powerful set of tools for building reports and including
them in your applications. Rave Reports are installed in a \RaveReports
subdirectory in your installation directory. To make the Rave Reports more easily
accessible, add the command executable to your Tools menu.

2.4.1 Adding Rave Reports to RAD Studio


Rave Reports offers a powerful set of tools for building reports and including them in your applications. Rave Reports are
installed in a \RaveReports subdirectory in your installation directory. To make the Rave Reports more easily accessible, add
the command executable to your Tools menu.

To add a Rave Reports command to the Tools menu


1. Choose Tools Configure Tools. This displays the Tool Options dialog box.
2. Click Add. This displays the Tool Properties dialog box.
2
3. Type Rave Reports in the Title text box.
4. Click the Browse button.
5. Browse to the \RaveReports subdirectory in your RAD Studio installation directory.
6. Select the Rave.exe icon.
7. Click OK. This adds the path for the program and the working directory to the Tool Properties dialog box.
8. Click OK
9. Click Close. This adds the command to your Tools menu that will initiate a Rave Reports session. Refer to the Rave Reports
online Help for information on how to build and integrate report objects.
See Also
Rave Reports Overview ( see page 35)

81
RAD Studio 2.5 VCL Procedures

2.5 VCL Procedures


This section provides how-to information on developing VCL for Win32 applications.

Topics
Name Description
Building a Windows "Hello World" Console Application ( see page 88) This "Hello World" console application demonstrates the essential steps for
creating a Windows application in Delphi or C++. The application uses Windows,
a console window, an event, and will display a dialog in response to a user action.
Developing a Windows Application ( see page 89) The following procedure illustrates the essential steps for building a Windows
application.
Building Application Menus ( see page 90) Menus provide an easy way for your users to execute logically grouped
commands. You can add or delete menu items, or drag them to rearrange them
during designtime. In addition to TMainMenu and TPopupMenu components,
the Tool Palette also contains TActionMainMenuBar, TActionManager, and
TActionToolBar.
Building a VCL Forms Application with Decision Support Components ( see Creating a form with tables and graphs of multidimensional data consists of the
page 91) following major steps:

1. Create a VCL form.


2. Add a decision query and dataset.
3. Add a decision cube.
4. Add a decision source.
5. Optionally add a decision pivot.
2 6. Add one or more decision grids and graphs.
7. Set the active property of the decision query (or alternate
dataset component) to True.
Building VCL Forms Applications With Graphics ( see page 93) Each of the procedures listed below builds a VCL Form application that uses
graphics. Build one or more of the examples and then add other graphics
features to these basic VCL Form applications.

1. Draw straight lines.


2. Draw rectangles and ellipses.
3. Draw a polygon.
4. Display a bitmap image.
5. Place a bitmap in a combo box.
Building a VCL Forms MDI Application Using a Wizard ( see page 93) The VCL Forms MDI application wizard automatically creates a project that
includes the basic files for an MDI application. In addition to the Main source file,
the wizard creates unit files for child and about box windows, along with the
supporting forms files and resources.
Building a VCL Forms MDI Application Without Using a Wizard ( see page 94)
Building a VCL Forms SDI Application ( see page 96)
Creating a New VCL Component ( see page 97) You can use the New VCL Component wizard to create a new VCL component
for your application. The wizard detects the personality of the product you are
using and creates the appropriate type of component.

82
2.5 VCL Procedures RAD Studio

Building a VCL Forms ADO Database Application ( see page 98) The following procedure describes how to build an ADO database application.
Building a VCL ADO application consists of the following major steps:

1. Set up the database connection.


2. Set up the dataset.
3. Set up the data provider, client dataset, and data source.
4. Connect a DataGrid to the connection components.
5. Run the application.
Building a VCL Forms Application ( see page 99) The following procedure illustrates the essential steps to building a VCL Forms
application using RAD Studio.
Creating Actions in a VCL Forms Application ( see page 100) Using RAD Studio, the following procedure illustrates how to create actions using
the ActionList tool. It sets up a simple application and describes how to create a
file menu item with a file open action.
Building the VCL application with ActionList actions consists of the following
major steps:

1. Create a main window and add tools for creating a main


menu and a File open action.
2. Add the File category to the main menu.
3. Add the File open action to the File category.
4. Build and run the application.
Building a VCL Forms "Hello World" Application ( see page 101) This procedure demonstrates how to construct a simple “Hello world” VCL Forms
application using either Delphi or C++. Though simple, the Windows Forms
"Hello world" application demonstrates the essential steps for creating a VCL
Forms application. The application uses a VCL Form, a control, an event, and
displays a dialog in response to a user action.
Creating the "Hello world" application consists of the following steps:

1. Create a VCL Form with a button control. 2


2. Write the code to display "Hello world" when the button is
clicked.
3. Run the application.
Using ActionManager to Create Actions in a VCL Forms Application ( see page Using RAD Studio, the following procedure illustrates how to create actions using
102) ActionManager. It sets up a simple user interface with a text area, as would be
appropriate for a text editing application, and describes how to create a file menu
item with a file open action.
Building the VCL application with ActionManager actions consists of the following
major steps:

1. Create a main window.


2. Add a File open action to the ActionManager.
3. Create the main menu.
4. Add the action to the menu.
5. Build and run the application.
Building a VCL Forms dbExpress Database Application ( see page 103) The following procedure describes how to build a dbExpress database
application.
Building a VCL Forms dbExpress application consists of the following major
steps:

1. Set up the database connection.


2. Set up the unidirectional dataset.
3. Set up the data provider, client dataset, and data source.
4. Connect a DataGrid to the connection components.
5. Run the application.

83
RAD Studio 2.5 VCL Procedures

Building an Application with XML Components ( see page 104) This example creates a VCL Forms application that uses an XMLDocument
component to display contents in an XML file.
Copying Data From One Stream To Another ( see page 106) Creating this VCL application consists of the following steps:

1. Create a project directory containing a text file to copy.


2. Create a VCL Form with a button control.
3. Write the code to read the string and write it to a file.
4. Run the application.
Copying a Complete String List (VCL) ( see page 107) Copying a string list can have the effect of appending to or overwriting an existing
string list. This VCL application appends to a string list. With a simple change, it
can overwrite a string list. Creating this VCL application consists of the following
steps:

1. Create a VCL Form with TButtons, TComboBox, and


TMemo controls.
2. Write the code to create a string list to the Button1
OnClick handler.
3. Write the code to copy the string list to the Button2
OnClick handler.
4. Run the application.
Creating Strings ( see page 109) Creating this VCL application consists of the following steps:

1. Create a VCL Form with TButton and TComboBox


controls.
2. Write the code to create strings to the TButton OnClick
handler.

2 3. Run the application.


Creating a VCL Form Instance Using a Local Variable ( see page 110) A safe way to create a unique instance of a modal VCL form is to use a local
variable in an event handler as a reference to a new instance. If you use a local
variable, it doesn't matter whether the form is auto-created or not. The code in
the event handler makes no reference to the global form variable. Using RAD
Studio, the following procedure creates a modal form instance dynamically. It
(optionally) removes the second form's invocation at startup.
Building this VCL application consists of the following steps:

1. Create the project directory.


2. Create two forms for the project.... more ( see page 110)
Deleting Strings ( see page 112) Creating this VCL application consists of the following steps:

1. Create a VCL Form with Buttons and ListBox controls.


2. Write the code to add strings to a list.
3. Write the code to delete a string from the list.
4. Run the application.
Displaying an Auto-Created VCL Form ( see page 113) Using RAD Studio, the following procedure creates a modal form at design time
that is displayed later during program execution.
Building this VCL application consists of the following steps:

1. Create the project directory.


2. Create two forms for the project.
3. Link the forms.
4. Create a control on the main form to display the modal
form; then write the event handler.
5. Build and run the application.

84
2.5 VCL Procedures RAD Studio

Displaying a Bitmap Image in a VCL Forms Application ( see page 114) This procedure loads a bitmap image from a file and displays it to a VCL form.

1. Create a VCL form with a button control.


2. Provide a bitmap image.
3. Code the button's onClick event handler to load and
display a bitmap image.
4. Build and run the application.
Displaying a Full View Bitmap Image in a VCL Forms Application ( see page This procedure loads a bitmap image from a file and displays it in its entirety to a
116) VCL form. The procedure uses the Height and Width properties of the Bitmap
object to display a full view of the image.

1. Create a VCL form with a button control.


2. Provide a bitmap image.
3. Code the button's onClick event handler to load and
display a bitmap image.
4. Build and run the application.
Drawing a Polygon in a VCL Forms Application ( see page 117) This procedure draws a polygon in a VCL form.

1. Create a VCL form.


2. Code the form's OnPaint event handler to draw a polygon.
3. Build and run the application.
Drawing Rectangles and Ellipses in a VCL Forms Application ( see page 118) This procedure draws a rectangle and ellipse in a VCL form.

1. Create a VCL form.


2. Code the form's OnPaint event handler to draw a
rectangle and ellipse.
2
3. Build and run the application.
Drawing a Rounded Rectangle in a VCL Forms Application ( see page 118) This procedure draws a rounded rectangle in a VCL form.

1. Create a VCL form and code the form's OnPaint event


handler.
2. Build and run the application.
Drawing Straight Lines In a VCL Forms Application ( see page 119) This procedure draws two diagonal straight lines on an image in a VCL form.

1. Create a VCL form.


2. Code the form's OnPaint event handler to draw the
straight lines.
3. Build and run the application.
Dynamically Creating a VCL Modal Form ( see page 120) You may not want all your VCL application's forms in memory at once. To reduce
the amount of memory required at load time, your application can create forms
only when it needs to make them available for use. A dialog box, for example,
needs to be in memory only during the time the user interacts with it. Using RAD
Studio, the following procedure creates a modal form dynamically. The main
difference between dynamically creating a form and displaying an auto-created
VCL form is that you remove the second form's invocation at startup and write
code to dynamically create the form.... more ( see page 120)

85
RAD Studio 2.5 VCL Procedures

Dynamically Creating a VCL Modeless Form ( see page 121) A modless form is a window that is displayed until it is either obscured by another
window or until it is closed or minimuzed by the user. Using RAD Studio, the
following procedure creates a modeless form dynamically.
Building this VCL application consists of the following steps:

1. Create the project directory.


2. Create two forms for the project.
3. Remove the second form's invocation at startup.
4. Link the forms.
5. Create a control on the main form to create and display
the modal form; then write the event handler.
6. Build and run the application.
Iterating Through Strings in a List ( see page 123) This VCL application first creates a list of strings. Then it iterates through the
strings, changing all string characters to uppercase. It consists of the following
steps:

1. Create a VCL Form with Buttons and TListBox controls.


2. Write the code to create a string list and add strings to it.
3. Write the code to iterate through the string list to process
string characters.
4. Run the application.
Building a Multithreaded Application ( see page 124) These are the essential steps to building a VCL Forms multithreaded application
with a thread object using RAD Studio.
Writing Cleanup Code ( see page 125)
Avoiding Simultaneous Thread Access to the Same Memory ( see page 125) Use these basic techniques to prevent other threads from accessing the same
memory as your thread:
2 1. Lock objects.
2. Use critical sections.
3. Use a multi-read exclusive-write synchronizer
Defining the Thread Object ( see page 126)
Handling Exceptions ( see page 129)
Initializing a Thread ( see page 130)
Using the Main VCL Thread ( see page 131) Using the main VCL thread consists of the following basic steps:

1. Create a separate routine to handle Windows messages


received by components in your application.
2. Call CheckSynchronize periodically.
3. Declare thread-local variables, as necessary, for exclusive
use by your thread.
Waiting for Threads ( see page 132) The following are procedures that can be used to wait for threads.

• Wait for a thread to finish executing.


• Wait for a task to complete.
• Check if another thread is waiting for your thread to
terminate.
Writing the Thread Function (Procedure) ( see page 134) The Execute method is your thread function. You can think of it as a program that
is launched by your application, except that it shares the same process space.
Writing the thread function is a little trickier than writing a separate program,
because you must make sure that you do not overwrite memory that is used by
other processes in your application. On the other hand, because the thread
shares the same process space with other threads, you can use the shared
memory to communicate between threads.

86
2.5 VCL Procedures RAD Studio

Placing A Bitmap Image in a Control in a VCL Forms Application ( see page This procedure adds a bitmap image to a combo box in a VCL forms application.
135)
1. Create a VCL form.
2. Place components on the form.
3. Set component properties in the Object Inspector.
4. Write event handlers for the component's drawing action.
5. Build and run the application.
Reading a String and Writing It To a File ( see page 136) Creating this VCL application consists of the following steps:

1. Create a VCL Form with a button control.


2. Write the code to read the string and write it to a file.
3. Run the application.
Renaming Files ( see page 137) Creating this VCL application consists of the following steps:

1. Create a project directory containing a file to rename.


2. Create a VCL Form with button and label controls.
3. Write the code to rename the file.
4. Run the application.
Adding and Sorting Strings ( see page 138) Creating this VCL application consists of the following steps:

1. Create a VCL Form with Button, Label, and TListBox


controls.
2. Write the code to add and sort strings.
3. Run the application.
Creating a VCL Forms ActiveX Button ( see page 139) Like a Delphi control, an ActiveX control generates program code when you
2
place the component on a form or other logical container in the IDE. The main
difference between an ActiveX control and a Delphi control is that an ActiveX
control is language independent. You can create ActiveX controls for deployment
to a variety of programming environments on Windows, not just Delphi or
C++Builder.
This procedure uses the VCL forms ActiveX wizard to create an ActiveX control.
To test the control, you can install it on your machine as a VCL component in the
IDE. To install the control, you... more ( see page 139)
Creating a VCL Forms ActiveX Active Form ( see page 140) Like a Delphi control, an ActiveX control generates program code when you
place the component on a form or other logical container in the IDE. The main
difference between an ActiveX control and a Delphi control is that an ActiveX
control is language independent. You can create ActiveX controls for deployment
to a variety of programming environments on Windows, not just Delphi or
C++Builder, for example.
This procedure uses the VCL forms ActiveX Active Form wizard to create an
Active Form containing two components. To test the control, you can deploy it to
the Web. This procedure consists of the... more ( see page 140)
Building a VCL Forms Web Browser Application ( see page 142) Creating the Web browser application consists of the following steps:

1. Create a VCL Form with a button control.


2. Add a TWebBrowser component to the form.
3. Add controls to enter a URL and launch the browser.
4. Write the code to launch the browser when a button is
clicked.
5. Run the application.

87
Building a Windows "Hello World" Console RAD Studio 2.5 VCL Procedures

Creating an Application that Uses Ribbon Controls ( see page 143) This procedure describes how to create an application that uses ribbon controls.
The core ribbon functionality is derived from the TRibbon component. While the
ribbon uses other components, none of the core components are registered on
the tool palette.
Components:

1. TRibbon: Main visual component that provides most


functionality.
2. TRibbonApplicationMenuBar: Component that provides
the functionality of the application menu.
3. TRibbonQuickAccessToolbar: Component that provides
the functionality of the Quick Access Toolbar
4. TRibbonPage: Component that represents the page of
the ribbon that is currently visible
5. TRibbonGroup: Component that all of the pages
commands are displayed in. Commands must be placed
in a group.... more ( see page 143)
Adding Commands to the Ribbon ( see page 144) This topic follows in sequence the creation of a ribbon application using either the
Ribbon Application Wizard or the manual steps described in Creating an
Application that Uses Ribbon Controls ( see page 143).
This topic assumes that you are familiar with the TActionManager component
and the components associated with its use. Numerous new properties have
been added to help support the ribbon requirements. Many existing properties
have no effect when modified on a command that is displayed on the ribbon.
For instance:

• Small buttons always display their glyph to the left of the


caption.
• Large buttons always display their glyph at... more ( see
2 page 144)

2.5.1 Building a Windows "Hello World" Console Application


This "Hello World" console application demonstrates the essential steps for creating a Windows application in Delphi or C++. The
application uses Windows, a console window, an event, and will display a dialog in response to a user action.

To create the "Hello world" console application


1. Create a Windows console application.
2. Create the logic.
3. Run the application.

To create a Windows console application


1. Choose File New Other.... The New Items dialog box appears.
2. In the New Items dialog box, select either Delphi Projects or C++Builder Projects and then double-click Console
Application.
3. For C++, in the New Console Application dialog box, make sure that VCL Forms and Multi-threaded are unchecked, and
Console application is checked. Then click OK.

To associate code with the console window


1. In the code template that is displayed in the Code Editor: For Delphi, enter the following statements after the try keyword and
before the except keyword:

88
2.5 VCL Procedures RAD Studio Building Application Menus

WriteLn('Hello, World!');

ReadLn;
For C++, enter the following after #pragma hdrstop:
#include <iostream>
2. For C++, enter the following code after the opening brace ({):
std::cout<<”Hello, World!”<<std::endl;
std::cin.ignore();
3. Save the application.

To run the "Hello World" application


1. Choose Run Run. The application compiles and displays a console window with your "Hello World" message.
2. Press the ENTER key. The console window closes when the program terminates.
See Also
Windows Overview ( see page 45)

Building a Windows Application ( see page 89)

Building Applications Menus ( see page 90)

2.5.2 Developing a Windows Application


The following procedure illustrates the essential steps for building a Windows application. 2

To create a Windows project


1. Select New VCL Forms Application — Delphi for Win32. The Windows Designer displays.
2. If necessary, select Design view.
3. From the Tool Palette, drag components onto the designer to create the user interface.
4. Associate logic with the controls.

To associate code with a control


1. In the Designer, double-click the component to which you want to apply logic. The Code Editor appears, cursor in place
between the reserved words begin and end in the event handler.
2. Code your application logic.
3. Save and compile the application.
See Also
Windows Overview ( see page 45)

Building a Windows "Hello World" Application ( see page 88)

Building Windows Application Menus ( see page 90)

89
Building Application Menus RAD Studio 2.5 VCL Procedures

2.5.3 Building Application Menus


Menus provide an easy way for your users to execute logically grouped commands. You can add or delete menu items, or drag
them to rearrange them during designtime. In addition to TMainMenu and TPopupMenu components, the Tool Palette also
contains TActionMainMenuBar, TActionManager, and TActionToolBar.

To create application menus


1. Choose File New Other. The New Items dialog appears.
2. In the New Items dialog, select VCL Forms Application. The Windows Designer displays.
3. Build application menus.
4. Use the Menu Designer.
5. Create an event handler for each menu item.
6. Move menu items.
7. Add images to menu items.

To build application menus


1. From the Standard category of the Tool Palette, add TMainMenu or TPopupMenu component to your form. A visual
representation of the menu appears on the designer.
Note: A TMainMenu
component creates a menu that is attached to the title bar of the form. A TPopupMenu component creates a menu that
2 appears when the user right-clicks in the form.
2. To view the menu, if the form is visible, click the form. The menu appears in the form exactly as it will when you run the
program.
3. To delete a menu item, select the menu item you want to delete. Press Delete.
4. To edit menu items, select the VCL form, select the menu item you want to edit, and edit its properties.
5. To make the menu item a separator bar, place the cursor on the menu where you want a separator to appear and enter a
hyphen (-) for the caption or press the hyphen (-) key.
6. To specify a keyboard shortcut for a menu item, in the Object Inspector, set the ShortCut property.

To use the Menu Designer


1. Select a menu component on the form.
2. Double-click the menu component. The Menu Designer window opens.
Note: You can also open the Menu Designer
by clicking the ellipsis(...) button next to the Items property in the Object Inspector.
3. To name a menu component, in the Object Inspector, set the Caption property.
Tip: Delphi derives the Name property from the caption, for e.g. if you give a menu item a Caption property value of File,
Delphi assigns the menu item a Name property of File1. However, if you fill in the Name property before filling in the Caption
property, Delphi leaves the Caption property blank until you type a value.

4. Right-click anywhere on the Menu Designer to use the Menu Designer context menu. A drop-down list opens. This is the
Menu Designer context menu.
5. To insert a placeholder below or to the right of the cursor, choose Insert from the context menu.

90
2.5 VCL Procedures RAD Studio Building a VCL Forms Application with

6. To delete the selected menu item (and all its subitems, if any), click Delete from the context menu.
7. To switch among menus in a form, choose Select Menu from the context menu. The Select Menu dialog box appears. It lists
all the menus associated with the form whose menu is currently open in the Menu designer.
8. From the list in the Select Menu dialog box, choose the menu you want to view or edit.

To create an event handler for a menu item


1. In the designer, double-click the menu item to which you wish to add an event handler. The Code Designer appears, cursor
in place between event handler brackets.
2. Code your menu item logic.
3. Save and compile the application.

To move menu items


1. To move a menu item along the desired menu bar, drag the item until the arrow tip of the cursor points to the new location.
2. Release the mouse button.
3. To move a menu item into a menu list, drag the item until the arrow tip of the cursor points to the new menu.
4. Release the mouse button.

To add images to menu items


1. From the Tool Palette, drag a TMainMenu or TPopupMenu component to a form.
2. From the Tool Palette, drop a TImageList component to the form.
3. Double-click on the TImageList component. The ImageList editor opens.
4. Click Add to select the bitmap or bitmap group you want to use in the menu.
5. Select the bitmap that you want and click OK. 2
6. In the Object Inspector, set the Images property of the TMainMenu or TPopupMenu component to the image you selected
in the ImageList editor.
See Also
Windows Overview ( see page 45)

Building a Windows Application ( see page 89)

2.5.4 Building a VCL Forms Application with Decision


Support Components
Creating a form with tables and graphs of multidimensional data consists of the following major steps:

1. Create a VCL form.


2. Add a decision query and dataset.
3. Add a decision cube.
4. Add a decision source.
5. Optionally add a decision pivot.
6. Add one or more decision grids and graphs.
7. Set the active property of the decision query (or alternate dataset component) to True.

91
Building a VCL Forms Application with RAD Studio 2.5 VCL Procedures

To create a VCL form


1. Choose File New Other Delphi Projects and double-click the VCL Forms Application icon. The VCL Forms Designer
displays.
2. If necessary, click Form1 to make it the active window.

To add a decision dataset


1. From the Decision Cube page on the Tool Palette, add a DecisionQuery component to the top of the form.
Tip: Place non-visual components such as this one in the top left corner of the form to keep them out of the way of visual
components you will be adding.

2. Right-click the DecisionQuery component, and select Decision Query Editor.... The Decision Query Editor displays.
3. On the Dimensions/Summary tab, select the BCDEMOS database from the Database: drop-down list.
4. From the Table: drop-down, select the parts.db table. The List of Available Fields: listbox displays the fields in the parts.db
table.
5. Use CTRL+Click to select the PartNo, OnOrder, and Cost fields; then click the right-arrow button next to the Dimensions:
listbox. PartNo, OnOrder, and Cost display in the listbox.
6. Select the OnOrder field; then click the right-arrow button next to the Summaries: listbox and select count from the pop-up
that displays. COUNT(OnOrder) displays in the Summaries: listbox.
7. Select the Cost field in the List of Available Fields: listbox; then click the right-arrow button next to the Summaries: listbox
and select sum from the pop-up that displays. SUM(Cost) displays in the Summaries: listbox.
8. Click OK to close the Decision Query Editor.
2 Note: When you use the Decision Query Editor, the query is initially handled in ANSI-92 SQL syntax and then translated (if
necessary) into the dialect used by the server. The Decision Query editor reads and displays only ANSI standard SQL. The
dialect translation is automatically assigned to the TDecisionQuery's SQL property. To modify a query, edit the ANSI-92
version in the Decision Query rather than the SQL property.

To add a decision cube


1. From the Decision Cube page on the Tool Palette, add a decision cube component to the top left corner of the form.
2. In the Object Inspector, select DecisionQuery1 from the drop-down list next to the decision cube's DataSet property.

To add a decision source


1. From the Decision Cube page on the Tool Palette, add a decision source component to the top left corner of the form.
2. In the Object Inspector, select DecisionCube1 from the drop-down list next to the decision source's DecisionCube property.

To add a decision pivot


1. From the Decision Cube page on the Tool Palette, add an optional DecisionPivot component to the top of the form.
Tip: The decision pivot displays in the final application window. Place it to the right of the nonvisual components.

2. In the Object Inspector, select DecisionSource1 from the drop-down list next to the decision pivot's DecisionSource property.

To create a decision grid


1. From the Decision Cube page on the Tool Palette, add a decision grid component to the form just beneath the decision
pivot.
2. In the Object Inspector, select DecisionSource1 from the drop-down list next to the decision grid's DecisionSource property.

92
2.5 VCL Procedures RAD Studio Building a VCL Forms MDI Application

To create a decision graph


1. From the Decision Cube page on the Tool Palette, add a decision graph component to the form just beneath the decision
grid.
2. In the Object Inspector, select DecisionSource1 from the drop-down list next to the decision graph's DecisionSource
property.

To run the application


1. In the Object Inspector, select True from the Active property drop-down. The visual decision graph, grid, and pivot
components display data.
2. Choose Run Run to run the application. The application runs and displays the decision support components.
3. Use the decision pivot to update, as desired, the data displayed in the grid and graph.
See Also
VCL Overview ( see page 36)

2.5.5 Building VCL Forms Applications With Graphics


Each of the procedures listed below builds a VCL Form application that uses graphics. Build one or more of the examples and
then add other graphics features to these basic VCL Form applications.

1. Draw straight lines.


2. Draw rectangles and ellipses.
2
3. Draw a polygon.
4. Display a bitmap image.
5. Place a bitmap in a combo box.
See Also
Overview of Graphics Programming ( see page 2176)

Drawing Straight Lines In a VCL Application ( see page 119)

Drawing Rectangles and Ellipses in a VCL Application ( see page 118)

Displaying a Bitmap Image in a VCL Application ( see page 114)

Placing A Bitmap Image In a Combo Box of a VCL Application ( see page 135)

2.5.6 Building a VCL Forms MDI Application Using a Wizard


The VCL Forms MDI application wizard automatically creates a project that includes the basic files for an MDI application. In
addition to the Main source file, the wizard creates unit files for child and about box windows, along with the supporting forms
files and resources.

To create a new MDI application using a wizard


1. Choose File New Other Delphi Projects and double-click the MDI Application icon. The Browse to Folder dialog box
is displayed.

93
Building a VCL Forms MDI Application RAD Studio 2.5 VCL Procedures

2. Navigate to the folder in which you want to store the files for the project.
3. Click OK.
4. Choose Run Run to compile and run the application.
5. Try commands that are automatically set up by the MDI Application wizard.
See Also
VCL Overview ( see page 36)

2.5.7 Building a VCL Forms MDI Application Without Using a


Wizard
The basic steps to create a new MDI application with a child window without using a wizard are
1. Create a main window form (MDI parent window).
2. Create a child window form.
3. Have the main window create the child window under user control.
4. Write the event handler code to close the child window.
5. Create the main menu and commands.
6. Add the event handlers for the commands.
7. Compile and run the application.
2
To create the main window form
1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.
2. In the Object Inspector, set the FormStyle property to fsMDIForm.
3. Enter a more descriptive name such as frMain for the Name property.
4. Save the unit file with a more descriptive name, such as uMain.pas (Delphi) or uMain.cpp (C++).

To create a child window


1. Choose File New Form
2. In the Object Inspector, set the FormStyle property to fsMDIChild.
3. Enter a more descriptive name such as frChild for the Name property.
4. Save the unit file as uChild.pas (Delphi) or uChild.cpp (C++).

To have the main window create the child window


1. Choose Project Options Forms. The Project Options dialog box appears.
2. Select frChild from Auto-create forms list and click [>] to move it to the Available forms list and click OK.
3. Select the frMain form to activate it; then switch to the Code view.
4. For Delphi, scroll to the uses section and add uChild to the list. For C++, add #include “uChild.h” to uMain.h.
5. For Delphi, scroll to the private declarations section and enter this procedure declaration:
procedure CreateChildForm(const childName: string);
For C++, add the following function declaration to the private: declarations of TfrMain.

94
2.5 VCL Procedures RAD Studio Building a VCL Forms MDI Application

void __fastcall CreateChildForm( const AnsiString childName );


6. For Delphi, scroll to the implementation section, and enter the code below:
procedure TfrMain.CreateChildForm (const childName: string);
var Child: TfrChild;
begin
Child := TfrChild.Create(Application);
Child.Caption := childName;
end;
For C++, add the following function definition to uMain.cpp:
void __fastcall TfrMain::CreateChildForm( const AnsiString childName )
{
TfrChild *Child = new TfrChild( Application );
Child->Caption = childName;
}

To write the event handler code to close the child window


1. If necessary, activate the frMain form; then select the Events tab in the Object Inspector.
2. Double-click the OnClose event. The Code Editor displays with the cursor in the TfrMain.FormClose (Delphi) or
TfrMain::FormClose (C++) event handler block.
3. For Delphi, enter the following code:
Action := caFree;
For C++, enter the following code:
Action = caFree;

To create the main menu and commands


2
1. From the Standard page on the Tool Palette, place a TMainMenu component on the main form.
2. Double-click the TMainMenu component. The Menu designer (frMain.MainMenu1) displays with the first blank menu item
highlighted.
3. In the Object Inspector on the Properties tab, enter mnFile for the Name property and &File for the Caption property; then
press ENTER. In the Menu designer, File displays as the name of the first menu item.
4. In the Menu designer, select File. A blank command field displays in the File group. Select the blank command.
5. In the Object Inspector, enter mnNewChild for the Name property and &New child for the Caption property; then press
ENTER. In the Menu designer, New child displays as the name of the first file command, and a blank command field displays
just beneath New child.
6. Select the blank command.
7. In the Object Inspector, enter mnCloseAll for the Name property and &Close All for the Caption property; then press ENTER.
In the Menu designer, Close All displays as the name of the second file command.

To add event handlers for the New child and Close All commands
1. If necessary, open the Menu designer and select New child.
2. In the Object Inspector, double-click the OnClick event on the Events tab. The Code Editor displays with the cursor in the
TfrMain.mnNewChildClick (Delphi) or TfrMain::mnNewChildClick (C++) event handler block.
3. For Delphi, enter the following code:
CreateChildForm('Child '+IntToStr(MDIChildCount+1));
For C++, enter the following code:
CreateChildForm( “Child “ + IntToStr( MDIChildCount + 1 ) );
4. In the Menu designer, select Close All.

95
Creating a New VCL Component RAD Studio 2.5 VCL Procedures

5. In the Object Inspector, double-click the OnClick event on the Events tab. The Code Editor displays with the cursor in the
TfrMain.mnCloseAllClick (Delphi) or TfrMain::mnCloseAllClick (C++) event handler block.
6. For Delphi, enter the following code:
for i:=0 to MDIChildCount - 1 do
MDIChildren[i].Close;
For C++, enter the following code:
for( int i = 0; i < MDIChildCount; i++ ) {
MDIChildren[i]->Close();
}
7. For Delphi, declare the local variable i. The first two lines of the event handler code should appear as shown here when you
are done:
procedure TfrMain.mnCloseAllClick(Sender: TObject);
var i: integer;
Note: The event handler minimizes the child window in the main window. To close the child window, you must add an OnClose
procedure to the child form (next).

To close the child window


1. Activate the child form.
2. In the Object Inspector, double-click the OnClose event on the Events tab. The Code Editor displays with the cursor in the
TfrChild.FormClose (Delphi) or TfrChild::FormClose (C++) event handler block.
3. For Delphi, enter the following statement:
Action := caFree;
For C++, enter the following statement:
2 Action = caFree;

To compile and run the MDI application


1. Choose Run Run.
2. The application executes, displaying the File command.
3. Choose File New child one or more times. A child window displays with each New child command.
4. Choose File Close All. The child windows close.
See Also
VCL Overview ( see page 36)

2.5.8 Building a VCL Forms SDI Application


To create a new SDI application
1. Choose File New Other Delphi Projects and double-click the SDI Application icon.
2. Pick a folder to save the files in and click OK.
3. Choose Run Run to compile and run the application.
See Also
VCL Overview ( see page 36)

96
2.5 VCL Procedures RAD Studio Creating a New VCL Component

2.5.9 Creating a New VCL Component


You can use the New VCL Component wizard to create a new VCL component for your application. The wizard detects the
personality of the product you are using and creates the appropriate type of component.

Metaprocedure: Creating a new VCL component


1. Specify an ancestor component on the Ancestor Component page.
2. Specify the class name and other properties on the Component page.
3. Choose from three methods for creating a unit:
• Create a unit, on the Create unit page
• Install the unit to an existing package, on the Existing package page
• Install the unit as a new package, on the New Package page

To specify an ancestor component


1. Create a new package for the new component by choosing File New Other Delphi Projects and double-clicking the
Package icon. This step adds a new package to the Project Manager and enables the Add unit to <my_new_package>
option on the Create unit page.
2. In the IDE, choose Component New VCL Component. This step displays the first page of the New VCL Component
wizard (the Ancestor Component page) and loads the page with names of components, along with the unit that defines each
component.
3. On the Ancestor Component page, select an ancestor component from the list. 2
4. Click Next. This displays the Component page of the New VCL Component wizard.

To specify the class name and other properties


1. On the Component page, the fields are prepopulated for Class Name, Palette Page, Unit name, and Search path. You can
either accept the default values for these fields, or you can change the values by using the following steps. If you want to
accept the default values, skip to step 6.
2. To change the default class name, enter a different class name in the Class Name textbox.
3. To change the default palette page for the component, in the Palette Page textbox, either enter the name of your chosen
Tool Palette area, or click the down-arrow to select from palette page areas.
4. In the Unit Name textbox, you can either enter or edit the full path of the unit name. Click [...] to browse for and select the unit
you want.
5. Either enter or edit the search path in the Search Path textbox.
6. Click Next. This opens the Create unit page of the wizard. The choices on the Create unit page are:
• Create Unit
• Install to Existing Package
• Install to New Package
• Add unit to <my_new_package> (this selection is present only if you create a new package in the very first step, above)

To create a unit
1. On the Create Unit page, select the Create Unit radio button.
2. Click Finish. The new unit opens in the Code Editor.

97
Building a VCL Forms ADO Database RAD Studio 2.5 VCL Procedures

To install a unit into an existing package


1. On the Create unit page, select the Install to Existing Package radio button.
2. Click Next. This generates a list of existing packages.
3. On the Existing Package page, select the package you want to install the unit into.
4. Click Finish. The new unit opens in the Code Editor.

To install a unit into a new package


1. On the Create unit page, select the Install to New Package radio button.
2. Click Next.
3. On the New Package page, enter a name for the package into the File Name textbox.
4. In the Description textbox, enter a description of your new package .
5. Click Finish. The new unit opens in the Code Editor.

To install a unit into the package created before starting the wizard
1. On the Create Unit page, select Add unit to <my_new_package>.
2. Click Finish. The new unit opens in the Code Editor.
See Also
VCL Overview ( see page 36)

2
2.5.10 Building a VCL Forms ADO Database Application
The following procedure describes how to build an ADO database application.

Building a VCL ADO application consists of the following major steps:

1. Set up the database connection.


2. Set up the dataset.
3. Set up the data provider, client dataset, and data source.
4. Connect a DataGrid to the connection components.
5. Run the application.

To add an ADO connection component


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.
2. From the dbGo page of the Tool Palette, place an ADOConnection component on the form.
3. Double-click the ADOConnection component to display the ConnectionString dialog.
4. If necessary, select Use Connection String; then click the Build button to display the Data Link Properties dialog.
5. On the Provider page of the dialog, select Microsoft Jet 4.0 OLE DB Provider; then click the Next button to display the
Connection page.
6. On the Connection page, click the ellipsis button to browse for the dbdemos.mdb database. The default path to this
database is C:\Program Files\Common Files\CodeGear Shared\Data.
7. Click Test Connection to confirm the connection. A dialog appears, indicating the status of the connection.

98
2.5 VCL Procedures RAD Studio Building a VCL Forms Application

8. Click OK to close the Data Link Properties dialog. Click OK to close the ConnectionString dialog.

To set up the dataset


1. From the dbGo page, place an ADODataSet component at the top of the form.
2. In the Object Inspector, select the Connection property drop-down list. Set it to ADOConnection1.
3. Set the CommandText property to an SQL command, for example, Select * from orders. You can either type the Select
statement in the Object Inspector or click the ellipsis to the right of CommandText to display the CommandText Editor
where you can build your own query statement.
Tip: If you need additional help while using the CommandText Editor
, click the Help button.
4. Set the Active property to True to open the dataset. You are prompted to log in. Use admin for the username and no
password.

To add the provider


1. From the Data Access page, place a DataSetProvider component at the top of the form.
2. In the Object Inspector, select the DataSet property drop-down list. Set it to ADODataSet1.

To add client dataset


1. From the Data Access page, place a ClientDataSet component to the right of the DataSetProvider component on the form.
2. In the Object Inspector, select the ProviderName drop-down. Set it to DataSetProvider1.
3. Set the Active property to True to allow data to be passed to your application. A data source connects the client dataset with
data-aware controls. Each data-aware control must be associated with a data source component to have data to display and
manipulate. Similarly, all datasets must be associated with a data source component for their data to be displayed and
manipulated in data-aware controls on the form. 2
To add the data source
1. In the Tool Palette on the Data Access page, place a DataSource component to the right of the ClientDataSet on the form.
2. In the Object Inspector, select the DataSet property drop-down. Set it to ClientDataSet1.

To connect a DataGrid to the DataSet


1. In the Tool Palette on the Data Controls page, place a DBGrid component on the form.
2. In the Object Inspector, select the DataSource property drop-down. Set the data source to DataSource1.
3. Choose Run Run.
4. You are prompted to log in. Enter admin for the username and no password. The application compiles and displays a VCL
form with a DBGrid.
See Also
VCL Overview ( see page 36)

2.5.11 Building a VCL Forms Application


The following procedure illustrates the essential steps to building a VCL Forms application using RAD Studio.

To create a VCL Form


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The

99
Creating Actions in a VCL Forms RAD Studio 2.5 VCL Procedures

VCL Forms Designer is displayed.


2. From the Tool Palette, place components onto the form to create the user interface.
3. Write the code for the controls.

To associate code with a control


1. Double-click the component on the form to which you want to apply logic. The Code Editor displays, cursor in place within the
event handler block.
2. Code your application logic.
3. Save and compile the application.
See Also
VCL Overview ( see page 36)

Building a VCL Forms "Hello World" Application ( see page 101)

Building a VCL Forms MDI Application Without Using a Wizard ( see page 94)

Using ActionManager to Create Actions in a VCL Forms Application ( see page 102)

2.5.12 Creating Actions in a VCL Forms Application


Using RAD Studio, the following procedure illustrates how to create actions using the ActionList tool. It sets up a simple
application and describes how to create a file menu item with a file open action.
2 Building the VCL application with ActionList actions consists of the following major steps:

1. Create a main window and add tools for creating a main menu and a File open action.
2. Add the File category to the main menu.
3. Add the File open action to the File category.
4. Build and run the application.

To create a main window


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer displays.
2. From the Standard category of the Tool Palette, add a TMainMenu and TActionList component to the form.
Tip: To display icons for nonvisual components such as ActionList1, choose Tools->Options->Environment Options
, select VCL Designer from the Delphi options, click Show Component Options, and click OK.

To add the File category to the main menu


1. Double-click MainMenu1 on the form. The MainMenu1 editor displays with the first blank command category selected.
2. In the Object Inspector, enter &File for the Caption property and press RETURN. File displays on the main menu.
3. Click File on the MainMenu1 editor. The first blank action under the File command displays. Select the blank action.
4. Double-click ActionList1 on the form. The ActionList editor displays.
5. In the editor, select New Standard Action from the drop-down list to display the Standard Action Classes dialog.
6. Scroll to the File category, and click the TFileOpen action.
7. Click OK to close the dialog. File displays in the Categories listbox in the ActionList editor.

100
2.5 VCL Procedures RAD Studio Building a VCL Forms "Hello World"

8. Click File in the editor. The FileOpen1 action displays in the Action listbox.

To add the File Open action to the File category


1. Double-click MainMenu1, if necessary, to display the MainMenu1 editor; select the blank action under the File category.
2. In the Object Inspector, enter &Open for the Caption property and select FileOpen1 from the Action property drop-down list;
then press RETURN. Open... displays in the blank action field in the MainMenu1 editor.

To build and run the application


1. Choose Run Run. The application executes, displaying a form with the main menu bar and the File menu.
2. Choose File Open in the application. The standard Open file dialog displays.
See Also
VCL Overview ( see page 36)

2.5.13 Building a VCL Forms "Hello World" Application


This procedure demonstrates how to construct a simple “Hello world” VCL Forms application using either Delphi or C++. Though
simple, the Windows Forms "Hello world" application demonstrates the essential steps for creating a VCL Forms application. The
application uses a VCL Form, a control, an event, and displays a dialog in response to a user action.

Creating the "Hello world" application consists of the following steps:

1. Create a VCL Form with a button control.


2. Write the code to display "Hello world" when the button is clicked. 2
3. Run the application.

To create a VCL Form


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon.
The VCL Forms Designer is displayed.
2. Click the VCL form to display the form view.
3. From the Standard page of the Tool Palette, place a TButton component on the form.

To display the "Hello world" string


1. Select Button1 on the form.
2. In the Object Inspector, double-click the OnClick action field on the Events tab. The Code Editor displays, with the cursor in
the Button1Click event handler block.
3. For Delphi, move the cursor before the begin reserved word and then press ENTER. This creates a new line above the code
block. For C++, place the cursor after the opening brace ({) and press ENTER.
4. For Delphi, insert the cursor on the new line created, and type the following variable declaration:
var s: string;
For C++, enter the following code:
AnsiString s;
5. For Delphi, insert the cursor within the code block and type the following code:
s:= 'Hello world!';
ShowMessage(s);
For C++, enter the following code:

101
Using ActionManager to Create Actions in RAD Studio 2.5 VCL Procedures

s = “Hello world!”;
ShowMessage( s );

To run the "Hello world" application


1. Choose Run Run to build and run the application. The form displays with a button called Button1.
2. Click Button1. A dialog box displays the message "Hello World!"
3. Close the VCL form to return to the IDE.
See Also
VCL Overview ( see page 36)

2.5.14 Using ActionManager to Create Actions in a VCL


Forms Application
Using RAD Studio, the following procedure illustrates how to create actions using ActionManager. It sets up a simple user
interface with a text area, as would be appropriate for a text editing application, and describes how to create a file menu item
with a file open action.

Building the VCL application with ActionManager actions consists of the following major steps:

1. Create a main window.


2. Add a File open action to the ActionManager.

2 3. Create the main menu.


4. Add the action to the menu.
5. Build and run the application.

To create a main window and add a File open action


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.
2. From the Additional page of the Tool Palette, add an TActionManager component to the form.
3. Double-click the TActionManager to display the Action Manager editor.
Tip: To display captions for nonvisual components such as ActionManager, choose Tools->Environment Options
. On the Designer tab, check Show component captions, and click OK.
4. If necessary, click the Actions tab.
5. Select New Standard Action from the drop-down list to display the Standard Action Classes dialog.
6. Scroll to the File category, and click the TFileOpen action.
7. Click OK to close the dialog.
8. In the Action Manager editor, select the File category. Open... displays in the Actions: list box.
9. Click Close to close the editor.

To create the main menu


1. From the Additional page of the Tool Palette, place an TActionMainMenuBar component on the form.
2. Open the Action Manager editor, and select the File category from the Categories: list box.
3. Drag File to the blank menu bar. File displays on the menu bar.

102
2.5 VCL Procedures RAD Studio Building a VCL Forms dbExpress

To build and run the application


1. Choose Run Run. The application executes, displaying a form with the main menu bar and the File menu.
2. Choose File Open. The Open file dialog displays.
See Also
VCL Overview ( see page 36)

Building a VCL Forms Application ( see page 99)

Building a VCL Forms MDI Application Without Using a Wizard ( see page 94)

2.5.15 Building a VCL Forms dbExpress Database


Application
The following procedure describes how to build a dbExpress database application.

Building a VCL Forms dbExpress application consists of the following major steps:

1. Set up the database connection.


2. Set up the unidirectional dataset.
3. Set up the data provider, client dataset, and data source.
4. Connect a DataGrid to the connection components.
5. Run the application. 2

To add a dbExpress connection component


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.
2. From the dbExpress page of the Tool Palette, place a TSQLConnection component on the form.
3. Double-click the TSQLConnection component to display the Connection Editor.
4. In the Connection Editor, set the Connection Name field to IBConnection.
5. In the Connections Setting box, specify the path to the InterBase database file called employee.gdb in the Database field.
By default, the file is located in C:\Program Files\Common Files\Borland Shared\Data.
6. Accept the value in the User_Name field (sysdba) and Password field (masterkey).
7. Click OK to close the Connection Editor and save your changes.

To set up the unidirectional dataset


1. In the Tool Palette on the dbExpress page, place a TSQLDataSet component at the top of the form.
2. In the Object Inspector, select the SQLConnection property drop-down list. Set it to TSQLConnection1.
3. Set the CommandText property to an SQL command, for example, Select * from SALES. You are prompted to log in.
Use the masterkey password. For the SQL command, you can either type a Select statement in the Object Inspector or click
the ellipsis to the right of CommandText to display the CommandText Editor where you can build your own query statement.
Tip: If you need additional help while using the CommandText Editor
, click the Help button.
4. In the Object Inspector, set the Active property to True to open the dataset.

103
Building an Application with XML RAD Studio 2.5 VCL Procedures

To add the provider


1. In the Tool Palette on the Data Access page, place a TDataSetProvider component at the top of the form.
2. In the Object Inspector, select the DataSet property drop-down list. Set it to SQLDataSet1.

To add client dataset


1. In the Tool Palette on the Data Access page, place a TClientDataSet component to the right of the TDataSetProvider
component on the form.
2. In the Object Inspector, select the ProviderName drop-down. Set it to DataSetProvider1.
3. Set the Active property to True to allow data to be passed to your application. A data source connects the client dataset with
data-aware controls. Each data-aware control must be associated with a data source component to have data to display and
manipulate. Similarly, all datasets must be associated with a data source component for their data to be displayed and
manipulated in data-aware controls on the form.

To add the data source


1. In the Tool Palette on the Data Access page, place a TDataSource component to the right of the TClientDataSet on the
form.
2. In the Object Inspector, select the DataSet property drop-down. Set it to ClientDataSet1.

To connect a DataGrid to the DataSet


1. In the Tool Palette on the Data Controls page, place a TDBGrid component on the form.
2. In the Object Inspector, select the DataSource property drop-down. Set the data source to DataSource1.
3. ChooseRun Run. You are prompted to enter a password. Enter masterkey. If you enter an incorrect password or no
password, the debugger throws an exception. The application compiles and displays a VCL form with a DBGrid.
2
See Also
VCL Overview ( see page 36)

2.5.16 Building an Application with XML Components


This example creates a VCL Forms application that uses an XMLDocument component to display contents in an XML file.

The basic steps are:


1. Create an XML document.
2. Create a VCL form.
3. Place an XMLDocument component on the form, and associate it with the XML file.
4. Create VCL components to enable the display of XML file contents.
5. Write event handlers to display XML child node contents.
6. Compile and run the application.

To create the XML document


1. Copy the text below into a file in a text editor.
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<!DOCTYPE StockHoldings [
<!ELEMENT StockHoldings (Stock+)>
<!ELEMENT Stock (name)>

104
2.5 VCL Procedures RAD Studio Building an Application with XML

<!ELEMENT Stock (price)>


<!ELEMENT Stock (symbol)>
<!ELEMENT Stock (shares)>
]>

<StockHoldings>
<Stock exchange="NASDAQ">
<name>CodeGear</name>
<price>10.375</price>
<symbol>BORL</symbol>
<shares>100</shares>
</Stock>

<Stock exchange="NYSE">
<name>MyCompany</name>
<price>8.75</price>
<symbol>MYCO</symbol>
<shares type="preferred">25</shares>
</Stock>
</StockHoldings>
2. Save the file to your local drive as an XML document. Give it a name such as stock.xml.
3. Open the document in your browser. The contents should display without error.
Note: In the browser, you can choose View->Source
to view the source file in the text editor.

To create a form with an XMLDocument component


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.
2. From the Internet page on the Tool Palette, place an TXMLDocument component on the form. 2
3. In the Object Inspector, click the ellipsis button next to the FileName property, browse to the location of the XML file you
created, and open it. The XML file is associated with the TXMLDocument component.
4. In the Object Inspector, set the Active property to true.

To set up the VCL components


1. From the Standard page on the Tool Palette, place a TMemo component on the form.
2. From the Standard page on the Tool Palette, place two TButton components on the form just above Memo1.
3. In the Object Inspector with Button1 selected, enter CodeGear for the Caption property.
4. In the Object Inspector with Button2 selected, enter MyCompany for the Caption property.

To display child node contents in the XML file


1. In the Object Inspector with Button1 selected, double-click the OnClick event on the Events tab. The Code displays with the
cursor in the TForm1.Button1Click event handler block.
2. Enter the following code to display the stock price for the first child node when the CodeGear button is clicked:
BorlandStock:=XMLDocument1.DocumentElement.ChildNodes[0];
Price:= BorlandStock.ChildNodes['price'].Text;
Memo1.Text := Price;
IXMLNode *BorlandStock = XMLDocument1->DocumentElement->
ChildNodes->GetNode(0);
WideString Price = BorlandStock->ChildNodes->
FindNode( "price" )->Text;
Memo1->Text = Price;
3. For Delphi, add a var section just above the code block in the event handler, and enter the following local variable
declarations:

105
Copying Data From One Stream To RAD Studio 2.5 VCL Procedures

var
BorlandStock: IXMLNode;
Price: string;
4. In the Object Inspector with Button2 selected, double-click the OnClick event on the Events tab. The Code displays with the
cursor in the TForm1.Button2Click event handler block.
5. Enter the following code to display the stock price for the second child node when the MyCompany button is clicked:
MyCompany:=XMLDocument1.DocumentElement.ChildNodes[1];
Price:= MyCompany.ChildNodes['price'].Text;
Memo1.Text := Price;
IXMLNode *MyCompany = XMLDocument1–>DocumentElement
->ChildNodes->GetNode(1);
WideString Price = BorlandStock->ChildNodes
->FindNode( “price” )->Text;
Memo1–>Text = Price;
6. For Delphi, add a var section just above the code block in the event handler, and enter the following local variable
declarations:
var
MyCompany: IXMLNode;
Price: string;

To compile and run the application


1. Choose Run Run to compile and execute the application. The application form displays two buttons and a memo.
2. Click the CodeGear button. The stock price displays.
3. Click the MyCompany button. The stock price displays.
See Also

2 VCL Overview ( see page 36)

Building a VCL Forms Application ( see page 99)

2.5.17 Copying Data From One Stream To Another


Creating this VCL application consists of the following steps:

1. Create a project directory containing a text file to copy.


2. Create a VCL Form with a button control.
3. Write the code to read the string and write it to a file.
4. Run the application.

To set up your project directory and a text file to copy


1. Create a directory in which to store your project files.
2. Using a text editor, create a simple text file and save it as from.txt in your project directory.

To create a VCL Form with a button control


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.
2. From the Standard page of the Tool palette, place a TButton component on the form.
3. In the Object Inspector, enter CopyFile for the Caption and Name properties.

106
2.5 VCL Procedures RAD Studio Copying a Complete String List (VCL)

To write the copy stream procedure


1. Select Button1 on the form.
2. In the Object Inspector, double-click the OnClick action on the Events tab. The Code Editor displays, with the cursor in the
TForm1.CopyFileClick (Delphi) or TForm1::CopyFileClick (C++) event handler block.
3. For Delphi, Place the cursor before the begin reserved word; then press return. This creates a new line above the code
block.
4. For Delphi, insert the cursor on the new line created and type the following variable declaration:
var stream1, stream2: TStream;
For C++, enter the following variable declarations:
TStream *stream1, *stream2;
5. Insert the cursor within the code block, and type the following code:
stream1 := TFileStream.Create('from.txt', fmOpenRead);
try
stream2:= TFileStream.Create('to.txt', fmCreate);
try
stream2.CopyFrom(stream1, stream1.Size);
finally
stream2.Free;
end;
finally
stream1.Free;
end;
stream1 = new TFileStream( “from.txt”, fmOpenRead );
try {
stream2 = new TFileStream( “to.txt”, fmCreate );
try { 2
stream2–>CopyFrom( stream1, stream1–>Size );
} __finally {
stream2–>Free();
}
} finally {
stream1–>Free();
}

To run the application


1. Save your project files; then choose Run Run to build and run the application. The form displays with a button called
CopyFile.
2. Click CopyFile.
3. Use a text editor to open the newly created file to.txt, which is located in your project directory. The contents of from.txt are
copied into to.txt.
See Also
VCL Overview ( see page 36)

Building a VCL Forms Application ( see page 99)

2.5.18 Copying a Complete String List (VCL)


Copying a string list can have the effect of appending to or overwriting an existing string list. This VCL application appends to a
string list. With a simple change, it can overwrite a string list. Creating this VCL application consists of the following steps:

107
Copying a Complete String List (VCL) RAD Studio 2.5 VCL Procedures

1. Create a VCL Form with TButtons, TComboBox, and TMemo controls.


2. Write the code to create a string list to the Button1 OnClick handler.
3. Write the code to copy the string list to the Button2 OnClick handler.
4. Run the application.

To create a VCL Form with Button, ComboBox, and Memo controls


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.
2. From the Standard page of the Tool palette, place two TButtons, a TComboBox, and a TMemo component on the form.

To create the string list


1. Select Button1 on the form.
2. In the Object Inspector, double-click the OnClick action on the Events tab. The Code Editor displays, with the cursor in the
TForm1.Button1Click (Delphi) or TForm1::Button1Click (C++) event handler block.
3. For Delphi, place the cursor before the begin reserved word; then press return. This creates a new line above the code
block.
4. For Delphi, insert the cursor on the new line created and type the following variable declarations:
var
StringList: TStrings;
For C++, enter the following variable declarations:
TStrings *StringList;
5. Insert the cursor within the code block, and type the following code:
2 StringList := TStringList.Create;
try
with StringList do begin
Add('This example uses a string List.');
Add('It is the easiest way to add strings');
Add('to a combobox''s list of strings.');
Add('Always remember: the TStrings.Create');
Add('method is abstract; use the');
Add('TStringList.Create method instead.');
end;

with ComboBox1 do begin


Width := 210;
Items.Assign(StringList);
ItemIndex := 0;
end;
finally
StringList.free;
end;
StringList = new TStringList();
try {
StringList->Add( "This example uses a string list" );
StringList->Add( "It is the easiest way to add strings" );
StringList->Add( "to a ComboBox's list of strings." );
StringList->Add( "Remember to call the TStringList constructor!" );
ComboBox1->Width = 210;
ComboBox1->Items->Assign( StringList );
ComboBox1->ItemIndex = 0;
} __finally {
StringList->Free();
}

108
2.5 VCL Procedures RAD Studio Creating Strings

To copy the string list


1. Select Button2 on the form.
2. In the Object Inspector, double-click the OnClick action on the Events tab. The Code Editor displays, with the cursor in the
TForm1.Button2Click (Delphi) or TForm1::Button2Click (C++) event handler block. At the cursor, enter the following
code:
Memo1.Lines.AddStrings(ComboBox1.Items);
Memo1–>Lines->AddStrings( ComboBox1–>Items

To run the application


1. Save your project files; then choose Run Run to build and run the application. The form displays with the controls.
2. Click Button1.
3. In ComboBox1, click the arrow to expand the drop-down list. The strings display in the TComboBox in the order listed in the
event handler code for Button1.
4. Click Button2. In the Memo1 window, the strings from ComboBox1 are appended to the 'Memo1' string.
Note: Try replacing the code in the Button2 event handler with the following code; then compile and run the application again.

Memo1.Lines.Assign(ComboBox1.Items);
Memo1–>Lines->Assign( ComboBox1–>Items );
The strings from ComboBox1 overwrite the 'Memo1' string.

See Also
VCL Overview ( see page 36)

Building a VCL Forms Application ( see page 99) 2

2.5.19 Creating Strings


Creating this VCL application consists of the following steps:

1. Create a VCL Form with TButton and TComboBox controls.


2. Write the code to create strings to the TButton OnClick handler.
3. Run the application.

To create a VCL Form with TButton and TComboBox controls


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.
2. From the Standard page of the Tool palette, place a TButton, a TLabel, and a TComboBox component on the form.

To write the create string procedure


1. Select Button1 on the form.
2. In the Object Inspector, double-click the OnClick action on the Events tab. The Code Editor displays, with the cursor in the
TForm1.Button1Click (Delphi) or TForm1::Button1Click (C++) event handler block.
3. For Delphi, place the cursor before the begin reserved word; then press RETURN. This creates a new line above the code
block.
4. For Delphi, insert the cursor on the new line created and type the following variable declarations:

109
Creating a VCL Form Instance Using a RAD Studio 2.5 VCL Procedures

var
StringList: TStrings;
For C++, enter the following variable declarations:
TStrings *StringList;
5. Insert the cursor within the code block, and type the following code:
StringList := TStringList.Create;
try
with StringList do begin
Add('Animals');
Add('Cats');
Add('Flowers');
end;

with ComboBox1 do begin


Width := 210;
Items.Assign(StringList);
ItemIndex := 0;
end;

Label1.Caption := 'Flowers has an index of ' +


IntToStr( StringList->IndexOf( 'Flowers' ) );
finally
StringList.free;
end;
StringList = new TStringList();
try {
StringList->Add( “Animals” );
StringList->Add( “Cats” );
StringList->Add( “Flowers” );
ComboBox1–>Width = 210;
2 ComboBox1–>Items->Assign( StringList );
ComboBox1–>ItemIndex = 0;
Label1–>Caption = “Flowers has an index of “ +
IntToStr( StringList->IndexOf( “Flowers” ) );
} __finally {
StringList->Free();
}

To run the application


1. Save your project files; then choose Run Run to build and run the application. The form displays with the controls.
2. Click the Button. The strings 'Animals', 'Cars', and 'Flowers' display alphabetically in a list in the ListBox. The Label caption
displays the message string: 'Flowers has an index value of 2.'
3. In the ComboBox, click the arrow to expand the drop-down list. The strings added in the TButton event handler appear.
See Also
VCL Overview ( see page 36)

Building a VCL Forms Application ( see page 99)

2.5.20 Creating a VCL Form Instance Using a Local Variable


A safe way to create a unique instance of a modal VCL form is to use a local variable in an event handler as a reference to a
new instance. If you use a local variable, it doesn't matter whether the form is auto-created or not. The code in the event handler
makes no reference to the global form variable. Using RAD Studio, the following procedure creates a modal form instance
dynamically. It (optionally) removes the second form's invocation at startup.

110
2.5 VCL Procedures RAD Studio Creating a VCL Form Instance Using a

Building this VCL application consists of the following steps:

1. Create the project directory.


2. Create two forms for the project.
3. Remove the second form's invocation at startup (optional).
4. Link the forms.
5. Create a control on the main form to create and display the modal form; then write the event handler.
6. Build and run the application.

To create the two forms


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer displays Form1.
2. Choose File New Other Delphi Projects Delphi Files or C++Builder Projects and double-click the Form icon. The VCL
Forms Designer displays Form2.

To optionally remove Form2's invocation at startup


1. Choose Project Options Forms. The Project Options dialog displays.
2. Select Form2 in the Auto-create forms list and click [>]. Form2 is moved to the Available forms list.
3. Click OK to close the dialog.

To link Form1 to Form2


1. Select Form1 and choose File Use Unit (Delphi) or Include Unit Hdr (C++). The Uses Unit dialog displays.
2. Select Form2 (the form that Form1 needs to reference) in the dialog.
2
3. Click OK.
For Delphi, a uses clause containing the unit name Unit2 is placed in the implementation section of Unit1.
For C++, the #include “Unit2.h” directive is added to Unit1.h.

To display Form2 from Form1


1. Select Form1, if necessary; then, from the Standard page of the Tool Palette, place a TButton on the form.
2. In the Object Inspector with Button1 selected, double-click the OnClick event on the Events tab. The Code Editor displays
with the cursor in the TForm1.Button1Click (Delphi) or TForm1::Button1Click (C++) event handler block.
3. For Delphi, insert the cursor just above the event handler block and enter the following statement to define a local variable:
var FM: TForm2;
For C++, enter the following variable declaration:
TForm2 *FM;
4. Insert the cursor in the event handler block, and enter the following code:
FM := TForm2.Create(self);
FM.ShowModal;
FM.Free;
FM = new TForm2( this );
FM->ShowModal();
FM->Free();

To build and run the application


1. Save all files in the project; then choose Run Run. The application executes, displaying Form1.
2. Click the button. Form2 displays.

111
Deleting Strings RAD Studio 2.5 VCL Procedures

3. With Form2 displayed, attempt to click on Form1 to activate it. Nothing happens. Click the X in the upper right corner of
Form2. Form2 closes and Form1 becomes the active form.
See Also
VCL Overview ( see page 36)

Building a VCL Forms Application ( see page 99)

Dynamically Creating a VCL Modeless Form ( see page 121)

Displaying an Auto-Created VCL Form ( see page 113)

2.5.21 Deleting Strings


Creating this VCL application consists of the following steps:

1. Create a VCL Form with Buttons and ListBox controls.


2. Write the code to add strings to a list.
3. Write the code to delete a string from the list.
4. Run the application.

To create a VCL Form with TButton and ListBox controls


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.

2 2. From the Standard page of the Tool palette, place two TButtons and a TListBox component on the form.
3. Select Button1 on the form.
4. In the Object Inspector, enter Add for the Name and Caption properties.
5. Select Button2 on the form.
6. In the Object Inspector, enter Delete for the Name and Caption properties.

To add strings to a list


1. Select the Add button on the form.
2. In the Object Inspector, double-click the OnClick action on the Events tab. The Code Editor displays, with the cursor in the
TForm1.AddClick (Delphi) or TForm1::AddClick (C++) event handler block.
3. For Delphi, place the cursor before the begin reserved word; then press return. This creates a new line above the code
block.
4. For Delphi, insert the cursor on the new line created and type the following variable declaration:
var
MyList: TStringList;
For C++, enter the following variable declaration:
TStringList *MyList;
5. Insert the cursor within the code block, and type the following code:
MyList := TStringList.Create;
try
with MyList do
begin
Add('Mice');
Add('Goats');

112
2.5 VCL Procedures RAD Studio Displaying an Auto-Created VCL Form

Add('Elephants');
Add('Birds');
ListBox1.Items.AddStrings(MyList);
end;
finally
MyList.Free;
end;
MyList = new TStringList();
try {
MyList->Add( “Mice” );
MyList->Add( “Goats” );
MyList->Add( “Elephants” );
MyList->Add( “Birds” );
ListBox1–>Items->AddStrings( MyList );
} __finally {
MyList->Free();
}

To delete a string from the list


1. Select the Delete button on the form.
2. In the Object Inspector, double-click the OnClick action on the Events tab. The Code Editor displays, with the cursor in the
TForm1.DeleteClick (Delphi) or TForm1::DeleteClick (C++) event handler block.
3. For Delphi, place the cursor before the begin reserved word; then press ENTER. This creates a new line above the code
block.
4. For Delphi, insert the cursor on the new line created and type the following variable declaration:
var
BIndex: Integer;
For C++, enter the following variable declaration:
2
int BIndex;
5. For Delphi, insert the cursor within the code block and type the following code:
with ListBox1.Items do
begin
BIndex := IndexOf('Elephants');
Delete (BIndex);
end;
BIndex = ListBox1–>Items->IndexOf( “Elephants” );
ListBox1–>Items->Delete( BIndex );

To run the application


1. Save your project files; then choose Run Run to build and run the application. The form displays with the controls.
2. Click the Add button. The strings 'Mice', 'Goats', 'Elephants', and 'Birds' display in the order listed.
3. Click the Delete button. The string 'Elephants' is deleted from the list.
See Also
VCL Overview ( see page 36)

Building a VCL Forms Application ( see page 99)

2.5.22 Displaying an Auto-Created VCL Form


Using RAD Studio, the following procedure creates a modal form at design time that is displayed later during program execution.

113
Displaying a Bitmap Image in a VCL Forms RAD Studio 2.5 VCL Procedures

Building this VCL application consists of the following steps:

1. Create the project directory.


2. Create two forms for the project.
3. Link the forms.
4. Create a control on the main form to display the modal form; then write the event handler.
5. Build and run the application.

To create the two forms


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer displays Form1.
2. Choose File New Other Delphi Projects Delphi Files or File New Other C++Builder Files and double-click the
Form icon. The VCL Forms Designer displays Form2.

To link Form1 to Form2


1. For Delphi, select Form1 and choose File Use Unit. For C++, select Form1 and choose File Include Unit Hdr. The Uses
Unit dialog displays.
2. Select Form2 (the form that Form1 needs to reference) in the dialog.
3. Click OK.
For Delphi, a uses clause containing the unit name Unit2 is placed in the implementation section of Unit1.
For C++, the #include “Unit2.h” directive is added to Unit1.h.

To display Form2 from Form1


2 1. Select Form1, if necessary; then, from the Standard page of the Tool Palette, place a button on the form.
2. In the Object Inspector with Button1 selected, double-click the OnClick event on the Events tab. The Code Editor displays
with the cursor in the TForm1.Button1Click (Delphi) or TForm1::Button1Click (C++) event handler block.
3. Enter the following event handling code:
Form2.ShowModal;
Form2–>ShowModal();

To build and run the application


1. Save all files in the project; then choose Run Run. The application executes, displaying Form1.
2. Click the button. Form2 displays.
3. Click the X in the upper right corner of Form2. Form2 closes and Form1 becomes the active form.
See Also
VCL Overview ( see page 36)

Building a VCL Forms Application ( see page 99)

Dynamically Creating a VCL Modal Form ( see page 120)

2.5.23 Displaying a Bitmap Image in a VCL Forms


Application
This procedure loads a bitmap image from a file and displays it to a VCL form.

114
2.5 VCL Procedures RAD Studio Displaying a Bitmap Image in a VCL Forms

1. Create a VCL form with a button control.


2. Provide a bitmap image.
3. Code the button's onClick event handler to load and display a bitmap image.
4. Build and run the application.

To create a VCL form and button


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.
2. From the Standard page of the Tool Palette, place a TButton component on the form.

To provide a bitmap image


1. Create a directory in which to store your project files.
2. Locate a bitmap image on your local drive, and copy it to your project directory.
3. Save all files in your project to your project directory.

To write the OnClick event handler


1. In the Object Inspector, double-click the Button1 OnClick event on the Events tab. The Code Editor displays with the cursor
in the TForm1.Button1Click (Delphi) or TForm1::Button1Click (C++) event handler block.
2. Enter the following event handling code, replacing MyFile.bmp with path to the bitmap image in your project directory:
Bitmap := TBitmap.Create;
try
Bitmap.LoadFromFile('MyFile.bmp');
Form1.Canvas.Brush.Bitmap := Bitmap;
Form1.Canvas.FillRect(Rect(0,0,100,100));
finally 2
Form1.Canvas.Brush.Bitmap := nil;
Bitmap.Free;
end;
Graphics::TBitmap *Bitmap = new Graphics::TBitmap();
try {
Bitmap->LoadFromFile( "..\\MyFile.bmp" );
Form1->Canvas->Brush->Bitmap = Bitmap;
Form1->Canvas->FillRect( Rect(0,0,100,100) );
} __finally {
Form1->Canvas->Brush->Bitmap = NULL;
Bitmap->Free();
}
Note: For C++ projects, the code assumes the target output directory is located in the project directory.

Tip: You can change the size of the rectangle to be displayed by adjusting the Rect parameter values.

3. For Delphi, add the following variable declaration in the var block:
Bitmap : TBitmap;

To run the program


1. Select Run Run.
2. Click the button to display the image bitmap in a 100 x 100-pixel rectangle in the upper left corner of the form.
See Also
VCL Overview ( see page 36)

Drawing Straight Lines In a VCL Application ( see page 119)

Drawing Rectangles and Ellipses in a VCL Application ( see page 118)

115
Displaying a Full View Bitmap Image in a RAD Studio 2.5 VCL Procedures

Drawing a Polygon in a VCL Application ( see page 117)

Placing A Bitmap Image In a Combo Box of a VCL Application ( see page 135)

2.5.24 Displaying a Full View Bitmap Image in a VCL Forms


Application
This procedure loads a bitmap image from a file and displays it in its entirety to a VCL form. The procedure uses the Height and
Width properties of the Bitmap object to display a full view of the image.

1. Create a VCL form with a button control.


2. Provide a bitmap image.
3. Code the button's onClick event handler to load and display a bitmap image.
4. Build and run the application.

To create a VCL form and button


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.
2. From the Standard page of the Tool Palette, place a button component on the form.
3. In the Object Inspector, enter Full View for the Caption property and FullView for the name property.

To provide a bitmap image


2
1. Create a directory in which to store your project files.
2. Locate a bitmap image on your local drive, and copy it to your project directory.
3. Save all files in your project to your project directory.

To write the OnClick event handler


1. In the Object Inspector, double-click the Button1 OnClick event on the Events tab. The Code Editor displays with the cursor
in the TForm1.FullViewClick (Delphi) or TForm1::FullViewClick (C++) event handler block.
2. Enter the following event handling code, replacing MyFile.bmp with the name of the bitmap image in your project directory:
Bitmap := TBitmap.Create;
try
Bitmap.LoadFromFile('MyFile.bmp');
Form1.Canvas.Brush.Bitmap := Bitmap;
Form1.Canvas.FillRect(Rect(0,0,Bitmap.Width,Bitmap.Height));
finally
Form1.Canvas.Brush.Bitmap := nil;
Bitmap.Free;
end;
Graphics::TBitmap Bitmap = new Graphics::TBitmap();
try {
Bitmap->LoadFromFile( “..\\MyFile.bmp” );
Form1–>Canvas->Brush->Bitmap = Bitmap;
Form1–>Canvas->FillRect(
Rect( 0, 0, Bitmap->Width, Bitmap->Height ) );
} __finally {
Form1–>Canvas->Brush->Bitmap = NULL;
Bitmap->Free();
}
Note: For C++ projects, the code assumes the target output directory is located in the project directory.

116
2.5 VCL Procedures RAD Studio Drawing a Polygon in a VCL Forms

3. For Delphi, add the following variable declaration in the var block:
Bitmap : TBitmap;s

To run the program


1. Choose Run Run.
2. Click the button to display the image bitmap in a rectangle in the upper left corner of the form.
See Also
VCL Overview ( see page 36)

Drawing Straight Lines In a VCL Forms Application ( see page 119)

Displaying a Bitmap Image in a VCL Forms application ( see page 114)

Drawing Rectangles and Ellipses in a VCL Forms Application ( see page 118)

Drawing a Polygon in a VCL Forms Application ( see page 117)

Placing A Bitmap Image In a Combo Box of a VCL Forms Application ( see page 135)

2.5.25 Drawing a Polygon in a VCL Forms Application


This procedure draws a polygon in a VCL form.

1. Create a VCL form.


2. Code the form's OnPaint event handler to draw a polygon. 2
3. Build and run the application.

To create a VCL form


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.
2. In the form view, click the form, if necessary, to display Form1 in the Object Inspector.

To write the OnPaint event handler


1. In the Object Inspector, click the Events tab.
2. Double-click the OnPaint event. The Code Editor displays with the cursor in the TForm1.FormPaint (Delphi) or
TForm1::FormPaint (C++) event handler block.
3. Enter the following event handling code:
Canvas.Polygon ([Point(0,0), Point(0, ClientHeight),
Point(ClientWidth, ClientHeight)]);
TPoint points[] = { Point(0,0),
Point(0, ClientHeight),
Point(ClientWidth, ClientHeight) };
Canvas->Polygon( points, 3 );

To run the program


1. Select Run Run.
2. The applications executes, displaying a right triangle in the lower left half of the form.
See Also
VCL Overview ( see page 36)

117
Drawing a Rounded Rectangle in a VCL RAD Studio 2.5 VCL Procedures

Drawing Straight Lines In a VCL Forms Application ( see page 119)

Drawing Rectangles and Ellipses in a VCL Forms Application ( see page 118)

Displaying a Bitmap Image in a VCL Forms Application ( see page 114)

2.5.26 Drawing Rectangles and Ellipses in a VCL Forms


Application
This procedure draws a rectangle and ellipse in a VCL form.

1. Create a VCL form.


2. Code the form's OnPaint event handler to draw a rectangle and ellipse.
3. Build and run the application.

To create a VCL form and place an image on it


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.
2. In the form view, click the form, if necessary, to display Form1 in the Object Inspector.

To write the OnPaint event handler


1. In the Object Inspector, double-click the Form1 OnPaint event on the Events tab. The Code Editor displays with the cursor
in the TForm1.FormPaint (Delphi) or TForm1::FormPaint (C++) event handler block.
2
2. Enter the following event handling code:
Canvas.Rectangle (0, 0, ClientWidth div 2, ClientHeight div 2);
Canvas.Ellipse (0, 0, ClientWidth div 2, ClientHeight div 2);
Canvas->Rectangle( 0, 0, ClientWidth / 2, ClientHeight / 2 );
Canvas->Ellipse( 0, 0, ClientWidth / 2, ClientHeight / 2 );

To run the program


1. Choose Run Run.
2. The applications executes, displaying a rectangle in the upper left quadrant, and an ellipse in the same area of the form.
See Also
VCL Overview ( see page 36)

Drawing a Polygon in a VCL Forms Application ( see page 117)

Displaying a Bitmap Image in a VCL Forms Application ( see page 114)

2.5.27 Drawing a Rounded Rectangle in a VCL Forms


Application
This procedure draws a rounded rectangle in a VCL form.

1. Create a VCL form and code the form's OnPaint event handler.
2. Build and run the application.

118
2.5 VCL Procedures RAD Studio Drawing Straight Lines In a VCL Forms

To create a VCL form


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.
2. In the Object Inspector, click the Events tab.
3. Double-click the OnPaint event. The Code Editor displays with the cursor in the TForm1.FormPaint (Delphi) or
TForm1::FormPaint (C++) event handler block.
4. Enter the following event handling code:
Canvas.RoundRect(0, 0, ClientWidth div 2,
ClientHeight div 2, 10, 10);
Canvas->RoundRect( 0, 0, ClientWidth / 2, ClientHeight / 2, 10, 10 );

To run the program


1. Save all files in your project; then choose Run Run.
2. The application executes, displaying a rounded rectangle in the upper left quadrant of the form.
See Also
VCL Overview ( see page 36)

Drawing Rectangles and Ellipses in a VCL Forms Application ( see page 118)

2.5.28 Drawing Straight Lines In a VCL Forms Application


2
This procedure draws two diagonal straight lines on an image in a VCL form.

1. Create a VCL form.


2. Code the form's OnPaint event handler to draw the straight lines.
3. Build and run the application.

To create a VCL form and place an image on it


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.
2. In the form view, click the form, if necessary, to display Form1 in the Object Inspector.

To write the OnPaint event handler


1. In the Object Inspector, double-click the Form1 OnPaint event on the Events tab. The Code Editor displays with the cursor
in the TForm1.FormPaint event handler block.
2. Enter the following event handling code:
with Canvas do
begin
MoveTo(0,0);
LineTo(ClientWidth, ClientHeight);
MoveTo(0, ClientHeight);
LineTo(ClientWidth, 0);
end;
Canvas->MoveTo( 0, 0 );
Canvas->LineTo( ClientWidth, ClientHeight );
Canvas->MoveTo( 0, ClientHeight );
Canvas->LineTo( ClientWidth, 0 );

119
Dynamically Creating a VCL Modal Form RAD Studio 2.5 VCL Procedures

To run the program


1. Choose Run Run.
2. The applications executes, displaying a form with two diagonal crossing lines.
Tip: To change the color of the pen to green, insert this statement following the first MoveTo() statement in the event
handler code: Pen.Color := clGreen; (Delphi) Canvas->Pen->Color = clGreen; (C++). Experiment using other
canvas and pen object properties. See "Using the properties of the Canvas object" in the Delphi 7 Developer's Guide.

See Also
VCL Overview ( see page 36)

Building VCL Forms Applications With Graphics ( see page 93)

Drawing Rectangles and Ellipses in a VCL Forms Application ( see page 118)

Drawing a Polygon in a VCL Forms Application ( see page 117)

Displaying a Bitmap Image in a VCL Forms Application ( see page 114)

2.5.29 Dynamically Creating a VCL Modal Form


You may not want all your VCL application's forms in memory at once. To reduce the amount of memory required at load time,
your application can create forms only when it needs to make them available for use. A dialog box, for example, needs to be in
2 memory only during the time the user interacts with it. Using RAD Studio, the following procedure creates a modal form
dynamically. The main difference between dynamically creating a form and displaying an auto-created VCL form is that you
remove the second form's invocation at startup and write code to dynamically create the form.

Building this VCL application consists of the following steps:

1. Create the project directory.


2. Create two forms for the project.
3. Remove the second form's invocation at startup.
4. Link the forms.
5. Create a control on the main form to create and display the modal form; then write the event handler.
6. Build and run the application.

To create the two forms


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer displays Form1.
2. Choose File New Other Delphi Projects Delphi Files or File New Other C++Builder Files and double-click the
Form icon. The VCL Forms Designer displays Form2.

To remove Form2's invocation at startup


1. Choose Project Options Forms. The Project Options dialog displays.
2. Select Form2 in the Auto-create forms list and click [>]. Form2 is moved to the Available forms list.
3. Click OK to close the dialog.

120
2.5 VCL Procedures RAD Studio Dynamically Creating a VCL Modeless

To link Form1 to Form2


1. For Delphi, select Form1 and choose File Use Unit. For C++, select Form1 and choose File Include Unit Hdr The Uses
Unit dialog displays.
2. Select Form2 (the form that Form1 needs to reference) in the dialog.
3. Click OK. For Delphi, a uses clause containing the unit name Unit2 is placed in the implementation section of Unit1. For C++,
the #include “Unit2.h” directive is added to Unit1.h.

To display Form2 from Form1


1. Select Form1, if necessary; then, from the Standard page of the Tool Palette, place a TButton on the form.
2. In the Object Inspector with Button1 selected, double-click the OnClick event on the Events tab. The Code Editor displays
with the cursor in the TForm1.Button1Click (Delphi) or TForm1::Button1Click (C++) event handler block.
3. Enter the following event handling code:
Form2 := TForm2.Create(self);
try
Form2.ShowModal;
finally
Form2.Free;
end;
Form2 = new TForm2( this );
try {
Form2–>ShowModal();
} __finally {
Form2–>Free();
}

To build and run the application


2
1. Save all files in the project; then choose Run Run. The application executes, displaying Form1.
2. Click the button. Form2 displays.
3. Click the X in the upper right corner of the form. Form2 closes and Form1 becomes the active form.
See Also
VCL Overview ( see page 36)

Building a VCL Forms Application ( see page 99)

Dynamically Creating a VCL Modeless Form ( see page 121)

Displaying an Auto-Created VCL Form ( see page 113)

2.5.30 Dynamically Creating a VCL Modeless Form


A modless form is a window that is displayed until it is either obscured by another window or until it is closed or minimuzed by
the user. Using RAD Studio, the following procedure creates a modeless form dynamically.

Building this VCL application consists of the following steps:

1. Create the project directory.


2. Create two forms for the project.
3. Remove the second form's invocation at startup.
4. Link the forms.

121
Iterating Through Strings in a List RAD Studio 2.5 VCL Procedures

5. Create a control on the main form to create and display the modal form; then write the event handler.
6. Build and run the application.

To create the two forms


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer displays Form1.
2. Choose File New Other Delphi Projects Delphi Files or File New Other C++Builder Files and double-click the
Form icon. The VCL Forms Designer displays Form2.

To remove Form2's invocation at startup


1. Choose Project Options. The Project Options dialog displays.
2. Select Form2 in the Auto-create forms list and click [>]. Form2 is moved to the Available forms list.
3. Click OK to close the dialog.

To link Form1 to Form2


1. For Delphi, select Form1 and choose File Use Unit. For C++, select Form1 and choose File Include Unit Hdr. The Uses
Unit dialog displays.
2. Select Form2 (the form that Form1 needs to reference) in the dialog.
3. Click OK. For Delphi, a uses clause containing the unit name Unit2 is placed in the implementation section of Unit1. For C++,
the #include “Unit2.h” directive is added to Unit1.h.

To display Form2 from Form1


1. Select Form1, if necessary; then, from the Standard page of the Tool Palette, place a button on the form.
2 2. In the Object Inspector with Button1 selected, double-click the OnClick event on the Events tab. The Code Editor displays
with the cursor in the TForm1.Button1Click (Delphi) or TForm1::Button1Click (C++)event handler block.
3. Enter the following event handling code:
Form2 := TForm2.Create(self);
Form2.Show;
Form2 = new TForm2( this );
Form2–>Show();
Note: If your application requires additional instances of the modeless form, declare a separate global variable for each
instance. In most cases you use the global reference that was created when you made the form (the variable name that matches
the Name property of the form).

To build and run the application


1. Save all files in the project; then choose Run Run. The application executes, displaying Form1.
2. Click the button. Form2 displays.
3. Click Form1. Form1 becomes the active form. Form2 displays until you minimize or close it.
See Also
VCL Overview ( see page 36)

Building a VCL Forms Application ( see page 99)

Displaying an Auto-Created VCL Form ( see page 113)

Dynamically Creating a VCL Modal Form ( see page 120)

122
2.5 VCL Procedures RAD Studio Iterating Through Strings in a List

2.5.31 Iterating Through Strings in a List


This VCL application first creates a list of strings. Then it iterates through the strings, changing all string characters to uppercase.
It consists of the following steps:

1. Create a VCL Form with Buttons and TListBox controls.


2. Write the code to create a string list and add strings to it.
3. Write the code to iterate through the string list to process string characters.
4. Run the application.

To create a VCL Form with TButton and TListBox controls


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.
2. From the Standard page of the Tool palette, place two TButtons and a TListBox component on the form.
3. Select Button1 on the form.
4. In the Object Inspector, enter Add for the Name and Caption properties.
5. Select Button2 on the form.
6. In the Object Inspector, enter ToUpper for the Name and Caption properties.

To create a string list and add strings to it


1. Select the Add button on the form. 2
2. In the Object Inspector, double-click the OnClick action on the Events tab. The Code Editor displays, with the cursor in the
TForm1.AddClick (Delphi) or TForm1::AddClick (C++) event handler block.
3. For Delphi, place the cursor before the begin reserved word; then press ENTER. This creates a new line above the code
block.
4. For Delphi, insert the cursor on the new line created, and type the following variable declaration:
var
MyList: TStringList;
5. Insert the cursor within the code block, and type the following code:
MyList := TStringList.Create;
try
with MyList do
begin
Add('Mice');
Add('Goats');
Add('Elephants');
Add('Birds');
ListBox1.Items.AddStrings(MyList);
end;
finally
MyList.Free;
end;
TStringList *MyList = new TStringList();
try {
MyList->Add(“Mice”);
MyList->Add(“Goats”);
MyList->Add(“Elephants”);
MyList->Add(“Birds”);
ListBox1–>Items->AddStrings( MyList );

123
Writing Cleanup Code RAD Studio 2.5 VCL Procedures

} __finally {
MyList->Free();
}

To change all characters to uppercase


1. Select the ToUpper button on the form.
2. In the Object Inspector, double-click the OnClick action on the Events tab. The Code Editor displays, with the cursor in the
TForm1.ToUpperClick (Delphi) or TForm1::ToUpperClick (C++) event handler block.
3. For Delphi, place the cursor before the begin reserved word; then press return. This creates a new line above the code
block.
4. For Delphi, insert the cursor on the new line created and type the following variable declaration:
var
Index: Integer;
5. Insert the cursor within the code block, and type the following code:
for Index := 0 to ListBox1.Items.Count - 1 do
ListBox1.Items[Index] := UpperCase(ListBox1.Items[Index]);
for( int i = 0; i < ListBox1–>Items->Count; i++ ) {
ListBox1–>Items[i] = UpperCase( ListBox1–>Items[i] );
}

To run the application


1. Save your project files; then choose Run Run to build and run the application. The form displays with the controls.
2. Click the Add button. The strings 'Mice', 'Goats', 'Elephants', and 'Birds' display in the order listed.
3. Click the ToUpper button. The string characters display in uppercase.

2 See Also
VCL Overview ( see page 36)

Building a VCL Forms Application ( see page 99)

2.5.32 Building a Multithreaded Application


These are the essential steps to building a VCL Forms multithreaded application with a thread object using RAD Studio.

To drop a component on a form


1. Create a VCL form with a defined thread object.
2. Optionally initialize the thread.
3. Write the thread function.
4. Optionally write the cleanup code.
See Also
VCL Overview ( see page 36)

Defining a Thread Object ( see page 126)

Initializing a Thread ( see page 130)

Writing the Thread Function ( see page 134)

Writing Cleanup Code ( see page 125)

124
2.5 VCL Procedures RAD Studio Avoiding Simultaneous Thread Access to

2.5.33 Writing Cleanup Code


To clean up after your thread finishes executing
1. Centralize the cleanup code by placing it in the OnTerminate event handler. This ensures that the code gets executed.
2. Do not use any thread-local variables, because OnTerminate is not run as part of your thread.
3. You can safely access any objects from the OnTerminate handler.
See Also
VCL Overview ( see page 36)

Building a Multithreaded Application ( see page 124)

2.5.34 Avoiding Simultaneous Thread Access to the Same


Memory
Use these basic techniques to prevent other threads from accessing the same memory as your thread:

1. Lock objects.
2. Use critical sections.
3. Use a multi-read exclusive-write synchronizer 2
To lock objects
1. For objects such as canvas that have a Lock method, call the Lock method, as necessary, to prevent other objects from
accessing the object, and call Unlock when locking is no longer required.
2. Call TThreadList.LockList (Delphi) or TThreadList::LockList() (C++) to block threads from using the list object
TThreadList, and call TThreadList.UnlockList when locking is no longer required.
Note: You can safely make calls to TCanvas.Lock and TThreadList.LockList.

To use a critical section


1. Create a global instance of TCriticalSection.
2. Call the Acquire method to lock out other threads while accessing global memory.
3. Call the Release method so other threads can access the memory by calling Acquire. The following code has a global
critical section variable LockXY that blocks access to the global variables X and Y. To use X or Y, a thread must surround that
use with calls to the critical section such as shown here:
LockXY.Acquire;
try
X := X + 1;
Y := sin(X);
finally
LockXY.Release
end;
LockXY->Acquire();
try {
x++;
y = sin( x );

125
Defining the Thread Object RAD Studio 2.5 VCL Procedures

} __finally {
LockXY->Release();
}
Warning: Critical sections only work if every thread uses them to access global memory. Otherwise, problems of simultaneous
access can occur.

To use the multi-read exclusive-write synchronizer


1. Create a global instance of TMultiReadExclusiveWriteSynchronizer that is associated with the global memory you
want to protect.
2. Before any thread reads from the memory, it must call BeginRead.
3. At the completion of reading memory, the thread must call EndRead.
4. Before any thread writes to the memory, it must call BeginWrite.
5. At the completion of writing to the memory, the thread must call EndWrite.
Warning: The multi-read exclusive-write synchronizer only works if every thread uses it to access the associated global
memory. Otherwise, problems of simultaneous access can occur.
See Also
VCL Overview ( see page 36)

Writing the Thread Function ( see page 134)

Using the Main VCL Thread ( see page 131)

Waiting for Threads ( see page 132)

Handling Exceptions ( see page 129)


2

2.5.35 Defining the Thread Object


To define the thread object
1. Choose File New Other Delphi Projects Delphi Files or File New Other C++Builder Files and double-click the
Thread Object icon. The New Thread Object dialog displays.
2. Enter a class name, for example, TMyThread.
3. Optionally check the Named Thread check box, and enter a name for the thread, for example, MyThreadName.
Tip: Entering a name for Named Thread makes it easier to track the thread while debugging.

4. Click OK.
The Code Editor displays the skeleton code for the thread object.
The code generated for the new unit will look like this if you named your thread class TMyThread.
unit Unit1;

interface

uses
Classes;

type
TMyThread = class(TThread)
private

126
2.5 VCL Procedures RAD Studio Defining the Thread Object

{ Private declarations }
protected
procedure Execute; override;
end;

implementation

{ Important: Methods and properties of objects in visual components can only be


used in a method called using Synchronize, for example,

Synchronize(UpdateCaption);

and UpdateCaption could look like,

procedure TMyThread.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }

{ TMyThread }

procedure TMyThread.Execute;
begin
{ Place thread code here }
end;

end.
Adding a name for the thread generates additional code for the unit. It includes the Windows unit, adds the procedure (Delphi) or
function (C++) SetName, and adds the record TThreadNameInfo (Delphi) or struct THREADNAME_INFO (C++). The name is
assigned to the FName field, as shown here:
unit Unit1;
2
interface

uses
Classes {$IFDEF MSWINDOWS} , Windows {$ENDIF};

type
TMyThread = class(TThread)
private
procedure SetName;
protected
procedure Execute; override;
end;

implementation

{ Important: Methods and properties of objects in visual components can only be


used in a method called using Synchronize, for example,

Synchronize(UpdateCaption);

and UpdateCaption could look like,

procedure TMyThread.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }

{$IFDEF MSWINDOWS}
type
TThreadNameInfo = record
FType: LongWord; // must be 0x1000
FName: PChar; // pointer to name (in user address space)

127
Defining the Thread Object RAD Studio 2.5 VCL Procedures

FThreadID: LongWord; // thread ID (-1 indicates caller thread)


FFlags: LongWord; // reserved for future use, must be zero
end;
{$ENDIF}

{ TMyThread }

procedure TMyThread.SetName;
{$IFDEF MSWINDOWS}
var
ThreadNameInfo: TThreadNameInfo;
{$ENDIF}
begin
{$IFDEF MSWINDOWS}
ThreadNameInfo.FType := $1000;
ThreadNameInfo.FName := 'MyThreadName';
ThreadNameInfo.FThreadID := $FFFFFFFF;
ThreadNameInfo.FFlags := 0;

try
RaiseException( $406D1388, 0, sizeof(ThreadNameInfo) div sizeof(LongWord), @ThreadNameInfo
);
except
end;
{$ENDIF}
end;

procedure TMyThread.Execute;
begin
SetName;
{ Place thread code here }
end;
2 end.
// Unit1.h

#ifndef Unit1H
#define Unit1H
#include <Classes.hpp>
class TMyThread : public TThread
{
typedef struct tagTHREADNAME_INFO
{
DWORD dwType;
LPCSTR szName;
DWORD dwThreadID;
DWORD dwFlags;
} THREADNAME_INFO;
private:
void SetName();
protected:
void __fastcall Execute();
public:
__fastcall TMyThread(bool CreateSuspended);
};

#endif
// Unit1.cpp
#include "Unit3.h"
#pragma package(smart_init)

__fastcall TMyThread::TMyThread(bool CreateSuspended)


: TThread(CreateSuspended)
{
}

128
2.5 VCL Procedures RAD Studio Handling Exceptions

void TMyThread::SetName()
{
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = "TMyThreadName";
info.dwThreadID = -1;
info.dwFlags = 0;

__try
{
RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD),(DWORD*)&info; );
}
__except (EXCEPTION_CONTINUE_EXECUTION)
{
}
}

void __fastcall TMyThread::Execute()


{
SetName();
//---- Place thread code here ----
}
See Also
VCL Overview ( see page 36)

Initializing the Thread ( see page 130)

Writing the Thread Function ( see page 134)

Writing Cleanup Code ( see page 125)

2.5.36 Handling Exceptions


To handle exceptions in the thread function
1. Add a try...except block to the implementation of your Execute method.
2. Code the logic such as shown here:
procedure TMyThreadExecute;
begin
try
while not Terminated do
PerformSomeTask;
except
{do something with exceptions}
end;
end;
void __fastcall TMyThread::Execute() {
try {
while( !Terminated() ) {
// perform tasks
}
} catch(...) { // catch specific exceptions first
// exception—handling code
}
}
See Also
VCL Overview ( see page 36)

129
Initializing a Thread RAD Studio 2.5 VCL Procedures

Writing the Thread Function ( see page 134)

Using the Main VCL Thread ( see page 131)

Avoiding Simultaneous Thread Access to the Same Memory ( see page 125)

Waiting for Threads ( see page 132)

2.5.37 Initializing a Thread


To initialize a thread object
1. Assign a default thread priority.
2. Indicate when the thread is freed.

To assign a default priority


1. Assign a default priority to the thread from the values listed in the table below. Use a high-priority to handle time critical tasks,
and a low priority to perform other tasks.

Value Priority
tpIdle The thread executes only when the system is idle. Windows won't interrupt the other threads to execute a
thread with tpIdle priority.
tpLowest The thread's priority is two points below normal.
tpLower The thread's priority is one point below normal.
2 tpNormal The thread has normal priority.
tpHigher The thread's priority is one point above normal.
tpHighest The thread's priority is two points above normal.
tpTimeCritical The thread gets highest priority.

2. Override the Create method (Delphi) or default constructor (C++) of the thread class by adding a new constructor to the
declaration.
3. Code the constructor. The following is an example for a low-priority thread:
constructor TMyThread.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
Priority := tpIdle;
end;
TMyThread::TMyThread( bool CreateSuspended ) : TThread( CreateSuspended ) {
Priority = tpIdle;
}
4. Indicate whether the thread should be freed automatically when it finishes executing.
Warning: Boosting the thread priority of a CPU intensive operation may starve other threads in the application. Only apply
priority boosts to threads that spend most of their time waiting for external events.

To indicate when a thread is freed


1. Set the FreeOnTerminate property to true, unless the thread must be coordinated with other threads.
2. If the thread requires coordination with another thread, set FreeOnTerminate to false; then explicitly free the first thread
from the second.

130
2.5 VCL Procedures RAD Studio Using the Main VCL Thread

See Also
VCL Overview ( see page 36)

Defining a Thread Object ( see page 126)

Writing the Thread Function ( see page 134)

Writing Cleanup Code ( see page 125)

2.5.38 Using the Main VCL Thread


Using the main VCL thread consists of the following basic steps:

1. Create a separate routine to handle Windows messages received by components in your application.
2. Call CheckSynchronize periodically.
3. Declare thread-local variables, as necessary, for exclusive use by your thread.

To create a separate routine


1. Write a main thread routine that handles accessing object properties and executing object methods for all objects in your
application.
2. Call the routine using the TThread.Synchronize (Delphi) or TThread::Synchronize method. The following code is an
example of how to call a method using Synchronize
procedure TMyThread.PushTheButton
begin
Button1.Click;
2
end;
procedure TMyThread.Execute;
begin
...
Synchronize(PushThebutton);
...
end;
void TMyThread::PushTheButton() { Form1–>Button1–>Click(); }
void __fastcall TMyThread::Execute() {
...
Synchronize( (TThreadMethod)&PushTheButton );
...
}
Synchronize waits for the main thread to enter the message loop and then executes the passed method.

Note: Because Synchronize uses a message loop, it does not work in console applications. For console applications, use
other mechanisms, such as critical sections, to protect access to VCL objects.

To call CheckSynchronize
1. Call CheckSynchronize periodically within the main thread to enable background threads to synchronize execution with the
main thread.
2. To ensure the safety of making background thread calls, call CheckSynchronize when the application is idle, for example,
from an OnIdle event handler.

To use a thread-local variable


1. Identify variables that you want to make global to all the routines running in your thread but not shared by other instances of
the same thread class.

131
Waiting for Threads RAD Studio 2.5 VCL Procedures

2. For Delphi, declare these variables in a threadvar section, for example,


threadvar
x: integer;
For C++, declare these variables with the __thread modifier:
int __thread x;
Note: Use the threadvar

section for global variables only. Do not use it for Pointer and Function variables or types that use copy-on-write semantics,
such as long strings.

Note: For C++, if you initialize a __thread

variable, you must initialize it to a constant expression. For example, int __thread foo = 3; is a legal statement, but int
__thread foo = get_value(); is not permitted because the initialization occurs at runtime.

See Also
VCL Overview ( see page 36)

Writing the Thread Function ( see page 134)

Avoiding Simultaneous Thread Access to the Same Memory ( see page 125)

Waiting for Threads ( see page 132)

Handling Exceptions ( see page 129)

2 2.5.39 Waiting for Threads


The following are procedures that can be used to wait for threads.

• Wait for a thread to finish executing.


• Wait for a task to complete.
• Check if another thread is waiting for your thread to terminate.

To wait for a thread to finish executing


1. Use the WaitFor method of the other thread.
2. Code your logic. For example, the following code waits for another thread to fill a thread list object before accessing the
objects in the list:
if ListFillingThread.WaitFor then
begin
with ThreadList1.LockList do
begin
for I := 0 to Count - 1 do
ProcessItem(Items[I];
end;
ThreadList1.UnlockList;
end;
if( ListFillingThread->WaitFor() ) {
TList* list = ThreadList1–>LockList();
for( int i = 0; i < list->Count; i++ ) {
DoSomething( list->Items[i] );
}
ThreadList1–>UnlockList();
}

132
2.5 VCL Procedures RAD Studio Waiting for Threads

To wait for a task to complete


1. Create a TEvent object of global scope.
2. When a thread completes an operation other threads are waiting for, have the thread call TEvent.SetEvent.
3. To turn off the signal, call TEvent.ResetEvent.
The following example is an OnTerminate event handler that uses a global counter in a critical section to keep track of the
number of terminating threads. When Counter reaches 0, the handler calls the SetEvent method to signal that all
processes have terminated:
procedure TDataModule.TaskTerminateThread(Sender: TObject);
begin
...
CounterGuard.Acquire; {obtain a lock on the counter}
Dec(Counter); {decrement the global counter variable}
if Counter = 0 then
Event1.SetEvent; {signal if this is the last thread}
Counter.Release; {release the lock on the counter}
...
end;
void __fastcall TDataModule::TaskThreadTerminate( TObject *Sender ) {
...
CounterGuard->Acquire(); // lock the counter
if( ––Counter == 0 ) // decrement counter
Event1–>SetEvent(); // signal if this is the last thread
CounterGuard->Release(); // release lock
}
The main thread initializes Counter, launches the task threads, and waits for the signal that they are all done by calling the
TEvent::WaitFor method. WaitFor waits a specified time period for the signal to be set and returns one of the values in the
table below.
2
The following code example shows how the main thread launches the task threads and resumes when they have completed.
Event1.ResetEvent; {clear the event before launching the threads}
for i := 1 to Counter do
TaskThread.Create(False); {create and launch the task threads}
if Event1.WaitFor(20000) <> wrSignaled then
raise Exception;
{continue with main thread}
Event1–>ResetEvent(); // clear the event before launching threads
for( int i = 0; i < Counter; i++ ) {
new TaskThread( false );
if( Event1–>WaitFor(20000) != wrSignaled )
throw Exception;
// now continue with the main thread
Note: If you do not want to stop waiting for an event handler after a specified time period, pass the WaitFor method a
parameter value of INFINITE. Be careful when using INFINITE, because your thread will hang if the anticipated signal is never
received.

To check if another thread is waiting on your thread to terminate


1. In your Execute procedure, implement the Terminate method by checking and responding to the Terminated property.
2. This is one way to code the logic:
procedure TMyThread.Execute;
begin
while not Terminated do
PerformSomeTask;
end;
void __fastcall TMyThread::Execute() {
while( !Terminated )

133
Placing A Bitmap Image in a Control in a RAD Studio 2.5 VCL Procedures

DoSomething();
}
WaitFor return values

Value Meaning
wrSignaled The signal of the event was set.
wrTimeout The specified time elapsed without the signal being set.
wrAbandoned The event object was destroyed before the timeout period elapsed.
wrError An error occurred while waiting.

See Also
VCL Overview ( see page 36)

Writing the Thread Function ( see page 134)

Using the Main VCL Thread ( see page 131)

Avoiding Simultaneous Thread Access to the Same Memory ( see page 125)

Handling Exceptions ( see page 129)

2.5.40 Writing the Thread Function (Procedure)


The Execute method is your thread function. You can think of it as a program that is launched by your application, except that it
2 shares the same process space. Writing the thread function is a little trickier than writing a separate program, because you must
make sure that you do not overwrite memory that is used by other processes in your application. On the other hand, because the
thread shares the same process space with other threads, you can use the shared memory to communicate between threads.

To implement Execute, coordinate thread execution by


1. Synchronizing with a main VCL thread.
2. Avoiding simultaneous access to the same memory.
3. Waiting for threads.
4. Handling exceptions.
See Also
VCL Overview ( see page 36)

Using the Main VCL Thread ( see page 131)

Avoiding Simultaneous Thread Access to the Same Memory ( see page 125)

Waiting for Threads ( see page 132)

Handling Exceptions ( see page 129)

134
2.5 VCL Procedures RAD Studio Placing A Bitmap Image in a Control in a

2.5.41 Placing A Bitmap Image in a Control in a VCL Forms


Application
This procedure adds a bitmap image to a combo box in a VCL forms application.

1. Create a VCL form.


2. Place components on the form.
3. Set component properties in the Object Inspector.
4. Write event handlers for the component's drawing action.
5. Build and run the application.

To create a VCL form with a TComboBox component


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.
2. From the Win32 page of the Tool Palette, place an TImageList component on the form.
3. From the Standard page of the Tool Palette, place a TComboBox on the form.

To set the component properties


1. Select ComboBox1 in the form.
2. In the Object Inspector, set the Style property drop-down to csOwnerDrawFixed.
2
3. In the Object Inspector, click the ellipsis next to the Items property. The String List Editor displays.
4. Enter a string you would like to associate with the bitmap image, for example, MyImage; then click OK.
5. Double-click ImageList1 in the form. The ImageList editor displays.
6. Click the Add button to display the Add Images dialog.
7. Locate a bitmap image to display in the Combo box. To locate an image, you can search for *.bmp images on your local drive.
Select a very small image such as an icon. Copy it to your project directory, and click Open. The image displays in the
ImageList editor.
8. Click OK to close the editor.

To add the event handler code


1. In the VCL form view, select ComboBox1.
2. In the Object Inspector, click the Events page, and double-click the OnDrawItem event. The Code Editor displays with cursor
in the code block of the ComboBox1DrawItem (Delphi) or ComboBox1::DrawItem (C++) event handler.
3. Enter the following code for the event handler:
Combobox1.Canvas.FillRect(Rect);
ImageList1.Draw(ComboBox1.Canvas, Rect.Left, Rect.Top, Index);
Combobox1.Canvas.TextOut(Rect.Left+ImageList1.Width+2,
Rect.Top, ComboBox1.Items[Index]);
ComboBox1–>Canvas->FillRect( Rect );
ImageList1–>Draw( ComboBox1–>Canvas, Rect.Left, Rect.Top, Index );
ComboBox1–>Canvas->TextOut( Rect.Left + ImageList1–>Width + 2,
Rect.Top,
ComboBox1–>Items[Index] );

135
Renaming Files RAD Studio 2.5 VCL Procedures

To run the program


1. Choose Run Run. The applications executes, displaying a form with a combo box.
2. Click the combo box drop-down. The bitmap image and the text string display as a list item.
See Also
VCL Overview ( see page 36)

Building VCL Forms Applications With Graphics ( see page 93)

2.5.42 Reading a String and Writing It To a File


Creating this VCL application consists of the following steps:

1. Create a VCL Form with a button control.


2. Write the code to read the string and write it to a file.
3. Run the application.

To create a VCL Form


1. Create a directory in which to store your project files.
2. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.

2 3. From the Standard page of the Tool palette, place a TButton component on the form.

To read and write a string


1. Select Button1 on the form.
2. In the Object Inspector, double-click the OnClick action on the Events tab. The Code Editor displays, with the cursor in the
TForm1.Button1Click (Delphi) or TForm1::Button1Click (C++) event handler block.
3. For Delphi. place the cursor before the begin reserved word; then press return. This creates a new line above the code
block.
4. Type the following variable declarations:
TFileStream *fs const AnsiString str = "Hello";
5. Insert the cursor within the code block, and type the following code:
fs = new TFileStream("temp.txt", fmCreate);
fs->Write ((void*)str.c_str(), str.fmCreate);

To run the "Hello world" application


1. Save your project files; then choose Run Run to build and run the application. The form displays with a button called
Button1.
2. Click Button1.
3. Use a text editor to open the newly created file temp.txt, which is located in your project directory. The string 'Hello' displays in
the file.
See Also
VCL Overview ( see page 36)

Building a VCL Forms Application ( see page 99)

136
2.5 VCL Procedures RAD Studio Adding and Sorting Strings

2.5.43 Renaming Files


Creating this VCL application consists of the following steps:

1. Create a project directory containing a file to rename.


2. Create a VCL Form with button and label controls.
3. Write the code to rename the file.
4. Run the application.

To set up your project directory and a text file to copy


1. Create a directory in which to store your project files.
2. Either create or copy a text file to your project directory; then save it as MyFile.txt.

To create a VCL Form with a button and label


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.
2. From the Standard page of the Tool palette, place a TButton component on the form.
3. From the Standard page of the Tool palette, place a TLabel component on the form.

To write the rename file procedure


1. Select Button1 on the form.
2
2. In the Object Inspector, double-click the OnClick action on the Events tab. The Code Editor displays, with the cursor in the
TForm1.Button1Click (Delphi) or TForm1::Button1Click (C++) event handler block.
3. At the cursor, type the following code:
if not RenameFile('MyFile.txt', 'YourFile.txt') then
Label1.Caption := 'Error renaming file!';
if( !RenameFile( "..\\MyFile.txt", "..\\YourFile.txt" )
Label1–>Caption = “Error renaming file”;
// the file parameters assume the target output directory is in your project directory
Note: You cannot rename (move) a file across drives using RenameFile. You would need to first copy the file and then delete
the old one. In the runtime library, RenameFile is a wrapper around the Windows API MoveFile function, so MoveFile will not
work across drives either.

To run the application


1. Save your project file; then choose Run Run to build and run the application. The form displays.
2. Click the button; If no message displays in the Label, check the file name in your project directory. MyFile.txt should is
renamed as YourFile.txt.
3. If the caption label displays the error message, recheck your event handler code.
See Also
VCL Overview ( see page 36)

Building a VCL Forms Application ( see page 99)

137
Adding and Sorting Strings RAD Studio 2.5 VCL Procedures

2.5.44 Adding and Sorting Strings


Creating this VCL application consists of the following steps:

1. Create a VCL Form with Button, Label, and TListBox controls.


2. Write the code to add and sort strings.
3. Run the application.

To create a VCL Form with Button, Label, and ListBox controls


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer displays.
2. From the Standard category of the Tool Palette, place a TButton, TLabel, and TListBox component on the form.

To write the copy stream procedure


1. Select Button1 on the form.
2. In the Object Inspector, double-click the OnClick action on the Events tab. The Code Editor displays, with the cursor in the
TForm1.Button1Click event handler block.
3. For Delphi, place the cursor before the begin reserved word and press ENTER. This creates a new line above the code block.
4. Type the following variable declarations:
var
MyList: TStringList;
2 Index: Integer;
TStringList *MyList;
int Index;
5. Insert the cursor within the code block, and type the following code:
MyList := TStringList.Create;
try
MyList.Add('Animals');
MyList.Add('Flowers');

MyList.Add('Cars');

MyList.Sort;
if MyList.Find('Flowers', Index) then
begin
ListBox1.Items.AddStrings(MyList);
Label1.Caption := 'Flowers has an index value of ' + IntToStr(Index);
end;
finally
MyList.Free;
end;
MyList = new TStringList();
try {
MyList->Add( "Animals" );
MyList->Add( "Flowers" );
MyList->Add( "Cars" );
MyList->Sort();
if( MyList->Find( "Flowers", Index ) {
ListBox1–>Items->AddStrings( MyList );
Label1–>Caption = "Flowers has an index of " +
IntToStr( Index );
}
} __finally {

138
2.5 VCL Procedures RAD Studio Creating a VCL Forms ActiveX Button

MyList->Free();
}
Note: Find will only work on sorted lists. Use IndexOf on unsorted lists.

To run the application


1. Save your project files; then choose Run Run to build and run the application. The form displays with the controls.
2. Click the Button. The strings 'Animals', 'Cars', and 'Flowers' display alphabetically in a list in the ListBox. The Label caption
displays the message string: 'Flowers has an index value of 2.'
See Also
VCL Overview ( see page 36)

2.5.45 Creating a VCL Forms ActiveX Button


Like a Delphi control, an ActiveX control generates program code when you place the component on a form or other logical
container in the IDE. The main difference between an ActiveX control and a Delphi control is that an ActiveX control is language
independent. You can create ActiveX controls for deployment to a variety of programming environments on Windows, not just
Delphi or C++Builder.

This procedure uses the VCL forms ActiveX wizard to create an ActiveX control. To test the control, you can install it on your
machine as a VCL component in the IDE. To install the control, you first need to create a package for it. This procedure consists
of the following major steps:

Metaprocedure for Creating a VCL Forms ActiveX Button


2
1. Create an ActiveX library project for an ActiveX button control.
2. Register the ActiveX button so its icon can be displayed in the toolbar.
3. Create a package for the ActiveX button.
4. Install the package.
5. Test the ActiveX button.

To create an ActiveX library project for an ActiveX button control


1. Create a directory on your local drive for the ActiveX project. Give it a name that you can find easily, for example, ActiveX.
2. Choose File New Other and select the ActiveX page in the New Items dialog box.
3. In the ActiveX folder, double-click ActiveX Library. This creates a Dynamic Link Library [DLL] project that you can use to
host in-process ActiveX Objects.
4. Choose File New Other again.
5. On the ActiveX page, double-click ActiveX Control. The ActiveX Control Wizard displays.
6. In the Component Name drop-down, select TButton.
7. By default, ButtonX displays as the New ActiveX Name. Rename ButtonX to the name you want displayed for your ActiveX
button, for example, MyActiveXButton.
Note: Modifications you make to the name update the Implementation Unit and Project Name. Leave the remaining fields
with default values.

8. Click OK. The wizard generates the code needed to implement the ActiveX control and adds the code to the project. If the
project is already an ActiveX library, the wizard adds the control to the current project.

139
Creating a VCL Forms ActiveX Active Form RAD Studio 2.5 VCL Procedures

Note: If the project is not already an ActiveX library, a Warning


dialog displays and asks you if you want to start a new ActiveX library project.
9. Click OK to start the new ActiveX Library project.

To register the ActiveX button


1. Build the project and save all files to your ActiveX project directory. Dismiss the warning about debugging. The project builds
and creates an OCX file in your project directory.
2. Choose Run Register ActiveX Server to register the ActiveX button. A dialog box displays a message indicating that
registration was successful and it shows the path to the resulting OCX file.
3. Click OK.

To create a new package for the ActiveX button


1. Choose File New Other to create a new package. The New Items dialog displays.
2. Double-click Package on the New page to display the Package - package.dpk dialog and click Add.
3. On the Add unit tab of the Add dialog, browse to your project directory.
4. Select the ButtonXControl1_TLB.pas file, and click Open.
5. Click OK to add the file to the package and return to the Package - package.dpk dialog. The Package - package.dpk dialog
displays showing the files in the package and two required files: rtl.dcp and vcl.dcp.

To add the required files and install the package


1. In the Package - package.dpk dialog, select rtl.dcp, and click Add.
2. On the Add unit tab of the Add dialog, browse to the Lib directory in Delphi, select the rtl.dcp file, and click Open; then click
OK on the Add dialog.
2
3. In the Package - package.dpk dialog, select vcl.dcp, and click Add.
4. On the Add unit tab of the Add dialog, browse to the Lib directory in Delphi, select the vcl.dcp file, and click Open; then click
OK on the Add dialog.
5. In the Package - package.dpk dialog, click Compile to compile the package. A dialog displays, indicating that the package
has been installed. Click OK.
6. Click the X in the upper right corner of the Package - package.dpk dialog to close it. You are prompted to save the package.
7. Save the package to your projects directory.

To test the button


1. Choose File New Application.
2. From the ActiveX page of the Tool Palette, locate your button and place it on the form. The button displays on the form.
See Also
VCL Overview ( see page 36)

Creating a VCL Forms ActiveX Active Form ( see page 140)

2.5.46 Creating a VCL Forms ActiveX Active Form


Like a Delphi control, an ActiveX control generates program code when you place the component on a form or other logical
container in the IDE. The main difference between an ActiveX control and a Delphi control is that an ActiveX control is language
independent. You can create ActiveX controls for deployment to a variety of programming environments on Windows, not just

140
2.5 VCL Procedures RAD Studio Building a VCL Forms Web Browser

Delphi or C++Builder, for example.

This procedure uses the VCL forms ActiveX Active Form wizard to create an Active Form containing two components. To test
the control, you can deploy it to the Web. This procedure consists of the following major steps:

1. Create an ActiveX library project for an ActiveX Active Form.


2. Add controls to the Active Form.
3. Add event handling code for the controls.
4. Deploy the project to the Web.
5. Display the form and test the controls in your Web browser.

To create an Active X library project for an ActiveX Active Form


1. Create a directory on your local drive for the ActiveX project. Give it an easy to find name, for example, ActiveX.
2. Create a second directory to contain the ActiveX component and an HTML file for deploying the Active Form to your Microsoft
Internet Explorer Web browser. Name this directory ActiveX_Deploy.
3. Choose File New Other and select the ActiveX page in the New Items dialog.
4. On the ActiveX page, double-click Active Form. The Active Form Wizard displays.
5. Accept the default settings and click OK. The wizard generates the code needed to implement the ActiveX control and adds
the code to the project. If the project is already an ActiveX library, the wizard adds the control to the current project.
Note: If the project is not already an ActiveX library, a Warning
dialog displays and asks you if you want to start a new ActiveX library project.
6. Click OK to start a new ActiveX library project. An ActiveX Active Form displays.

To add some functionality to the Active Form 2


1. From the Standard page of the Tool Palette, add TEdit and TButton components to the form.
2. Select the button.
3. On the Events tab in the Object Inspector, double-click the OnClick event. The Code Editor opens with the cursor in place
in the TActiveFormX.Button1Click (Delphi) or TActiveFormX::Button1Click() (C++) event handler block. Enter
the following code at the cursor:
ShowMessage(Edit1.text);
ShowMessage( Edit1–>Text )
4. Save the project files to your ActiveX directory.
Note: To deploy the Active form to your Web, use the Deployment Manager
. Click File New Other Deployment.

To test the Active Form


1. Launch your browser.
2. Choose File Open, and browse to the ActiveX_Deploy directory.
3. Double-click the HTML file to launch it in the browser window. The Active Form displays in the browser window.
4. Click the button. A pop-up dialog displays the text in the Edit box.
5. Change the text, and click the button again. The new text you entered displays in the pop-up.
See Also
VCL Overview ( see page 36)

Creating a VCL Forms ActiveX Button ( see page 139)

141
Creating an Application that Uses Ribbon RAD Studio 2.5 VCL Procedures

2.5.47 Building a VCL Forms Web Browser Application


Creating the Web browser application consists of the following steps:

1. Create a VCL Form with a button control.


2. Add a TWebBrowser component to the form.
3. Add controls to enter a URL and launch the browser.
4. Write the code to launch the browser when a button is clicked.
5. Run the application.

To create a VCL Form


1. Choose File New Other Delphi Projects or C++Builder Projects and double-click the VCL Forms Application icon. The
VCL Forms Designer is displayed.
2. From the Internet page of the Tool Palette, place a TWebBrowser component on the form.
3. With the TWebBrowser component selected on the form, drag the handles to adjust the size of the browser window. Leave
some space on the form above the TWebBrowser to add a URL entry window. If the window is not large enough to display a
browser page in its entirety, the TWebBrowser component adds scrollbars when you run the application and launch the
browser window.
4. From the Standard page of the Tool Palette, place a TMemo component on the form. With the TMemo component selected
on the form, drag the handles to adjust the size to accommodate a user-entered URL.
5. From the Standard page of the Tool Palette, place a Label component on the form.
2 6. Select the Label, and in the Object Inspector, enter URL: as the Label caption.
7. From the Standard page of the Tool Palette, place a TButton component on the form.
8. Select the Button, and in the Object Inspector, enter OK as the TButton caption.

To code a button click event that launches the browser


1. Select Button1 on the form.
2. In the Object Inspector, double-click the OnClick action on the Events tab. The Code Editor displays, with the cursor in the
Button1Click event handler block.
3. Type the following code:
WebBrowser1.Navigate(WideString(Memo1.Text));
WebBrowser1–>Navigate( WideString( Memo1–>Text ) );

To run the application


1. Choose Run Run to build and run the application.
2. Enter a URL to a Web page in the memo window; then click the button. The browser launches in the TWebBrowser window.
See Also
VCL Overview ( see page 36)

Building a VCL Forms Application ( see page 99)

142
2.5 VCL Procedures RAD Studio Adding Commands to the Ribbon

2.5.48 Creating an Application that Uses Ribbon Controls


This procedure describes how to create an application that uses ribbon controls. The core ribbon functionality is derived from the
TRibbon component. While the ribbon uses other components, none of the core components are registered on the tool palette.

Components:

1. TRibbon: Main visual component that provides most functionality.


2. TRibbonApplicationMenuBar: Component that provides the functionality of the application menu.
3. TRibbonQuickAccessToolbar: Component that provides the functionality of the Quick Access Toolbar
4. TRibbonPage: Component that represents the page of the ribbon that is currently visible
5. TRibbonGroup: Component that all of the pages commands are displayed in. Commands must be placed in a group.

To create a new application that uses ribbon controls


1. Create a new Delphi Win32 VCL application (select New VCL Forms Application — Delphi for Win32).
2. Drop a TActionManager component onto the form.
3. Drop a TRibbon component onto the form.
4. Right-click the TRibbon component and select the Add Application Menu item.
5. Right-click the TRibbon component again and select the Add Quick Access Toolbar item.
Note: During initial configuring of the ribbon you might see a dialog saying that the current style selected in the
TActionManager.Style is not a valid ribbon style. Change the TRibbonManager.Style property to be the Ribbon – Luna. 2
Applicable styles for use with the ribbon have the Ribbon prefix. By default three ribbon styles are implemented. These ribbon
styles also work with the default ActionManager toolbar and menu bar controls. The available ribbon Styles are:
• Luna
• Obsidian
• Silver
See Also
VCL Overview ( see page 36)

Adding Commands to the Ribbon ( see page 144)

TRibbon

TRibbon

TRibbonApplicationMenuBar

Caption

TRibbonQuickAccessToolbar

TRibbonPage

TRibbonGroup

143
Adding Commands to the Ribbon RAD Studio 2.5 VCL Procedures

2.5.49 Adding Commands to the Ribbon


This topic follows in sequence the creation of a ribbon application using either the Ribbon Application Wizard or the manual
steps described in Creating an Application that Uses Ribbon Controls ( see page 143).

This topic assumes that you are familiar with the TActionManager component and the components associated with its use.
Numerous new properties have been added to help support the ribbon requirements. Many existing properties have no effect
when modified on a command that is displayed on the ribbon.

For instance:

• Small buttons always display their glyph to the left of the caption.
• Large buttons always display their glyph at the top.
• A Large button must have a caption. The caption can be a maximum of two lines, and the button width is resized accordingly.
A large button's height is fixed to cover the height of the group where the command is displayed.
• Only small buttons with no caption can be displayed in groups.
New Properties
CommandStyle: The CommandStyle determines the type of control that is used to represent this command on the ribbon. The
default style is csButton. CommandStyle is used extensively for determining the control type that is used for the command
except under one exception.
type TCommandStyle = (csButton, csMenu, csSeparator, csText, csGallery, csComboBox, csControl,
csCustom);
2
Style of the Command on the Ribbon Group

csButton Command is a button.


csComboBox Command displays an Office 2007 style combobox. See following Note.
csControl Command has a TControl descendant associated with it. An example is dropping a TEdit component
onto a ribbon Group.
csCustom User-defined.
csGallery Command is a gallery or when selected, it displays a gallery.
csMenu Command is a menu item
csSeparator Command is a separator with a text description.
csText Command only displays text and has no associated control.

Note: You can only use the csComboBox CommandStyle if you first place a TRibbonComboBox from the tool palette onto your
ribbon Group.

CommandProperties: CommandProperties is a dynamic property class. The published properties of this property (it is a
TPersistent descendant) vary depending on the CommandStyle that has been selected. If you select the csButton
CommandStyle, the CommandProperties class used is called TButtonProperties. This property class publishes properties that
are specific to the csButton CommandStyle.

An example is ButtonSize, which allows you to indicate if the button is a large button or a small button. There is no need for a
csMenu command to have a ButtonSize property because the menu does not react to a size variance.

All CommandProperties classes descend from TCommandProperties. If you are using the csCustom CommandStyle, you must
descend from the TCommandProperties class.

144
2.5 VCL Procedures RAD Studio Adding Commands to the Ribbon

Properties that can be available in the CommandProperties property depending on your selected CommandStyle

csButton ButtonSize
Size of the button:
TButtonSize = (bsSmall, bsLarge);
ButtonType
Special types of buttons allowed:
TButtonType = (btNone, btDropDown, btSplit, btGallery); // btNone - normal
button // btDropdown - button display a dropdown menu // btSplit - button has
dropdown menu and a default action // btGallery - button displays a gallery as a
dropdown
GroupPosition
Position of this command in a group of commands:
TGroupPosition = (gpNone, gpStart, gpMiddle, gpEnd, gpSingle); // Determines
whether a border is drawn around a button // gpNone - no border drawn // gpStart
- the right edge of a border isn't drawn // gpMiddle - top and bottom of border
is drawn // gpEnd - the left edge isn't drawn // gpSingle - the full border is
drawn
csCheckBox Command appears like an Office 2007 checkbox.
csComboBox AllowResize Controls whether the popup menu associated with the combo box can be resized:
TGalleryResize = (grNone, grVertical, grBoth); // grNone – don’t allow resizing
// grVertical – only allow vertical resizing // grBoth – allow both vertical and
horizontal resizing
Items
Items to display when the user selects the dropdown button. These items display in a window like a regular
combobox.
Text
The text to display in the combobox. 2
Width
The width of the spinner control, excluding any caption width.
csControl ContainedControl Reference to the control it is associated with on the ribbon.
csCustom User-defined.
csGallery The csGallery CommandProperties class descends from the csButton CommandProperties class.
This means all of the csButton properties are also available for csGallery commands, as well as the
following gallery ones.
GalleryType
Type of gallery to be displayed:
TGalleryType = (gtDropDown, gtGrid, gtRibbon); // gtDropDown - Gallery is in the
form of a dropdown menu // gtGrid - Gallery is a grid layout. Meaning it can be
more than one item across. ItemsPerRow controls the number of items across //
gtRibbon - Gallery is in Ribbon
ItemsPerRow
Number of items to display on a row.
ShowRichContent
Set to true to display rich content for the gallery items.
csMenu ShowRichContent: Set to true to display rich content for the menu item.
Content: The content to be displayed as rich content.
Font: Use a custom font when displaying the rich content. Rich content menu items are limited to two lines.
Depending on the content, the menu items might be wider and are not changed to be taller, and some menu
items therefore display additional lines (beyond the two permitted.)
csRadioButton Command appears like an Office 2007 radio button.

145
Adding Commands to the Ribbon RAD Studio 2.5 VCL Procedures

csSeparator csText and csSeparator share the same CommandProps class, so the available properties are the same.
Alignment: The alignment of the caption text.
EllipsisPosition: Position of any ellipsis if caption text is too wide for the menu width. It is only possible
for menu items to be displayed in the Application menu.
Font: Font to use when drawing the caption text.
Width: Force the width of the created control to be a specific size. Leave as -1 for csSeparator
CommandStyle and modify as required for csText CommandStyle.
csText csText and csSeparator share the same CommandProps class, so the available properties are the same.

Additional Ribbon Component Properties

KeyTip: The key that can be pressed to activate the command when using the keyboard. To activate KeyTips, press either the
Alt or F10 key.

NewCol: Setting NewCol for a command forces the control to be displayed in a new column of the ribbon group. This property is
only effective when the ribbon group alignment is gaVertical.
NewRow: Setting NewRow for a command forces the control to be displayed in a new row of the ribbon group. This property is
only effective when the ribbon group alignment is gaHorizontal.
Default: Set to true to force a menu items caption to be bolded. Only effective for menu items.

See Also
VCL Overview ( see page 36)

Building VCL Forms Applications With Graphics ( see page 93)

Creating an Application that Uses Ribbon Controls ( see page 143)


2

146
2.6 WebSnap Procedures RAD Studio Building a WebSnap Application

2.6 WebSnap Procedures


This section provides how-to information on developing WebSnap applications.

Please note that WebSnap is being deprecated in RAD Studio. Although WebSnap is still documented in the online help, the
WebSnap product is no longer fully supported. As an alternative, you should begin using IntraWeb (VCL for the Web). IntraWeb
( see page 2254) is documented in this online help. For more documentation on VCL for the Web, go to
http://www.atozed.com/intraweb/docs/.

Topics
Name Description
Building a WebSnap Application ( see page 148) The following procedure describes the generic steps required to build a simple
WebSnap project. For more advanced topics, refer to related information
following the procedure.
Building a WebSnap application consists of five major steps:

1. Create an WebSnap project.


2. Change included components (optional).
3. Set page options (optional)
4. Create additional WebSnap pages.
5. Run the application.
Note: WebSnap is being deprecated in RAD Studio.
Although WebSnap is still documented in the online help, 2
the WebSnap product is no longer fully supported. As an
alternative, you should begin using IntraWeb (VCL for the
Web). IntraWeb ( see page 2254) is documented in this
online help. For more documentation... more ( see page
148)
Building a WebSnap "Hello World" Application ( see page 149) Though simple, the WebSnap "Hello world" application demonstrates the
essential steps for creating an WebSnap application.
Building the WebSnap "Hello world" application consists of five major steps:

1. Create a WebSnap project.


2. Accept the default included components.
3. Set the page title in the page options.
4. Modify the HTML template.
5. Run the application.
Debugging a WebSnap Application using the Web Application Debugger ( see This topic describes the essential tasks for debugging a WebSnap application
page 150) using the Web Application Debugger.
Using the HTML Tag Editor ( see page 151) When you are creating or editing an HTML file, you can use the Tag Editor
window, beneath the Form Designer, to edit the HTML tags. If you are using an
HTML Form, you can display the Tag Editor in the Designer by selecting
View Tag Editor.
The Tag Editor lets you review and modify HTML tags while viewing the
corresponding controls in the Designer window, above it. The Tag Editor allows
you to use the Code Completion, Error Insight, and Live Template
Completion features that are also available in the Code Editor. Refer to the
links... more ( see page 151)

147
Building a WebSnap Application RAD Studio 2.6 WebSnap Procedures

2.6.1 Building a WebSnap Application


The following procedure describes the generic steps required to build a simple WebSnap project. For more advanced topics,
refer to related information following the procedure.

Building a WebSnap application consists of five major steps:

1. Create an WebSnap project.


2. Change included components (optional).
3. Set page options (optional)
4. Create additional WebSnap pages.
5. Run the application.
Note: WebSnap is being deprecated in RAD Studio. Although WebSnap is still documented in the online help, the WebSnap
product is no longer fully supported. As an alternative, you should begin using IntraWeb (VCL for the Web). IntraWeb ( see
page 2254) is documented in this online help. For more documentation on VCL for the Web, go to
http://www.atozed.com/intraweb/docs/.

To create a WebSnap project


1. Choose File New Other. The New Items dialog appears.
2. In the New Items dialog, select WebSnap Application from the Delphi Projects WebSnap folder.
3. Click OK. The New WebSnap Application dialog appears.
2 4. Select the type of application you are creating.
5. Select your application model components.
6. In the Page Name field, enter the name of your page.
7. Select your caching type from the Caching drop-down.

To change included components (optional)


1. In the New WebSnap Application dialog, click Components. The WebApp Components dialog appears.
2. Select the components you want to include.
Tip: In most cases, the default settings will suffice.

3. Click OK.

To set page options (optional)


1. In the New WebSnap Application dialog, click Page Options. The WebApp Components dialog appears.
2. Set the page options.

To create additional WebSnap pages


1. In the New Items dialog, select WebSnap Page Module from the Delphi Projects WebSnap folder.
2. Configure the page module options and click OK.
3. Add and configure components.
See Also
Web Applications Overview ( see page 41)

148
2.6 WebSnap Procedures RAD Studio Building a WebSnap "Hello World"

Building an WebSnap "Hello world" Application ( see page 149)

2.6.2 Building a WebSnap "Hello World" Application


Though simple, the WebSnap "Hello world" application demonstrates the essential steps for creating an WebSnap application.

Building the WebSnap "Hello world" application consists of five major steps:

1. Create a WebSnap project.


2. Accept the default included components.
3. Set the page title in the page options.
4. Modify the HTML template.
5. Run the application.

To create a WebSnap project


1. Choose File New Other. The New Items dialog appears.
2. In the New Items dialog, select WebSnap Application from the Delphi Projects WebSnap or C++Builder
Projects WebSnap folder.
3. Click OK. The New WebSnap Application dialog appears.
4. Select the Web App Debugger executable radio button.
5. In the Class Name field, enter HelloWorld.
6. Select your application model components. 2
7. In the Page Name field, enter HelloWorld.
8. Select your caching type from the Caching drop-down.

To change included components (optional)


1. In the New WebSnap Application dialog, click Components. The WebApp Components dialog appears.
2. Select the components you want to include.
Tip: In most cases, the default settings will suffice.

3. Click OK.

To set the page title in the page options


1. In the New WebSnap Application dialog, click Page Options. The WebApp Components dialog appears.
2. In the Title field, enter Hello World!.

To modify the HTML template


1. Click on the HTML tab in the IDE.
2. Below the line <h2><%= Page.Title %></h2>, insert a line saying This is my first WebSnap application.
3. Save the application.

To run the "Hello world" application


1. Choose Run Run. An application window opens, and the COM server registers your WebSnap application with the Web
Application Debugger.

149
Debugging a WebSnap Application using RAD Studio 2.6 WebSnap Procedures

2. Close the application window.


3. Choose Tools Web App Debugger . The Web Application Debugger launches.
4. In the Web App Debugger, click the Start button.
5. Click on the Default URL to launch the browser.
6. In the browser, select your Hello World application from the list of applications and click Go. Your application appears in the
browser with the text Hello World! This is my first WebSnap application.
7. Close the Web browser to return to the IDE.
Note: WebSnap is being deprecated in RAD Studio. Although WebSnap is still documented in the online help, the WebSnap
product is no longer fully supported. As an alternative, you should begin using IntraWeb (VCL for the Web). IntraWeb ( see
page 2254) is documented in this online help. For more documentation on VCL for the Web, go to
http://www.atozed.com/intraweb/docs/.
See Also
Web Applications Overview ( see page 41)

Building a WebSnap Application ( see page 148)

2.6.3 Debugging a WebSnap Application using the Web


Application Debugger
This topic describes the essential tasks for debugging a WebSnap application using the Web Application Debugger.

2 To debug a WebSnap Application using the Web Application Debugger


1. Register the server information application for the Web Application Debugger.
2. Register your WebSnap application with the Web Application Debugger the first time you run it.
3. Launch the Web Application Debugger.
4. Select and launch your web application.
5. Debug your web application using breakpoints and the Web Application Debugger log.

To register the server information application for the Web Application Debugger
1. Navigate to the bin directory of your RAD Studio installation.
2. Run serverinfo.exe.
3. Close the blank application window that opens.
This step only needs to be performed the first time you use the Web Application Debugger.

To register your web application with the Debugger


1. Choose Run Run. This displays the console window of the COM server that is your Web server application.
2. Close the blank application window that opens.
Your COM server is now registered so that the Web App debugger can access it.

To launch the Web Application Debugger


1. Choose Tools Web App Debugger . The Web Application Debugger launches.
2. In the Web App Debugger, click the Start button.
3. Click on the Default URL to launch the browser.

150
2.6 WebSnap Procedures RAD Studio Using the HTML Tag Editor

To select and launch your web application


1. In the browser, select your application from the list of applications.
2. Click Go. Your application appears in the browser.
Note: WebSnap is being deprecated in RAD Studio. Although WebSnap is still documented in the online help, the WebSnap
product is no longer fully supported. As an alternative, you should begin using IntraWeb (VCL for the Web). IntraWeb ( see
page 2254) is documented in this online help. For more documentation on VCL for the Web, go to
http://www.atozed.com/intraweb/docs/.
See Also
Web Applications Overview ( see page 41)

Building an WebSnap Application ( see page 148)

2.6.4 Using the HTML Tag Editor


When you are creating or editing an HTML file, you can use the Tag Editor window, beneath the Form Designer, to edit the
HTML tags. If you are using an HTML Form, you can display the Tag Editor in the Designer by selecting View Tag Editor.

The Tag Editor lets you review and modify HTML tags while viewing the corresponding controls in the Designer window, above
it. The Tag Editor allows you to use the Code Completion, Error Insight, and Live Template Completion features that are
also available in the Code Editor. Refer to the links at the end of this topic for more information about using each of these
features.

The Tag Editor works with one tag at a time, unless you have the Document object selected or you have zoomed out from a tag. 2
(When the document object is selected, you'll see the item "DOCUMENT" on the Object Inspector.)

Use the zoom buttons to zoom out to a tag's parent and zoom back in to the selected child tag. Zooming isn't specific to the tag,
it's more generic to the markup in the document itself. For example, if the cursor is on a tag in your HTML markup, and you use
the Zoom command, it will take you to the outer tag, or one level above the attribute where the cursor is positioned.

Validation against standard HTML style rules occurs automatically. If validation fails, the incorrect element is highlighted in red in
the Designer, and Error Insight appears in the Tag Editor to help you correct the problem.

To view HTML code for an individual control


1. With the Designer displayed, drag an HTML element from the Tool Palette to the Designer surface. The Tag Editor displays
the HTML code.
2. To view the individual control's code, click anywhere on the Designer surface to deselect the control. The HTML code appears
in the tag editor window, with syntax highlighting. The gray header of the tag editor now displays the higher level tag, usually
the FORM tag that defines this particular Web Form.
Note: If a control is defined using several lines of HTML code, when you select the control, the first line of the code is
displayed in the gray header of the tag editor. The additional code appears below in the tag editor window.

To view the HTML code for all controls


1. With the Designer displayed, drag several HTML elements from the Tool Palette to the Designer surface. The editor displays
the HTML code for each element as you drop them on the Designer surface.
2. Click anywhere on the Designer surface to deselect all controls. This displays the code for all the controls in the tag editor,
with syntax highlighting.

151
Using the HTML Tag Editor RAD Studio 2.6 WebSnap Procedures

To modify a control
1. Click anywhere on the Designer surface to deselect all controls.
2. Locate the tag that corresponds to the control you want to modify.
3. Modify the code, and the change is immediately reflected in the control on the Designer surface.
4. Save your project to make the modifications permanent.

To change editor properties


1. Choose Tools Options HTMLOptions.
2. Change any code editor properties.
3. Click OK. Your changes take effect immediately.

To zoom between contents of the form and the form container


1. To zoom out so that you can view the HTML form definition, click the left-hand blue arrow in the gray header of the tag editor.
Note: You can only use this feature when the cursor is somewhere in the tag editor, rather than on the Designer surface.

2. To zoom in so that you can view only the content within the FORM tags, click the right-hand blue arrow in the gray header of
the tag editor.
Note: You can only use this feature when the cursor is somewhere in the tag editor, rather than on the Designer surface.

To close the Tag Editor


2 1. Choose Tools Options HTML Options.
2. Uncheck the Display Tag Editor option.
3. Click OK.
See Also
Using the Code Editor

Customizing the Code Editor

Using Live Templates

Using Code Insight

152
2.7 Web Services Procedure RAD Studio Building a "Hello World" Web Services

2.7 Web Services Procedure


This section provides how-to information on developing and using web services.

Topics
Name Description
Building a "Hello World" Web Services Application ( see page 153) Web Services are self-contained modular applications that can be published and
invoked over a network (such as the World Wide Web). Web Services use
SOAP, a standard lightweight protocol for exchanging information in a distributed
environment. It uses HTTP as a communications protocol and XML to encode
remote procedure calls.

2.7.1 Building a "Hello World" Web Services Application


Web Services are self-contained modular applications that can be published and invoked over a network (such as the World
Wide Web). Web Services use SOAP, a standard lightweight protocol for exchanging information in a distributed environment. It
uses HTTP as a communications protocol and XML to encode remote procedure calls.

To build a "Hello World" Web Services application


1. Choose File New Other. The New Items dialog box appears.
2. Select WebServices folder. 2
3. Double-click the Soap Server Application icon. The SOAP Server Application wizard opens.
4. Choose the type of Web server application you want to use for your Web Service. The wizard generates a new Web server
application that includes a Web module that contains three components—HTTPSoapPascalInvoker, HTTPSoapDispatcher,
and WSDLHTMLPublish. When you exit the SOAP Server Application wizard, it asks you if you want to define an interface for
your Web Service.
5. To create a a Web Service from scratch, click Yes. The Add New Web Service wizard opens.
6. To add a new Web Service, specify the name of the invokable interface you want to expose to clients. The Add New Web
Service wizard lets you specify the name of the invokable interface and generates the code to declare and register the
interface and its implementation class.
7. To implement a Web Service that has already been defined in a WSDL document, use the WSDL importer to generate the
interfaces

To use the WSDL importer


1. Choose File New Other. A New Items dialog appears.
2. Select WebServices folder.
3. Double-click the icon labeled WSDL importer. A WSDL Import Wizard appears.
4. In that dialog box, either specify the file name of a WSDL document (or XML file) or click the ellipsis button [...] to browse for
the file.
5. If the WSDL document is on a server that requires authentication, click Options. On the Import Options dialog box, enter the
user name and password required before the wizard can retrieve the WSDL document. After completing the import options,
click OK.
6. Click Next. The WSDL importer displays the code it generates for every definition in the WSDL document that is compatible
with the Web Services framework.

153
Building a "Hello World" Web Services RAD Studio 2.7 Web Services Procedure

7. Click Finish. The importer creates new units that define and register invokable interfaces for the operations defined in the
document, and that define and register remotable classes for the types that the document defines.
See Also
Web Services Overview ( see page 44)

Using Web Services ( see page 2291)

Using Web Services (chapter index) ( see page 2289)

WSDL Import Wizard

154
3 RAD Studio

3 Reference
Topics
Name Description
C++ Reference ( see page 156) This section contains reference topics for the C++ library in RAD Studio.
Win32 Developer's Guide ( see page 1217) This section contains the Win32 Developer's Guide topics for the Delphi Win32
personality in RAD Studio.

155
Command Line Utilities RAD Studio 3.1 C++ Reference

3.1 C++ Reference


This section contains reference topics for the C++ library in RAD Studio.

Topics
Name Description
Command Line Utilities ( see page 156) C++Builder provides a rich set of command line utilities in addition to its
integrated development environment (IDE). These utilities enable you to use the
command line to perform targeted compilation and other related functions,
including file search and import of definition files.
C++ Compiler Errors And Warnings (C++) ( see page 216) This section describes the RAD Studio C++ compiler error and warning
messages.
C++ Language Guide ( see page 385) This sections contains C++ language topics.
C Runtime Library Reference ( see page 711) RAD Studio has several hundred functions, macros, and classes that you call
from within your C and C++ programs to perform a wide variety of tasks,
including low- and high-level I/O, string and file manipulation, memory allocation,
process control, data conversion, mathematical calculations, and more.
Note: In the online help, each function, macro, and class in the C Runtime
Library is listed only once . However, some functions, macros, and classes are
defined in more than one header file.
For example, _strerror is defined in both string.h and stdio.h. For functions
that are defined in several header files, the online... more ( see page 711)

3.1.1 Command Line Utilities


C++Builder provides a rich set of command line utilities in addition to its integrated development environment (IDE). These
utilities enable you to use the command line to perform targeted compilation and other related functions, including file search and
import of definition files.

Topics
Name Description
BCC32, the C++ Command-Line Compiler ( see page 159) The CodeGear C++ compiler (BCC32.EXE) is a resource compiler shell. It
invokes BRCC32 and RLINK32, depending on the command-line syntax.
BRC32, the Resource Shell ( see page 163) The Borland resource compiler (BRC32) is a resource compiler shell. It invokes
BRCC32 and RLINK32, depending on the command-line syntax.
BRCC32.EXE, the Resource Compiler ( see page 165) BRCC32 is the command-line version of the resource compiler. It accepts a
resource script file (.RC) as input and produces a resource object file (.RES) as
output.
RAD Studio provides a choice in resource compilers. You can choose to use
either BRCC32 or RC (the Microsoft SDK resource compiler) on the
Project Options Resource Compiler dialog box.
COFF2OMF.EXE, the Import Library Conversion Tool ( see page 166) COFF2OMF converts a COFF import library file (InputFile) to a corresponding
OMF import library file (OutputFile). COFF2OMF.EXE is located in the
C++Builder \bin directory.
CPP32.EXE, the C Compiler Preprocessor ( see page 167) CPP32.EXE produces a file that lists a C or C++ program, in which all #include
3 files and #define macros have been expanded. While you do not need to use the
preprocessor during normal compilation, you may find the list file helpful for
debugging purposes.
Often, when the compiler reports an error inside a macro or an include file, you
can get more information about what the error is if you can see the include files
or the results of the macro expansions. In many multi-pass compilers, a separate
pass performs this work, and the results of the pass can be... more ( see page
167)
DCC32.EXE, the Delphi Command Line Compiler ( see page 169) DCC32 is the Delphi (Object Pascal) command line compiler.
To display command line help, enter:

156
3.1 C++ Reference RAD Studio Command Line Utilities

GREP.EXE, the text search utility ( see page 170) GREP (Global Regular Expression Print) is a powerful text-search program
derived from the UNIX utility of the same name. GREP searches for a text pattern
in one or more files or in its standard input stream.
ILINK32.EXE, the Incremental Linker ( see page 174) ILINK32 links object modules (.OBJ files), library modules (.LIB files), and
resources to produce executable files (.EXE, .DLL, and .BPL files). ILINK32
creates and maintains a series of state files that contains this information. These
state files allow subsequent links to be incremental, greatly reducing the total link
time.
IMPDEF.EXE, the Module Definition Manager ( see page 179) Import libraries provide access to the functions in a Windows DLL. Import
libraries contain records. Each record contains the name of a DLL and specifies
where in the DLL the imported functions reside. These records are bound to the
application by the linker and provide Windows with the information necessary to
resolve DLL function calls. You can substitute an import library for part or all of
the IMPORTS section of a module definition file.
IMPDEF takes as input a DLL name, and produces as output a module definition
file with an EXPORTS section containing the names of functions exported by...
more ( see page 179)
IMPLIB.EXE, the Import Library Tool ( see page 181) IMPLIB takes as input either DLLs or module definition files, or both, and
produces an import library as output.
If you've created a Windows application, you've already used IMPORT32.LIB, the
import library for the standard Windows DLLs. IMPORT32.LIB is linked
automatically when you build a Win32 application in the C++Builder IDE and
when using BCC32 at the command line.
An import library lists some or all of the exported functions for one or more DLLs.
IMPLIB creates an import library directly from DLLs or from module definition files
for DLLs (or a combination of the two).
Using Include Files ( see page 182) In C++, include files always have the file extension .h.
MAKE ( see page 183) MAKE.EXE is a command-line utility that helps you manage project compilation
and link cycles. MAKE is not inherently tied to compiling and linking, but is a
more generic tool for executing commands based on file dependencies. MAKE
helps you quickly build projects by compiling only the files you have modified
since the last compilation. In addition, you can set up rules that specify how
MAKE should deal with the special circumstances in your builds.
MAKE Directives ( see page 186) MAKE directives resemble directives in languages such as C and Pascal. In
MAKE, directives perform various control functions, such as displaying
commands onscreen before executing them. MAKE directives begin either with
an exclamation point or a period, and they override any options given on the
command line. Directives that begin with an exclamation point must appear at the
start of a new line.
The following table lists the MAKE directives and their corresponding
command-line options:

MAKE Macros ( see page 191) A macro is a variable that MAKE expands into a string whenever MAKE
encounters the macro in a makefile. For example, you can define a macro called
LIBNAME that represents the string "mylib.lib." To do this, type the line LIBNAME
= mylib.lib at the beginning of your makefile. Then, when MAKE encounters the
macro $(LIBNAME), it substitutes the string mylib.lib. Macros let you create
template makefiles that you can change to suit different projects.
To use a macro in a makefile, type $(MacroName) where MacroName is a
defined macro. You can use either braces or parentheses to enclose
MacroName.
MAKE... more ( see page 191)
MAKE Rules (Explicit and Implicit) and Commands ( see page 193) You write explicit and implicit rules to instruct MAKE how to build the targets in
your makefile. In general, these rules are defined as follows:

• Explicit rules are instructions for specific files.


• Implicit rules are general instructions for files without
explicit rules.
All the rules you write follow this general format: 3
Message Options ( see page 197) Use the -w option to specify message options for the CodeGear C++ compiler:

• To enable a particular warning message, enter the -w


option with a one- to three-letter option code.
• To disable the warning message, enter the -w- option with
a one- to three- letter option code.

157
Command Line Utilities RAD Studio 3.1 C++ Reference

Module Definition Files ( see page 199) You use module definition files with ILINK32. A module definition file is an ASCII
text file that provides information to ILINK32 about the contents and system
requirements of a Windows application. Use IMPDEF to create a module
definition file.
The module definition file names the .EXE or .DLL, identifies the application type,
lists imported and exported functions, describes the code section and data
segment attributes, lets you specify attributes for additional code sections and
data segments, specifies the size of the stack, and provides for the inclusion of a
stub program.
Using Precompiled Header Files ( see page 203) Precompiled header files can dramatically increase compilation speed by storing
an image of the symbol table on disk in a file, then later reloading that file from
disk instead of parsing all the header files again. Directly loading the symbol table
from disk is much faster than parsing the text of header files, especially if several
source files include the same header file.
To use precompiled header files, specify the various -H options in your BCC32
command.
Precompiled Header Options
RLINK32.DLL, the Resource Linker (C++) ( see page 204) RLINK32.DLL is the resource linker that binds resources, in .RES file form, to an
.EXE file, and marks the resulting .EXE file as a Windows executable.
RLINK32.DLL also:

• Links the resources by fixing up string tables and


message tables and then binding these linked resources
into the executable.
• Is called by ILINK32 and is used for 32-bit resources.
TDUMP.EXE, the File Dumping Utility ( see page 204) TDUMP.EXE produces a file dump that shows the structure of a file.
TDUMP breaks apart a file structurally and uses the file's extension to determine
the output display format. TDUMP recognizes many file formats, including .EXE,
.OBJ, and .LIB files. If TDUMP doesn't recognize an extension, it produces a
hexadecimal dump of the file. You can control the output format by using the
TDUMP command-line options when you start the program.
TDUMP's ability to peek at a file's inner structure displays not only a file's
contents, but also how a file is constructed. Moreover, because TDUMP verifies
that a file's... more ( see page 204)
TLIB.EXE, the Library Manager ( see page 208) TLIB is a utility that manages libraries of .OBJ (object module) files. A library is a
convenient way to deal with a collection of object modules as a unit.
The libraries included with the CodeGear C++ compiler were built with TLIB. You
can use TLIB to build your own libraries, or to modify the CodeGear C++
libraries, your libraries, libraries furnished by other programmers, or commercial
libraries you've purchased.
When TLIB modifies an existing library, TLIB creates a copy of the original library
and gives it a .BAK extension.
You can use TLIB to:

• Create a new library from a... more ( see page 208)


Using TOUCH.EXE ( see page 212) TOUCH.EXE updates a file's date stamp so that it reflects your system’s current
time and date.
TRIGRAPH ( see page 213) Trigraphs are three-character sequences that replace certain characters used in
the C language that are not available on some keyboards. Translating trigraphs
in the compiler would slow compilation down considerably, so CodeGear C++
provides a filter named TRIGRAPH.EXE to handle trigraph sequences.
RC.EXE, the Microsoft SDK Resource Compiler ( see page 213) RC is the command-line version of the standard Microsoft SDK resource
compiler. It accepts a resource script file (.RC) as input and produces a resource
object file (.RES) as output.
Both C++Builder 2009 and Delphi 2009 give you a choice of resource compilers.
On the Project Options Resource Compiler dialog box, you can select
either of the following:
3 • BRCC32.exe, the CodeGear resource compiler
• RC.exe, the Microsoft platform SDK Resource Compiler
RC supports Unicode characters in resource files and file
names, as well as new Vista resource types such as icons
with alpha channel.
The actual filename of the RC compiler... more ( see page
213)

158
3.1 C++ Reference RAD Studio Command Line Utilities

WSDLIMP.EXE, the Command Line WSDL Import Tool ( see page 214) WSDLIMP generates code to represent the types and APIs that a WSDL
document defines. This code can be used to write client applications that call on
the Web Service that the WSDL (Web Services Description Language) document
describes. If you want to write a server that implements the Web Service, one of
the command line options tells the importer to generate implementation classes
that you can then complete by filling in the bodies of the generated methods.
Note: WSDLIMP ignores any definitions in the WSDL document for which it can't
generate code. That is, it can only import Web Services... more ( see page 214)

3.1.1.1 BCC32, the C++ Command-Line Compiler


The CodeGear C++ compiler (BCC32.EXE) is a resource compiler shell. It invokes BRCC32 and RLINK32, depending on the
command-line syntax.

Command Line Syntax


bcc32 [option [option...}] <filename> [<filename>...]

Use spaces to separate the command-line compiler name, each option, and the filenames. Precede each option by either a
hyphen (-) or a forward slash (/). For example:
BCC32 -Ic:\code\hfiles

You can also specify options in configuration (.CFG) files, which are described in a following section.

You can use BCC32 to send .OBJ files to ILINK32 or .ASM files to TASM32 (if you have TASM32 installed on your machine).

See the BCC32 Command Line Help for Detailed Information


To display the BCC32.exe command line help in the cmd window, include the —h command line option.

For example, to display a list of the commonly used compiler command line options, type:
BCC32 -h

The displayed list indicates the options that are enabled by default (*):
C:\>bcc32 -h CodeGear C++ 5.92 for Win32 Copyright (c) 1993, 2007 CodeGear
Available options (* = default setting, xxx = has sub-options: use -h -X):
(Note: -X- or -w-XXX will usually undo whatever was set or unset by -X)
-3 Generate 80386 protected-mode compatible instructions
-4 Generate 80386/80486 protected-mode compatible instructions
-5 Generate Pentium instructions
-6 Generate Pentium Pro instructions
-Axxx Enable ANSI conformance
-B Compile to .ASM (-S), then assemble to .OBJ
-C Enable nested comments
-CP Enable code paging (for MBCS)
-D -D <name> defines 'name' as a null string, or use -D<name>=<value>
-E Specify which assembler to use
-G Optimize for size/speed; use -O1 and -O2 instead
-Hxxx Generate and use precompiled headers
-I Set the include file search path
-Jxxx Template generation options
-K Set default character type to unsigned 3
-L Library file search path
-M Create a linker map file
-O Optimize jumps
-P Perform C++ compile regardless of source extension
-Q Extended compiler error information
-R Include browser information in generated .OBJ files
-RF Find references to symbol
* -RT Enable runtime type information
-S Compile to assembly
-T Specify assembler option, e.g. -Tx

159
Command Line Utilities RAD Studio 3.1 C++ Reference

-U Undefine any previous definitions of name


-Vxxx Compatibility options
-Wxxx Target is a Windows application
-X Disable compiler autodependency output
-axxx Set data alignment boundary. Default is -a8; -a- means -a1
* -b Make enums integer-sized (-b- makes them short as possible)
-c Compile to object file only, do not link
-d Merge duplicate strings
-dc Put strings into the read-only data segment
-dw Put strings into the (writeable) data segment
-e Specify target executable pathname
* -ff Fast floating point
-fp Correct Pentium FDIV flaw
* -fq Use quiet floating point compare instruction (FUCOMP)
-g Stop batch compilation after n warnings (Default = 255)
-h Request help ('-h -' shows all help). Can be specific: -h -V
-i Set maximum significant identifier length (Default = 250)
-j Stop batch compilation after n errors (Default = None)
* -k Generate standard stack frames
-l Pass options to the linker; example: -ls -l-x
-m Generate makefile dependency information
-md Put dependency info in .d files, not in the object file
-mm Ignore system header files while generating dependency info
-mo Specify the output file for dependency info
-n Set output directory for object files
-o Set output filename (-o<filename> or —o <filename> supported)
-pxxx Use Pascal calling convention
-q Suppress compiler identification banner
-r Use register variables
-rd Use register variables only when register keyword is employed
-s Link using the system's non-incremental linker
-txxx An alternate name for the -Wxxx switches; there is no difference
* -u Generate underscores on symbol names
-vxxx Turn on source debugging
-w Display all warnings
-w! Return non-zero from compiler on warnings
-xxxx Enable exception handling
-y Debug line numbers on
-z Options for redefining standard segment names

Displaying Help for Specific Options, Groups such as -Axxx and -Vxxx
You can get more specific information about each of the multi-letter options, such as -Axxx (language compatibility and
standards compliance) and -Vxxx (backward compatibility).

To do this, use the -h command line option with the initial letter of the option group (such as -A to specify the -Axxx options).
BCC32 will display only the help topics for the specified set of options (such as —Axxx, —Vxxx or —Wxxx).

For example, to display a description of the -Axxx (language compatibility and standards compliance) options, use the —h and —A
command line options:
C:\>bcc32 -h -A
CodeGear C++ 6.10 for Win32 Copyright (c) 1993-2008 CodeGear
3 Available options (* = default setting, xxx = has sub-options: use -h -X):
(Note: -X- or -w-XXX will usually undo whatever was set or unset by -X)
-A Enable ANSI conformance
-AF Use SUN Forte keywords and extensions
-AG Use GNU keywords and extensions
-AK Use Kernighan and Ritchie keywords and extensions
-AT Use CodeGear C++ keywords and extensions (also -A-)
-AU Use UNIX System V keywords and extensions
-An Use C99 keywords and extensions
-Ax Use C++-0x keywords and extensions

160
3.1 C++ Reference RAD Studio Command Line Utilities

In the following example, the BCC32 command line help displays details about all the -Vxxx (backward compatibility) options:
C:\>bcc32 -h -V
CodeGear C++ 6.10 for Win32 Copyright (c) 1993-2008 CodeGear
Available options (* = default setting, xxx = has sub-options: use -h -X):
(Note: -X- or -w-XXX will usually undo whatever was set or unset by -X)
-V Compatibility options
-V0 External C++ virtual tables
-V1 Public C++ virtual tables
* -VA Generate all global functions in their own virtual/weak segment
-VC Do not mangle calling convention into symbols
-VF MFC compatibility
-VF3 Support MFC 3.2
-VF4 Support MFC 4.0
* -VI Use Microsoft search algorithm to locate header files
-VM Microsoft Visual C++ compatibility
-Va Support old-style class arguments
-Vb Enable backward compatability with Bcc versions 5.8.2 and earlier
-Vbc Don't collapse reference to reference and allow qualified references
-Vbe Allow old-style explicit template specialization
-Vbn Allow calling of non-const or non-volatile member function for a const
or volatile object
-Vbo Use old Borland overload resolution rules
-Vbr Allow non-const reference binding
-Vbs Treat string literals as non-const
-Vbt Use old Borland type rules for ternary operators
-Vbx Allow explicit template specialization as a member function
-Vc Support constructor displacements
-Vd Use old C++ for-statement scoping rules
-Ve Zero-length empty base classes
-Vg Disable lexical digraph scanner
-Vi Use old 8.3 search algorithm to locate header files
-Vl Use old Borland class layout
-Vm Member pointer options
-Vmd Use the smallest possible representation for member pointers
-Vmm Support multiple inheritance for member pointers
-Vmp Honor declared precision of member pointers
-Vms Support single inheritance for member pointers
-Vmv Place no restrictions on where member pointers can point
-Vn Enable new operator names: and, or, and_eq, bitand, etc.
-Vo Set (almost) all compatibility flags; used with old code
-Vp Push 'this' first, as does Pascal
-Vr Reverse order for Multi-character constant
-Vs Use old-style virdef generation
-Vt Put virtual table pointer at front of object layout
-Vv Use 'slow' virtual base pointers
-Vw Emit native code instead of Unicode for multi-byte character
-Vx Zero-length empty class member functions

Default Settings
BCC32.EXE has specific options that are on by default. To turn off a default option or to override options in a configuration file,
follow the option with a minus (-) sign.

Files with the .CPP extension compile as C++ files. Files with a .C extension, with no extension, or with extensions other than 3
.CPP, .OBJ, .LIB, or .ASM compile as C files.

The compiler tries to link with a module-definition file with the same name as the executable, and extension .DEF.

General Compiler Output Options

161
Command Line Utilities RAD Studio 3.1 C++ Reference

Option Description Details


-c Compiles to Compiles and assembles the named .C, .CPP, and .ASM files, but does not execute a link on the
.OBJ, no link resulting .OBJ files.

-e Specify Link file using <filename> as the name of the executable file. If you do not specify an executable
<filename> executable name with this option, the linker creates an executable file based on the name of the first source
filename file or object file listed in the command.
-l <x> Pass option to Use this command-line option to pass option(s) <x> to the linker from a compile command. Use
linker. the command-line option -l-x to disable a specific linker option.

-M Create a MAP Use this compiler option to instruct the linker to create a map file.
file
-o Compike Compiles the specified source file to <filename>.OBJ
<filename> .OBJ to
<filename>
-P C++ compile Causes the compiler to compile all source files as C++ files, regardless of their extension. Use -P-
to compile all .CPP files as C++ source files and all other files as C source files.
The command-line option -Pext causes the compiler to compile all source files as C++ files and it
changes the default extension to whatever you specify with ext. This option is provided because
some programmers use different extensions as their default extension for C++ code.
The option -P-ext compiles files based on their extension (.CPP compiles to C++, all other
extensions compile to C) and sets the default extension (other than .CPP).
-tWM Generate a Creates a multi-threaded .EXE or .DLL. This option is not needed if you include a module
multi-threaded definition file (.DEF file) in your compile and link commands which specify the type of 32-bit
target application you intend to build.

Compiler option precedence rules


The command-line compilers evaluate options from left to right, and follow these rules:

• If you duplicate any option (except for the options -D, -I, -L, or -U), the last option typed overrides any earlier one.
• Options typed at the command line override configuration and response file options except for the -D, -I, -L, and -U options,
which are cumulative.

Specifying directories in command line options


The CodeGear C++ compiler can search multiple directories for include and library files. The syntax for the library directories
option (-L) and the include directories option (-I), (like the #define option (-D)) allows multiple listings of a given option. Here is
the syntax for these options:
-L <dirname> [<dirname>;...]
-I <dirname> [<dirname>;...]
3
The parameter <dirname> used with -L and -I can be any directory or directory path. You can enter these multiple directories on
the command line in the following ways

• You can stack multiple entries with a single -L or -I option by using a semicolon: BCC32.EXE —L
dirname1;dirname2;dirname3 —I include1;include2;include3 myfile.c
• You can place more than one of each option on the command line, like this: BCC32.EXE —L dirname1 —L dirname2 —L
dirname3 —I include1 —I include2 —I include3 myfile.c
• You can mix styles: BCC32.EXE —L dirname1;dirname2 —Ldirname3 —I include1;include2 —I include3

162
3.1 C++ Reference RAD Studio Command Line Utilities

myfile.c
If you list multiple -L or -I options on the command line, the result is cumulative. The compiler searches all the directories listed,
in order from left to right.

Using compiler configuration files (.CFG files)


If you repeatedly use a certain set of options, you can list them in a configuration file instead of continually typing them on the
command line. A configuration file is a standard ASCII text file that contains one or more command-line options. Each option
must be separated by a space or a new line.

Whenever you issue a compile command, BCC32.EXE searches for a configuration file called BCC32.CFG. The compiler looks
for the .CFG file first in the directory where you issue the compile command, then in the directory where the compiler is located.

You can create and use multiple configuration files in addition to using the default .CFG file.

To use a configuration file, use the following syntax where you would place the compiler options:
+[path]filename

For example, you could use the following command line to use a configuration file called MYCONFIG.CFG:
BCC32 +C:\MYPROJ\MYCONFIG.CFG mycode.cpp

Options typed on the command line override settings stored in configuration files except for the prepended options -D, -I, -L, and
-U.

Using response files


Response files let you list both compiler options and file names in a single file (unlike configuration files, which accept only
compiler options). A response file is a standard ASCII text file that contains one or more command-line options and/or file
names, with each entry in the file separated by a space or a new line. In addition to simplifying your compile commands,
response files let you issue a longer command line than most operating systems allow.

The syntax for using a single response file is:


BCC32 @[path]respfile.txt

The syntax for using multiple response files is:


BCC32 @[path]respfile.txt @[path]otheresp.txt

Response files typically have an .RSP extension.

Options typed at the command line override any option or file name in a response file except for -D, -I, -L, and -U, which are
prepended.

See Also
Using Include Files ( see page 182)

Using Precompiled Header Files ( see page 203)

Using Module Definition Files ( see page 199)

RLINK32.DLL ( see page 204) 3


BRCC32.EXE ( see page 165)

3.1.1.2 BRC32, the Resource Shell


The Borland resource compiler (BRC32) is a resource compiler shell. It invokes BRCC32 and RLINK32, depending on the
command-line syntax.

163
Command Line Utilities RAD Studio 3.1 C++ Reference

Command Line Syntax


brc32 [options] <filename>.RC [<filename>.EXE]

To display command line help, enter:


brc32

Command Line Options

Option Description
-d<name> Defines a symbol you can test with the #IFDEF preprocessor directive.
[=string]
-fo<filename> Renames the .RES file.
-fe<filename> Renames the .EXE file.
-i<path> Adds one or more directories (separated by semicolons) to the include search path.
-k Disables the contiguous preload of segments and resources in the .EXE file. Segments are kept in the order in
which they appear in the .DEF file. (This option only applies to 16-bit resources and is disabled when the -r
option is in effect.)
-r Creates a .RES file only. The compiled .RES file is not added to the .EXE.
-v Prints progress messages (verbose listing).
-x Directs the compiler to ignore the INCLUDE environment variable when it searches for include or resource files.
-16 Builds 16–bit .RES files.
-32 Builds 32–bit .RES files.
-Vd.d Makes the .EXE file with Windows version provided (v3.1 is the default for 16-bit resources; -v4.0 is the default
for 32-bit resources). Version options are listed in the following table.

Version Options (Used with —Vd.d Option)

Option Bit Resulting Look


3.1 16 Gives white background with a non 3-D look for Windows 3.1x, Windows 32s, or WinNT 3.1
4.0 16 Gives gray 3-D look for Windows 95 and WinNT 3.51
3.1 32 Gives white background with a non 3-D look for Windows 32s or WinNT 3.1
4.0 32 Gives gray 3-D look for Windows 95 and WinNT 3.51

Options for Downward Compatibility

Option Description
-t Creates an application that runs only in protected mode (Windows Standard or 386 Enhanced mode).
-31 Builds Windows 3.1-compatible .RES files.
-w32 Builds Win32-compatible .RES files.
3
Resource Shell Examples
The following statement compiles the .RC file, creates a .RES file, and adds the .RES file to the executable file:
brc32 <filename>.RC <filename>.EXE

BRC32 automatically seeks an .EXE file with the same name as the .RC file. You need to specify the .EXE file only if its name is
different from that of the .RC file.

164
3.1 C++ Reference RAD Studio Command Line Utilities

The following statement creates a .RES file, but not an .EXE file. If you name an .EXE file in the command line, BRC ignores it:
brc32 -r <filename>.EXE

The following statement adds an existing .RES file to an executable file. The .EXE file name is required only if it differs from the
.RES file name:
brc32 <filename>.RES <filename>.EXE

This example uses BRC32 to build a 16-bit Windows 3.1 compatible .RES file:
brc32 -16 -v3.1 -fo<filename>.RES <filename>.RC

See Also
RLINK32.DLL ( see page 204)

BRCC32.EXE ( see page 165)

3.1.1.3 BRCC32.EXE, the Resource Compiler


BRCC32 is the command-line version of the resource compiler. It accepts a resource script file (.RC) as input and produces a
resource object file (.RES) as output.

RAD Studio provides a choice in resource compilers. You can choose to use either BRCC32 or RC (the Microsoft SDK resource
compiler) on the Project Options Resource Compiler dialog box.

Command Line Syntax


BRCC32 [<options>] <filename>

To display command line help, enter:


brcc32

Or add the help flag:


brcc32 -h

BRCC32 Command Options

Option Description
@<responsefile> Takes instructions from the specified command file.
-c <codepage> Uses the specified code page for resource translation. If -c is not used, the default ANSI code page is
used.
-d<name>[=<string>] Defines a preprocessor symbol.
-fo<filename> Renames the output .RES file. (By default, BRCC32 creates the output .RES file with the same name
as the input .RC file.)
-i<path> Adds one or more directories (separated by semicolons) to the include search path.
-l<language> Specifies default language. 3
-m Indicates that the code page specified with the -c switch contains double-byte character set (DBCS)
characters.
-r This switch is ignored. It is included for compatibility with other resource compilers.
-v Prints progress messages (verbose).
-x Deletes the current include path.
-h or ? Displays help.

165
Command Line Utilities RAD Studio 3.1 C++ Reference

-16 Builds a 16–bit resource.


-32 Builds a 32–bit resource.

BRCC32 predefines common resource-related Windows constants such as WS_VISIBLE and BS_PUSHBUTTON. Also, two
special compiler-related symbols are defined: RC_INVOKED and WORKSHOP_INVOKED. These symbols can be used in the
source text in conjunction with conditional preprocessor statements to control compilation.

For example, the following construct can greatly speed up compilation:


#ifndef WORKSHOP_INVOKED#include “windows.h” #endif
Downward Compatibility
The following syntax and options are supported for downward compatibility:

Option Description
-16 Builds 16–bit .RES files.
-32 Builds 32–bit .RES files.
-31 Builds Windows 3.1–compatible .RES files.
-w32 Builds Win32–compatible .RES files.

See Also
BRC32.EXE ( see page 163)

RC.EXE ( see page 213)

3.1.1.4 COFF2OMF.EXE, the Import Library Conversion Tool


COFF2OMF converts a COFF import library file (InputFile) to a corresponding OMF import library file (OutputFile).
COFF2OMF.EXE is located in the C++Builder \bin directory.

Command Line Syntax


Coff2Omf [<options>] InputFile OutputFile

To display command line help, enter:


coff2omf

COFF2OMF converts the publicly exported symbols in the COFF import library into a corresponding set of symbols in the OMF
import library. COFF2OMF enables C++Builder users to link to Microsoft and other third-party DLLs that use the COFF format.
COFF2OMF does not convert .OBJ files.

Run the COFF2OMF tool on a COFF import library created for a specific DLL, and use the resulting import library to link OMF
format EXEs and DLLs to the COFF DLL.

3 Command Description
Line
Option
-q Quiet mode. Converts without writing tool and copyright information to standard output.
-v Dumps selected symbols. Dumps the converted symbols to standard output, which can be redirected to an output
file.
-h or -? Displays help.

166
3.1 C++ Reference RAD Studio Command Line Utilities

-r Removes (deletes) output file if empty. Deletes the output file if there is an error and the conversion results in an
empty file.
-lib:xx Specifies options for OMF import library generation. The xx options can be:
• ms — Allow entries that have MS C++ name mangling. The default is No.
• st — Normalize names instead of aliasing MS stdcall mangling.
• ca — Don't perform MS cdecl aliasing. Default is to alias.

3.1.1.5 CPP32.EXE, the C Compiler Preprocessor


CPP32.EXE produces a file that lists a C or C++ program, in which all #include files and #define macros have been expanded.
While you do not need to use the preprocessor during normal compilation, you may find the list file helpful for debugging
purposes.

Often, when the compiler reports an error inside a macro or an include file, you can get more information about what the error is
if you can see the include files or the results of the macro expansions. In many multi-pass compilers, a separate pass performs
this work, and the results of the pass can be examined. Because the CodeGear C++ compiler is a single-pass compiler, use
CPP32 to get the first-pass functionality found

For each file processed by CPP32, the output is written to a file in the current directory (or the output directory named by the -n
option) with the same name as the source name but with an extension of .I.

This output file is a text file containing each line of the source file and any include files. Any preprocessing directive lines have
been removed, along with any conditional text lines excluded from the compile. Unless you use a command-line option to specify
otherwise, text lines are prefixed with the file name and line number of the source or include file the line came from. Within a text
line, any macros are replaced with their expansion text. Use the -Sr option to produce a file which doesn't have line numbers.
You can then pass this file to the compiler (use the -P compiler option to force a C++ compile).

Command Line Syntax


CPP32 [<options>] <filename[s]>

To display command line help, enter:


cpp32 -h

CPP32 recognizes all the same options that BCC32 does, except for the following additions for the -S option (Control
preprocessed output format):

Option Description
-Sc Keep comments in preprocessed file.
-Sd Keep defines in preprocessed file.
-Sk Keep output on errors.
-Sr Make output readable by preserving comments and indentations
3
-Ss Show statistics of file names and line counts.

CPP32 as a Macro Preprocessor


CPP32 can be used as a macro preprocessor; the resulting .i file can then be compiled with BCC32. The following simple
program illustrates how CPP32 preprocesses a file.

167
Command Line Utilities RAD Studio 3.1 C++ Reference

Source file: HELLOFB.C


#define NAME “Frank CodeGear” #define BEGIN { #define END } main() BEGIN
printf(“%s\n”, NAME);p END

CPP32 Command Line


CPP32 HELLOFB.C

Output (written to HELLOFB.I)


/* HELLOFP.C 1: */

/* HELLOFP.C 2: */

/* HELLOFP.C 3: */

/* HELLOFP.C 4: */

/* HELLOFP.C 5: */main()

/* HELLOFP.C 6: */printf("%s\n", "Frank CodeGear");

/* HELLOFP.C 7: */}
/* HELLOFP.C 8: */}

Using MIDL with CPP32


MIDL (Microsoft Interface Definition Language) is an RPC compiler. In order to use MIDL with the C++ preprocessor
(CPP32.EXE), you must use the following MIDL command:

Option Description
-<cpp_cmd> Tells MIDL which preprocessor to use when processing an .IDL or .ACF file. MIDL calls the
{<CPP32>} preprocessor to expand macros within source files.
-<cpp_opt> Specifies the command line options for the preprocessor. The -Sr option removes line number and file
"{<options>}" name information from each line of the preprocessed output. The -oCON option indicates that
preprocessed output should go to standard output, instead of to file. The preprocessor banner and the
current file that is being processed are not emitted. Including -oCON within a .CFG file processed by
the preprocessor causes the banner to be emitted.
{<CPP32 options>} Passes the options to CPP32.
{<MIDL options>} Any MIDL command-line options.
{<.idl/.acf file> The source file that MIDL processes.

BCC32, CPP32 and UUIDs


In some cases, CPP32 does not accept valid UUIDs. For example, a valid UUID statement is:
uuid(5630EAA0-CA48-1067-B320-00DD010662DB)
3
When CPP32 encounters 5630EAA0, it is classified as a floating-point number, and since it is an invalid floating point number,
the preprocessor emits an error. To work around this problem, enclose the UUID within quotes. When using MIDL with CPP32,
use the -ms_ext option. The UUID statement becomes:
uuid("5630EAA0-CA48-1067-B320-00DD010662DB")

and the MIDL command line becomes:


MIDL -ms_ext -cpp_cmd CPP32 -cpp_opt " -oCON {<CPP32 options>}" {<MIDL options>} {<.idl/.acf

168
3.1 C++ Reference RAD Studio Command Line Utilities

file>}

See Also
BCC32.EXE ( see page 159)

3.1.1.6 DCC32.EXE, the Delphi Command Line Compiler


DCC32 is the Delphi (Object Pascal) command line compiler.

To display command line help, enter:


dcc32
or:
dcc32 —h
or:
dcc32 —help
C:\>dcc32
CodeGear Delphi for Win32 compiler version 18.5
Copyright (c) 1983,2007 CodeGear

Syntax: dcc32 [options] filename [options]

-A <unit>=<alias> = Set unit alias


-B = Build all units
-CC = Console target
-CG = GUI target
-D<syms> = Define conditionals
-E<path> = EXE/DLL output directory
-F<offset> = Find error
-GD = Detailed map file
-GP = Map file with publics
-GS = Map file with segments
-H = Output hint messages
-I<paths> = Include directories
-J = Generate C .obj file
-JP = Generate C++ object file
-JPN = Generate C++ .obj, include namespace
-JPE = Generate C++ .obj, export all symbols
-JPH = Generate C++ .obj, export symbols, generate header .hpp files
-JPHNE = Generate C++ .obj file, .hpp file, in namespace, export all
-JL = Generate package .lib, .bpi, and all .hpp files for C++
-K<addr> = Set image base addr
-LE<path> = package .bpl output directory
-LN<path> = package .dcp output directory
-LU<package> = Use package
-M = Make modified units
-N0<package> = Use package
-M = Make modified units
-N0<path> = unit .dcu output directory
-NH<path> = unit .hpp output directory
-NO<path> = unit .obj output directory 3
-NB<path> = unit .bpi output directory
-NS<namespace> = Namespace search path
-O<paths> = Object directories
-P = look for 8.3 file names also
-Q = Quiet compile
-R<paths> = Resource directories
-U<paths> = Unit directories
-V = Debug information in EXE
-VR = Generate remote debug (RSM)

169
Command Line Utilities RAD Studio 3.1 C++ Reference

-W[+|-][warn_id] = Output warning messages


-Z = Output 'never build' DCPs
-$<dir> = Compiler directive
--help = Show this help screen
--version = Show name and version
--codepage:<cp> = specify source file encoding
--default-namespace:<namespace> = set namespace
--depends = output unit dependency information
--doc = output XML documentation
--drc = output resource string .drc file
--no-config = do not load default DCC32.CFG file
--description:<string> = set executable description
Compiler switches: -$<state> (defaults are shown below)
A8 Aligned record fields
B- Full boolean Evaluation
C+ Evaluate assertions at runtime
D+ Debug information
G+ Use imported data references
H+ Use long strings by default
I+ I/O checking
J- Writeable structured consts
L+ Local debug symbols
M- Runtime type info
O+ Optimization
P+ Open string params
Q- Integer overflow checking
R- Range checking
T- Typed @ operator
U- Pentium(tm)-safe divide
V+ Strict var-strings
W- Generate stack frames
X+ Extended syntax
Y+ Symbol reference info
Z1 Minimum size of enum types
Creating C++ Files from DCC32
If you want to generate .hpp files (and the corresponding .obj) from a .pas file, you should use -JPHNE.

You can also use -JL on the .dpk file containing the .pas file.

3.1.1.7 GREP.EXE, the text search utility


GREP (Global Regular Expression Print) is a powerful text-search program derived from the UNIX utility of the same name.
GREP searches for a text pattern in one or more files or in its standard input stream.

Using GREP
Here is a quick example of a situation where you might want to use GREP. Suppose you wanted to find out which text files in
your current directory contained the string "Bob". You would type:
grep Bob *.txt
GREP responds with a list of the lines in each file (if any) that contained the string "Bob". Because GREP does not ignore case
3 by default, the strings "bob" and "boB" do not match.

GREP can do a lot more than match a single, fixed string. You can make GREP search for any string that matches a particular
pattern. (See GREP: The search string.)

Command Line Syntax


The general command-line syntax for GREP is
grep [-<options>] <searchstring> [<files(s)>...]

170
3.1 C++ Reference RAD Studio Command Line Utilities

To display a list of the GREP command line options, special characters, and defaults for GREP, enter:
grep ?
GREP Command Line Options

Option Description
<options> Consists of one or more letters, preceded by a hyphen (-), that changes the behavior of GREP.
<searchstring> Gives the pattern to search for.
<file(s)> Tells GREP which files to search. (If you do not specify a file, GREP searches standard input; this lets you use
pipes and redirection.)
Files can be an explicit file name or a generic file name incorporating the DOS ? and * wildcards. In addition,
you can type a path (drive and directory information). If you list files without a path, GREP searches the
current directory. If you do not specify any files, input to GREP must come from redirection (<) or a vertical bar
(|).

Redirecting Output from GREP


If you find that the results of your GREP are longer than one screen, you can redirect the output to a file.

For example, you could use this command:


GREP "Bob" *.txt > temp.txt
This command searches all files with the TXT extension in the current directory, then puts the results in a file called TEMP.TXT.
(You can name this file anything you like.) Use any word processor to read TEMP.TXT (the results of the search).

GREP Command Line Options


You can pass options to the GREP utility on the command line by specifying one or more single characters preceded by a
hyphen (-). Each individual character is a switch that you can turn on or off: A plus symbol (+) after a character turns the option
on; a hyphen (-) after the character turns the option off. The + sign is optional; for example, -r means the same thing as -r+. You
can list multiple options individually (like this: -i -d -l), or you can combine them (like this: -ild or -il, -d, and so on).

Here are the GREP option characters and their meanings:

Command Line Options for GREP

Option Description
-c Count only: Prints only a count of matching lines. For each file that contains at least one matching line, GREP prints
the file name and a count of the number of matching lines. Matching lines are not printed. This option is off by
default.
-d Search subdirectories: For each file specified on the command line, GREP searches for all files that match the file
specification, both in the directory specified and in all subdirectories below the specified directory. If you give a file
without a path, GREP assumes the files are in the current directory. This option is off by default.
-e Search expression follows: Indicates that the next argument is the search expression. This option is useful when
you want to search for an expression that begins with "-".
-i Ignore case: GREP ignores upper/lowercase differences. When this option is on, GREP treats all letters a to z as
3
identical to the corresponding letters A to Z in all situations. This option is off by default.
-l List file names only: Prints only the name of each file containing a match. After GREP finds a match, it prints the file
name and processing immediately moves on to the next file. This option is off by default.
-n Line numbers: Each matching line that GREP prints is preceded by its line number. This option is off by default.

171
Command Line Utilities RAD Studio 3.1 C++ Reference

-o UNIX output format: Changes the output format of matching lines to support more easily the UNIX style of
command-line piping. All lines of output are preceded by the name of the file that contained the matching line. This
option is off by default.
-r Regular expression search: The text defined by searchstring is treated as a regular expression instead of as a
literal string. This option is on by default. A regular expression is one or more occurrences of one or more
characters optionally enclosed in quotes. The following symbols are treated specially:
• ^ start of line
• . any character
• * match zero or more chatacteres
• [aeiou0-9] match a, e, i, o, u, and 0-9
• [^aeiou0-9] match all but a, e, i, o, u, and 0-9
• $ end of line
• \ quote next character
• + match one or more

-u < Update options: Creates a copy of GREP.EXE called <filename>.EXE. Any options included on the command line
filename> are saved as defaults in the new copy of GREP. Use the -u option to customize the default option settings. To verify
that the defaults have been set correctly, type filename ?; each option on the help screen is followed by a + or - to
indicate its default setting.
-v Nonmatch: Prints only nonmatching lines. Only lines that do not contain the search string are considered
nonmatching lines. This option is off by default.
-w Word search: Text found that matches the regular expression is considered a match only if the character
immediately preceding and following cannot be part of a word. The default word character set includes A to Z, 0 to
9, and the underscore ( _ ). This option is off by default. An alternate form of this option lets you specify the set of
legal word characters. Its form is -w[set], where set is any valid regular expression.
If you define the set with alphabetic characters, it is automatically defined to contain both the uppercase and
lowercase values for each letter in the set (regardless of how it is typed), even if the search is case-sensitive. If you
use the -w option in combination with the -u option, the new set of legal characters is saved as the default set.
-z Verbose: GREP prints the file name of every file searched. Each matching line is preceded by its line number. A
count of matching lines in each file is given, even if the count is zero. This option is off by default.
? Displays a help screen showing the options, special characters, and defaults for GREP.

The Search String


The value of <searchstring> defines the pattern GREP searches for. A search string can be either a regular expression or a
literal string.

• In a regular expression, certain characters have special meanings: They are operators that govern the search. (A regular
expression is either a single character or a set of characters enclosed in brackets. A concatenation of regular expressions is a
regular expression.)
3 • In a literal string, there are no operators: Each character is treated literally.
You can enclose the search string in quotation marks to prevent spaces and tabs from being treated as delimiters. To search for
an expression that begins with "-", use the -e option. The text matched by the search string cannot cross line boundaries; that
is, all the text necessary to match the pattern must be on a single line.
When you use the -r option (on by default), the search string is treated as a regular expression (not a literal expression).
The following characters have special meanings:

172
3.1 C++ Reference RAD Studio Command Line Utilities

Symbol Description
^ A circumflex at the start of the expression matches the start of a line.
$ A dollar sign at the end of the expression matches the end of a line.
. A period matches any character.
* An asterisk after a character matches any number of occurrences of that character followed by any characters,
including zero characters. For example, bo* matches bot, boo, as well as bo.
+ A plus sign after a character matches any number of occurrences of that character followed by any characters, except
zero characters. For example, bo+ matches bot and boo, but not b, bo, or bt.
{} Characters or expressions in braces are grouped so that the evaluation of a search pattern can be controlled and so
grouped text can be referred to by number.
[] Characters in brackets match any one character that appears in the brackets, but no others. For example [bot]
matches b, o, or t.
[^] A circumflex at the start of the string in brackets means NOT. Hence, [^bot] matches any characters except b, o, or t.
[-] A hyphen within the brackets signifies a range of characters. For example, [b-o] matches any character from b
through o..
\ A backslash before a wildcard character tells GREP to treat that character literally, not as a wildcard. For example, \^
matches ^ and does not look for the start of a line.

Four of the "special" characters ($, ., *, and +) do not have any special meaning when used within a bracketed set. In addition,
the character ^ is only treated specially if it immediately follows the beginning of the set definition (immediately after the [
delimiter).

GREP Examples
Example 1
grep -r "[^a-z]main\ *\(" *.c
Matches:
main(i,j:integer)
if (main ()) halt;
if (MAIN ()) halt;
Does Not Match:
mymain()
Explanation: The search string tells GREP to search for the word main with no preceding lowercase letters ([^a-z]), followed by
zero or more occurrences of blank spaces (\ *), then a left parenthesis. Since spaces and tabs are normally considered
command-line delimiters, you must quote them if you want to include them as part of a regular expression.

Example 2
grep -ri [a-c]:\\data\.fil *.c *.inc
Matches:
A:\data.fil 3
B:\DATA.FIL
c:\Data.Fil
Does Not Match:
d:\data.fil a:data.fil
Explanation: Because the backslash (\) and period (.) characters usually have special meaning in path and file names, you must
place the backslash escape character immediately in front of them if you want to search for them. The -i option is used here, so
the search is not case sensitive.

173
Command Line Utilities RAD Studio 3.1 C++ Reference

Example 3l
grep "search string with spaces" *.doc *.c
Matches:
A search string with spaces in it.
Does not match
This search string has spaces in it.
Explanation: This is an example of how to search for a string containing specific text.

Example 4
grep -rd "[ ,.:?'\"]"$ \*.doc
Matches:
He said hi to me.
Where are you going?
In anticipation of a unique situation,
Examples include the following:
"Many men smoke, but fu man chu."Explanation
Does not match:
He said "Hi" to me
Where are you going? I'm headed to the
Explanation: This example searches for any one of the characters " . : ? ' and , at the end of a line. The double quote within the
range is preceded by an escape character so it is treated as a normal character instead of as the ending quote for the string.
Also, the $ character appears outside of the quoted string. This demonstrates how regular expressions can be concatenated to
form a longer expression.

Example 5
grep -w[=] = *.c
Matches:
i = 5;
j=5;
i += j;
Does not match:
if (i == t) j++;
/* ==================================== */
This example redefines the current set of legal characters for a word as the assignment operator (=) only, then does a word
search. It matches C assignment statements, which use a single equal sign (=), but not equality tests, which use a double equal
sign (==).

See Also
BCC32.EXE ( see page 159)
3
3.1.1.8 ILINK32.EXE, the Incremental Linker
ILINK32 links object modules (.OBJ files), library modules (.LIB files), and resources to produce executable files (.EXE, .DLL,
and .BPL files). ILINK32 creates and maintains a series of state files that contains this information. These state files allow
subsequent links to be incremental, greatly reducing the total link time.

174
3.1 C++ Reference RAD Studio Command Line Utilities

Command Line Syntax


ILINK32 [@<respfile>][<options>] <startup> <myobjs>, [<exe>], [<mapfile>], [<libraries>],
[<deffile>], [<resfile>]

To display command line help, enter:


ilink32

Linker command-line options are case-sensitive.

The linker can also use a configuration file called ILINK32.CFG for options that you'd typically type at the command-line.

Element Description
[@<respfile>] A response file is an ASCII file that lists linker options and file names that you would normally type at the
command line. By placing options and file names in a response file, you can save the amount of keystrokes you
need to type to link your application.
<options> Linker options that control how the linker works. For example, options specify whether to produce an .EXE,
.BPL, or .DLL file. Linker options must be preceded by either a slash (/) or a hyphen (-).
<startup> A CodeGear initialization module for executables or DLLs that arranges the order of the various segments of
the program. Failure to link in the correct initialization module usually results in a long list of error messages
telling you that certain identifiers are unresolved, or that no stack has been created.
<myobjs> The .OBJ files you want linked. Specify the path if the files aren't in the current directory. (The linker appends an
.OBJ extensions if no extension is present.)
<exe> The name you want given to the executable file (.EXE, .BPL, or .DLL). If you don't specify an executable file
name, ILINK32 derives the name of the executable by appending .EXE, .BPL, or .DLL to the first object file
name listed. (The linker assumes or appends an .EXE extensions for executable files if no extension is present.
It also appends a .DLL extension for dynamic link libraries if no extension is present. Similarly, the linker
appends a .BPL extension for package files if no extension is present.)
<mapfile> The name you want given to the map file. If you don't specify a name, the map file name is the same as the
.EXE file (but with the .MAP extension). (The linker appends a .MAP extension if you do not specify an
extension.)
<libraries> The library files you want included at link time. Do not use commas to separate the libraries listed. If a file is not
in the current directory or the search path (see the /L option) then you must include the path in the link
statement. (The linker appends a .LIB extension if no extension is present.)
The order in which you list the libraries is very important; be sure to use the order defined in this list:
1. Code Guard libraries (if needed)
2. Any of your own user libraries (note that if a function is defined more than once, the linker uses the first
definition encountered)
3. IMPORT32.LIB (if you are creating an executable that uses the Windows API)
4. Math libraries
5. Runtime libraries

<deffile> The module definition file for a Windows executable. If you don't specify a module definition (.DEF) file and you
have used the /Twd or /Twe option, the linker creates an application based on default settings. (The linker
appends a .DEF extension if no extension is present.) 3
<resfile> A list of .RES files (compiled resource files) to bind to the executable. (The linker appends an .RES extension if
no extension is present.)

Linker Options

175
Command Line Utilities RAD Studio 3.1 C++ Reference

Option Description
@xxxx Uses the response file xxxx.
/A:dd Specifies file alignment (backward compatibility switch, use /Af).
/Af:nnnn Specifies file alignment; set nnnn in hex or decimal. nnnn must be a power of 2. Default is 0x200 =
512 byte boundaries.
/Ao:nnnn Specifies object alignment; set nnnn in hex or decimal. nnnn must be a power of 2. Default is
0x1000 = 4096 byte boundaries.
/aa Builds a 32-bit Windows application.
/ad Builds a 32-bit Windows device driver.
/ap Builds a 32-bit Windows console application.
/B:xxxx Specifies the image base address and removes the relocation table.
/b:xxxx Specifies the image base address, and preserves DLL relocation table. Successive objects are
aligned on 64K linear address boundaries. Improves load-time and runtime
performance.Recommended for producing DLLs. Default is Off.
/C Refreshes the linker state files. Erases all linker state files before each link; then recreates the files
and continues with the link.
/c Treats case as significant in public and external symbols. Default is On.
/d Delay-loads a DLL. The specified DLL is not loaded or initialized until an entrypoint in the DLL is
actually called.
/D:xxxx Saves the specified description in the PE image.
/Enn Specifies the max. number of errors.
/GC Inserts a comment string ino the image directly after the object table in the PE file header. You can
specify more than one string. Default is Off.
/GD Generates a Delphi compatible RC file (DRC file). Default is Off.
/GF:xxxx Sets image flags.
The xxxx flags are:
• -GF SWAPNET copies the image to a local swap file and runts it from there if the image resides
on a network drive.
• -GF SWAPCD copies the image to a local swap file and runs it if the image resides on
removable media (CD, zip drive).
• -GF UNIPROCESSOR prevents the application from running on a multiprocessor system.
• -GF LARGEADDRESSAWARE tells the OS that the application understands addresses larger
than 4G.
• -GF AGGRESSIVE aggressively trims the workingg seet of an application when the application
is idel (suited for screen savers and other processes that you want to stay out of the way of
main line processes).

/Gk Keeps output files on error. Default is Off.


3
/Gl Generates a .LIB file.
/Gpd Generates design-time-only package. Default is: the package works at both design time and
runtime.
/Gpr Generate runtime-only package Default is: the package works at both design time and runtime.
/Gn Don't generate state files (disable incremental linking). Subsequent links will take just as long as
the first one. Default is Off.

176
3.1 C++ Reference RAD Studio Command Line Utilities

/Gs:string=[EICRWSDKP] Set section flags. Adds the specified flag(s) to the existing flags for a given section, but cannot
remove default flags from a section.
Section flags are:
E = Executable
C = Contains code
I = Contains initialized data
R = Section is readable
W = Section is writable
S = Section is shared
D = Section is discardable
K = Section must not be cached
P = Section must not be paged
Example -GS:.rsrc=W This switch makes the RSRC section writable.
/Gz Calculate checksum of target and insert result in PE header. Used for NT Kernel mode drivers and
system DLLs. Default is Off.
/H:xxxx Specifies application heap reserve size in hex or decimal. Minimum value is 0. This switch
overrides the HEAPSIZE sestting in a module definition file. Default is 1 MB (0x1000000).
/HC:nnnn Specifies application heap commit size.
/I Specifies the directory for intermediate output files. Directs linker state files, but the MAP file and
TDS files are saved in the same directory as the output image, unless otherwise specified for the
MAP file.
/j Specifies object search paths.
Example ILINK32 /jc:\myobjs;.\objs splash .\common\logo,,,utils logolib This command directs the
linker to first search the current directory for SPLASH.OBJ. If the file is not found in the current
directory, the linker then searches the C:\MYOBJS directory, and then the .\OBJs directory.
However, the linker does not use the object search paths to find the file LOGO.OBJ because an
explicit path was given for this file.
/L Specifies the library search path to use if no explicit path is given for the LIB file and the linker
cannot find the LIB file in the current directory.
Example ILINK32 /Lc:\mylibs;.\libs splash .\common\logo,,,utils logolib directs the linker to first
search the current directory for SPLASH.LIB. If the file is not found in the current directory, the
linker then searches the C:\MYLIBS directory, and then the .\LIBs directory. However, the linker
does not use the library search paths to find the file LOGO.LIB because an explicit path was given
for this file.
/M Prints the mangled C++ identifiers in the map file, not the full name.
/m The segments listing has a line for each segment, showing the segment starting address, segment
length, segment name, and the segment class. The public symbols are broken down into two lists,
the first showing the symbols in sorted alphabetically, the second showing the symbols in
increasing address order. Symbols with absolute addresses are tagged Abs. A list of public
symbols is useful when debugging.:Many debuggers use public symbols, which lets you refer to
symbolic addresses while debugging.
/q Suppresses command line banner.
/r Verbose linking. Default is Off. 3
/Rr Replaces resources.
/S:xxxx Specifies application stack reserve size.
/Sc:xxxx Specifies application stack commit size.
/s Produces a detailed map file of segments.
/Tpd Targets a 32-bit Windows DLL file.

177
Command Line Utilities RAD Studio 3.1 C++ Reference

/Tpe Targets a 32-bit Windows EXE file.


/Tpp Generates a package.
/t Displays time spent on link.
/w Turns all warnings on.
/w-dee Disables the warning: “.EXE module built with a .DLL or BPL extension.”
/w-dpl Disables the warning: “Duplicate symbol in library.”.
/w-dup Disables the warning: “Duplicate symbol.”
/w-exp Enables the warning: “Attempt to export non-public symbol..”
/w-nou Disables the warning: “Creating a package without any units.”
/w-rty Enables the warning: “Unable to perform incremental link - performing full link”.
/w-srd Disables the warning: “Stripping relocations from a DLL may cause it to malfunction.”
/w-snf Disables the warning: “Section not found.”
/w-uld Disables the warning: “Unable to load DLL.”
/x Suppresses creation of a MAP file.
(blank) Default map file of segments (no linker switch, map file created by default)

Linker Response Files


You can use response files with the command-line linker to specify linker options.

Response files are ASCII files that list linker options and file names that you would normally type at the command line. Response
files allow you longer command lines than most operating systems support, plus you don't have to continually type the same
information. Response files can include the same information as configuration files, but they also support the inclusion of file
names.

Unlike the command line, a response file can be several lines long. To specify an added line, end a line with a plus character (+)
and continue the command on the next line. Note that if a line ends with an option that uses the plus to turn it on (such as /v+),
the + is not treated as a line continuation character (to continue the line, use /v+ +).

If you separate command-line components (such as .OBJ files from .LIB files) by lines in a response file, you must leave out the
comma used to separate them on the command line.

For example:
/c c0ws+
myprog,myexe +
mymap +
mylib cws
leaves out the commas you'd have to type if you put the information on the command line:
ILINK32 /c c0ws myprog,myexe,mymap,mylib cws
To use response files:
3
1. Type the command-line options and file names into an ASCII text file and save the file. Response files typically have an .RSP
extension.
2. Type: ILINK32 @[<path>]<RESFILE.RSP> where <RESFILE.RSP> is the name of your response file.
You can specify more than one responses file, as follows:
ilink32 /c @listobjs.rsp,myexe,mymap,@listlibs.rsp
Note: You can add comments to response files using semicolons; the linker ignores any text on a line that follows a semicolon.

178
3.1 C++ Reference RAD Studio Command Line Utilities

Module Definition Files


The module definition file is an ASCII text file that provides information to ILINK32 about the contents and system requirements
of a Windows application. You can create a module definition file using IMPDEF.EXE, and you can create import libraries from
module definition files using IMPLIB.EXE.

If no module definition file is specified, the following defaults are assumed:


CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE (for applications)
PRELOAD MOVEABLE SINGLE (for DLLs)
HEAPSIZE 4096
STACKSIZE 1048576
To change an application's attributes from these defaults, you need to create a module definition file.

If you delete the EXETYPE statement, the linker can determine what kind of executable you want to produce from the options
you supply on the command line.

You can include an import library to substitute for the IMPORTS section of the module definition.

You can use the __declspec(dllexport) or _export keywords in the definitions of export functions in your C and C++ source code
to remove the need for an EXPORTS section. Note, however, that if __declspec(dllexport) or _export is used to export a
function, that function is exported by name rather than by ordinal. Please also note that __declspec(dllexport) is the preferred
method of export

Linker-State Files
The four linker-state files have file names of <Project>.IL?, where <Project> is taken from the name of the project .BPR file, and
the character in place of the question mark (?) identifies each of the four individual linker-state files.

Debug Information File


If you include debug information in your final linked executable, ILINK32 will always store the debug information in a separate
.TDS file, named <Project Name>.TDS by default. The debugger should be able to read this debugger-information file. ILINK32
will always create this file. If you do not have the -v linker switch set, the TDS file is marked as invalid.

See Also
RLINK32.EXE ( see page 204)

IMPDEF.EXE ( see page 179)

Module Definition Files ( see page 199)

3.1.1.9 IMPDEF.EXE, the Module Definition Manager


Import libraries provide access to the functions in a Windows DLL. Import libraries contain records. Each record contains the
name of a DLL and specifies where in the DLL the imported functions reside. These records are bound to the application by the
linker and provide Windows with the information necessary to resolve DLL function calls. You can substitute an import library for 3
part or all of the IMPORTS section of a module definition file.

IMPDEF takes as input a DLL name, and produces as output a module definition file with an EXPORTS section containing the
names of functions exported by the DLL.

Command Line Syntax


IMPDEF <options> <destination.def> <source.dll>

179
Command Line Utilities RAD Studio 3.1 C++ Reference

Option Description
-a Adds '_' alias for cdecl functions for compatibility with Microsoft libraries
-h Emits hints

For example:
IMPDEF DestName.DEF SourceName.DLL

To display command line help, enter:


impdef

This creates a module definition file named DestName.DEF from the file SourceName.DLL. The resulting module definition file
would look something like this:
LIBRARY <FileName>
DESCRIPTION '<Description>'
EXPORTS
<ExportFuncName> @<Ordinal>
.
.
.
<ExportFuncName> @<Ordinal>
• <FileName> is the root file name of the DLL.
• '<Description>' is the value of the DESCRIPTION statement if the DLL was previously linked with a module definition file that
included a DESCRIPTION statement.
• <ExportFuncName> names an exported function.
• <Ordinal> is that function's ordinal value (an integer).
Classes in a DLL
IMPDEF is useful for a DLL that uses C++ classes. If you use the __declspec (or _export) keyword when defining a class, all of
the non-inline member functions and static data members for that class are exported. It's easier to let IMPDEF make a module
definition file for you because it lists all the exported functions, and automatically includes the member functions and static data
members.

Since the names of these functions are mangled, it would be tedious to list them all in the EXPORTS section of a module
definition file simply to create an import library from the module definition file. If you use IMPDEF to create the module definition
file, it will include the ordinal value for each exported function. If the exported name is mangled, IMPDEF will also include that
function's unmangled, original name as a comment following the function entry. So, for instance:
LIBRARY <FileName>
DESCRIPTION '<Description>'
EXPORTS
<MangledExportFuncName> @<Ordinal> ; <ExportFuncName>
.
.
.
<MangledExportFuncName> @<Ordinal> ; <ExportFuncName>
3
• <FileName> is the root file name of the DLL.
• '<Description>' is the value of the DESCRIPTION statement if the DLL was previously linked with a module definition file that
included a DESCRIPTION statement.
• <MangledExportFuncName> provides the mangled name.
• <Ordinal> is that function's ordinal value (an integer).
• <ExportFuncName> gives the function's original name.

180
3.1 C++ Reference RAD Studio Command Line Utilities

Functions in a DLL
IMPDEF creates an editable source file that lists all the exported functions in the DLL. You can edit this .DEF file to contain only
those functions that you want to make available to a particular application, then run IMPLIB on the edited .DEF file. This results
in an import library that contains import information for a specific subset of a DLL's export functions.

Suppose you're distributing a DLL that provides functions to be used by several applications. Every export function in the DLL is
defined with __declspec (or _export). Now, if all the applications used all the DLL's exports, then you could use IMPLIB to make
one import library for the DLL. You could deliver that import library with the DLL, and it would provide import information for all of
the DLL's exports. The import library could be linked to any application, thus eliminating the need for the particular application to
list every DLL function it uses in the IMPORTS section of its module definition file.

But suppose you want to give only a few of the DLL's exports to a particular application. Ideally, you want a customized import
library to be linked to that application--an import library that provides import information only for the subset of functions that the
application will use. All of the other export functions in the DLL will be hidden to that client application.

To create an import library that satisfies these conditions, run IMPDEF on the compiled and linked DLL. IMPDEF produces a
module definition file that contains an EXPORT section listing all of the DLL's export functions. You can edit that module
definition file, remove the EXPORTS section entries for those functions you don't want in the customized import library, and then
run IMPLIB on the module definition file. The result will be an import library that contains import information for only those export
functions listed in the EXPORTS section of the module definition file.

See Also
ILINK32.EXE ( see page 174)

IMPLIB.EXE ( see page 181)

Module Definition Files ( see page 199)

3.1.1.10 IMPLIB.EXE, the Import Library Tool


IMPLIB takes as input either DLLs or module definition files, or both, and produces an import library as output.

If you've created a Windows application, you've already used IMPORT32.LIB, the import library for the standard Windows DLLs.
IMPORT32.LIB is linked automatically when you build a Win32 application in the C++Builder IDE and when using BCC32 at the
command line.

An import library lists some or all of the exported functions for one or more DLLs. IMPLIB creates an import library directly from
DLLs or from module definition files for DLLs (or a combination of the two).

Command Line Syntax


IMPLIB <options> <LibName> [< DefFiles>... | <DLLs>... ] [@<ResponseFile> | <sourcename> ]
[<sourcename> ...]

To display command line help, enter:


implib
3

181
Command Line Utilities RAD Studio 3.1 C++ Reference

Command Line Description


Element

<options> An optional list of one or more of the following IMPLIB command options:
• -a Adds '_' alias for cdecl functions for compatibility with Microsoft libraries. If the identifier already
begins with an underscore (_), it is skipped (unless you use the -aa option).
• -aa Forces the creation of an '_' alias for cdecl functions for compatibility with Microsoft libraries. If the
identifier begins with an underscore (_), the -aa option adds a second underscore.
• -c Emits warning on case sensitive symbols.
• -f Forces imports by name.
• -w Emits no warnings.

<LibName> The name for the new import library.


<DefFiles> One or more existing module definition files for one or more DLLs. You must specify at least one DLL or
module definition file.
<DLLs> One or more existing DLLs. You must specify at least one DLL or one module definition file.
@<ResponseFile> An ACSII text file that contains a list of DEF and DLL files that you want to process using IMPLIB. In the
response file, separate the filenames using either spaces or new lines.
<sourcename> Either a DEF or DLL file that is to be processed by IMPLIB.

Example

implib foo.lib @respon.txt

Note: A DLL can also have an extension of .EXE or .DRV, not just .DLL.

See Also
IMPDEF.EXE ( see page 179)

3.1.1.11 Using Include Files


In C++, include files always have the file extension .h.

Include File Search Algorithms


The CodeGear C++ compiler searches for files included in your source code with the #include directive in the following ways:

• If you specify a path and/or directory with your include statement, the compiler searches only the specified location. For
example, if you have the following statement in your code: #include "c:\C++\include\vcl\vcl.h" the header file
vcl.h must reside in the directory C:\C++\include. In addition, if you use the statement: #include <vcl\vcl.h> and you set
the Include option (-I) to specify the path C:\C++\include, the file vcl.h must reside in C:\C++\include\vcl, and not in
C:\C++include or C:\vcl.
• If you put a #include <somefile> statement in your source code, the compiler searches for "somefile" only in the directories
3 specified with the Include (-I) option.
• If you put a #include "somefile" statement in your code, the compiler will search for "somefile" in the following order:
1. The same directory as the file containing the #include statement.
2. The directories of flies that include (#include) that file.
3. The current directory
4. The directories specified with the include (-I) option

182
3.1 C++ Reference RAD Studio Command Line Utilities

Library File Search Algorithms


The library file search algorithms are similar to those for include files:

• Implicit libraries: The CodeGear C++ compiler searches for implicit libraries only in the specified library directories; this is
similar to the search algorithm for: #include “somefile” Implicit library files are the ones the compiler automatically links
in and the start-up object file (C0x.OBJ).
• Explicit libraries: Where the compiler searches for explicit (user-specified) libraries depends in part on how you list the
library file name. Explicit library files are ones you list on the command line or in a project file; these are file names with a .LIB
extension.
• If you list an explicit library file name with no drive or directory (such as MYLIB.LIB), the compiler first searches for that library
in the current directory. If the first search is unsuccessful, the compiler looks in the directories specified with the Library (-L)
option. This is similar to the search algorithm for #include "somefile".
• If you list a user-specified library with drive and/or directory information (like this: c:\mystuff\mylib1.lib), the CodeGear C++
compiler searches only in the location you explicitly listed as part of the library path name and not in any specified library
directories.
See Also
BCC32.EXE ( see page 159)

3.1.1.12 MAKE
MAKE.EXE is a command-line utility that helps you manage project compilation and link cycles. MAKE is not inherently tied to
compiling and linking, but is a more generic tool for executing commands based on file dependencies. MAKE helps you quickly
build projects by compiling only the files you have modified since the last compilation. In addition, you can set up rules that
specify how MAKE should deal with the special circumstances in your builds.

MAKE Basics
MAKE uses rules you write along with its default settings to determine how it should compile the files in your project. For
example, you can specify when to build your projects with debug information and to compile your .OBJ files only if the date/time
stamps of a source file is more recent than the .OBJ itself. If you need to force the compilation of a module, use TOUCH.EXE to
modify the time stamp of one of the module’s dependents.

In an ASCII makefile, you write explicit and implicit rules to tell MAKE how to treat the files in your project; MAKE determines if it
should execute a command on a file or set of files using the rules you set up. Although your commands usually tell MAKE to
compile or link a set of files, you can specify nearly any operating system command with MAKE.

Command Line Syntax


MAKE [<options>...][<target>[<target>]]

You must separate the MAKE command and the options and target arguments with spaces.

When specifying targets, you can use wildcard characters (such as * and ?) to indicate multiple files.

To display command line help, enter:


make —? 3
or:
make —h

Command Line Element Description


[<options>] MAKE options that control how MAKE works. See “Make Command Options” in this topic.

183
Command Line Utilities RAD Studio 3.1 C++ Reference

<target> The name of the target listed in the makefile that you want to build

Default MAKE Actions


When you issue a MAKE command, MAKE looks for the file BUILTINS.MAK, a file that you create to contain the default rules for
MAKE (use the -r option to ignore the default rules). MAKE looks for this file first in the current directory, then in the directory
where MAKE.EXE is stored. After loading BUILTINS.MAK, MAKE looks in the current directory for a file called MAKEFILE or
MAKEFILE.MAK (use the -f option to specify a file other than MAKEFILE). If MAKE can’t find the makefile, it generates an error
message.

After loading the makefile, MAKE tries to build only the first explicit target listed in the makefile by checking the time and date of
the dependent files of the first target. If the dependent files are more recent than the target file, MAKE executes the commands
to update the target.

If one of the first target’s dependent files is used as a target elsewhere in the makefile, MAKE checks that target’s dependencies
and builds it before building the first target. This chain reaction is called a linked dependency.

If something during the build process fails, MAKE deletes the target file it was building. Use the precious directive if you want
MAKE to keep the target when a build fails.

You can stop MAKE after issuing the MAKE command by pressing Ctrl+Break or Ctrl+C

About makefiles
A makefile is an ASCII file that contains the set of instructions that MAKE uses to build a certain project. Although MAKE
assumes your makefile is called MAKEFILE or MAKEFILE.MAK, you can specify a different makefile name with the -f option.

MAKE either builds the target(s) you specify with the make command or it builds the first target it finds in the makefile. To build
more than a single target, use a symbolic target in your makefile.

Makefiles can contain:

• Comments (precede a comment with a number sign [#])


• Explicit and implicit rules
• Macros
• Directives

Symbolic Targets
A symbolic target forces MAKE to build multiple targets in a makefile. When you specify a symbolic target, the dependency line
lists all the targets you want to build (a symbolic target basically uses linked dependencies to build more than one target).

For example, the following makefile uses the symbolic target AllFiles to build both FILE1.EXE and FILE2.EXE:
AllFiles: file1.exe file2.exe #Note that AllFiles has no commands file1.exe: file1.obj
3 bcc32 file1.obj file2.exe: file2.obj bcc32 file2.obj
Rules for symbolic targets

• Do not type a line of commands after the symbolic target line.


• A symbolic target must have a unique name; it cannot be the name of a file in your current directory.
• Symbolic target names must follow the operating system rules for naming files.

184
3.1 C++ Reference RAD Studio Command Line Utilities

BUILTINS.MAK
You can create the optional file BUILTINS.MAK and store in it the standard rules and macros that you want MAKE to use when it
builds the targets in a makefile. To ignore this file when it exists, use the -r MAKE option.

Here is a sample of a BUILTINS.MAK file:


#
# CodeGear C++ BUILTINS.MAK
#

CC = bcc32
RC = brcc32
AS = tasm32

.asm.obj:
$(AS) $(AFLAGS) $&.asm

.c.exe:
$(CC) $(CFLAGS) $&.c

.c.obj:
$(CC) $(CFLAGS) /c $&.c

.cpp.exe:
$(CC) $(CFLAGS) $&.cpp

.cpp.obj:
$(CC) $(CPPFLAGS) /c $&.cpp

.rc.res:
$(RC) $(RFLAGS) /r $&

.SUFFIXES: .exe .obj .asm .c .res .rc

!if !$d(BCEXAMPLEDIR)
BCEXAMPLEDIR = $(MAKEDIR)\..\EXAMPLES

!endif
MAKE Command Options
You can use command-line options to control the behavior of MAKE. MAKE options are case-sensitive and must be preceded
with either a hyphen (-) or slash (/).

You must separate the MAKE command and the options and target arguments with spaces. When specifying targets, you can
use wildcard characters (such as * and ?) to indicate multiple files. To get command-line help for MAKE, type MAKE -?.

For example, to use a file called PROJECTA.MAK as the makefile, type:


MAKE -fPROJECTA.MAK
Many of the command-line options have equivalent directives that you can use within the makefile.

Option Description
-a Checks dependencies of include files and nested include files associated with .OBJ files and updates
the .OBJ if the .h file changed. See also -c.
-B Builds all targets regardless of file dates.

185
Command Line Utilities RAD Studio 3.1 C++ Reference

-c Caches autodependency information, which can improve MAKE speed. Use with -a. Do not use this
option if MAKE modifies include files (which can happen if you use TOUCH in the makefile or if you
create header or include files during the MAKE process).
-D<macro> Defines macro as a single character, causing an expression !ifdef macro written in the makefile to return
true.
-D<macro>=<string> Defines <macro> as <string>. If <string> contains any spaces or tabs, enclose <string> in quotation
marks. The -D is optional.
-d<directory> Specifies the drive and the directory that MAKER (the real mode version of MAKE) uses when it swaps
out of memory. This option must be used with -S. MAKE ignores this option.
-e Ignores a macro if its name is the same as an environment variable. MAKE uses the environment
variable instead of the macro.
-f<filename> Uses <filename> or <fillename>.MAK instead of MAKEFILE (a space after -f is optional).
-h or: -? Help. Displays the MAKE options. Default settings are shown with a trailing plus sign.
-I<directory> Searches for include files in the current directory first, then in the specified directory.
-i Ignores the exit status of all programs run from the makefile and continues the build process.
-K Keeps temporary files that MAKE creates (MAKE typically deletes temporary files).
-m Displays the date and timestamp of each file as MAKE processes it.
-n Prints the MAKE commands but does not perform them. This is helpful for debugging makefiles.
-N Causes MAKE to mimic Microsoft's NMAKE.
-p Displays all macro definitions and implicit rules before executing the makefile.
-q Returns 0 if the target is up-to-date and nonzero if it is not up-to-date (for use with batch files).
-r Ignores any rules defined in BUILTINS.MAK.
-s Suppresses onscreen command display (silent).
-S Swaps MAKER out of memory while commands are executed, reducing memory overhead and allowing
compilation of large modules. MAKE ignores this option.
-U<macro> Undefines the previous macro definition of <macro>.
-W<filename> Writes MAKE to <filename>, updating all non-string options.

See Also
MAKE Macros ( see page 191)

MAKE Directives ( see page 186)

MAKE Rules and Commands ( see page 193)

3.1.1.13 MAKE Directives


3 MAKE directives resemble directives in languages such as C and Pascal. In MAKE, directives perform various control functions,
such as displaying commands onscreen before executing them. MAKE directives begin either with an exclamation point or a
period, and they override any options given on the command line. Directives that begin with an exclamation point must appear at
the start of a new line.

The following table lists the MAKE directives and their corresponding command-line options:

186
3.1 C++ Reference RAD Studio Command Line Utilities

Directive Option Description/Example


(if
available)
.autodepend -a Turns on autodependency checking.
Autodependencies are the files that are automatically included in the targets you build, such
as the header files included in your C++ source code. With .autodepend on, MAKE
compares the dates and times of all the files used to build the .OBJ, including the
autodependency files. If the dates or times of the files used to build the .OBJ are newer than
the date/time stamp of the .OBJ file, the .OBJ file is recompiled. You can use .autodepend
(or -a) in place of forming linked dependencies.
.cacheautodepend -c Turns on autodependency caching.
!cmdswitches Uses + or - followed by non-string option letters to turn each option on or off. Spaces or tabs
must appear before the + or - operator, none can appear between the operator and the
option letters.
!elif Acts like a C else if.
!else Acts like a C else.
!endif Ends an !if, !ifdef, or !ifndef statement
!error Stops MAKE and prints an error message The syntax of the !error directive is: !error
<message>
MAKE stops processing and prints the following string when it encounters this directive:
Fatal makefile exit code: Error directive: <message>
Embed !error in conditional statements to abort processing and print an error message, as
shown in the following example: !if !$d(MYMACRO) #if MYMACRO isn't defined
!error MYMACRO isn't defined ! endif
If MYMACRO isn't defined, MAKE terminates and prints:

Fatal makefile 4: Error directive: MYMACRO isn't defined


Error-Checking Controls: MAKE offers four different error-checking controls:
• The .ignore directive turns off error checking for a selected portion of the makefile.
• The -i command-line option turns off error checking for the entire makefile.
• The -num prefix, which is entered as part of a rule, turns off error checking for the
related command if the exit code exceeds the specified number.
• The - prefix turns off error checking for the related command regardless of the exit code.

!if Begins a conditional statement.


!ifdef Acts like a C #ifdef, testing whether a given macro has been defined.
!ifndef Acts like a C #ifndef, testing whether a given macro is undefined.
.ignore -i MAKE ignores the return value of a command.
!include Acts like a C #include, specifying a file to include in the makefile.
This directive is like the #include preprocessor directive for the C or C++ language -- it lets
you include the text of another file in the makefile: !include <filename>
3
You can enclose the filename in quotation marks (" ") or angle brackets (< >) and nest
directives to unlimited depth, but writing duplicate !include directives in a makefile isn't
permitted -- you'll get the error message cycle in the include file.
Rules, commands, or directives must be complete within a single source file; you can't start
a command in an !include file, then finish it in the makefile. MAKE searches for !include files
in the current directory unless you've specified another directory with the -I command-line
option.

187
Command Line Utilities RAD Studio 3.1 C++ Reference

.keep -K Keeps temporary files that MAKE creates (MAKE usually deletes them).
!message Prints a message to stdout while MAKE runs the makefile
The !message directive lets you send messages to the screen from a makefile. You can use
these messages to help debug a makefile that isn't working properly. For example, if you're
having trouble with a macro definition, you could put this line in your makefile:
!message The macro is defined here as: $(MacroName)
When MAKE interprets this line, it will print onscreen (assuming the macro expands to .CPP):
The macro is defined here as: .CPP
.noautodepend Turns off autodependency checking.
a

.nocacheautodepend Turns off autodependency caching.


c

.noIgnore Turns off .Ignore.


i

.nokeep Does not keep temporary files that MAKE creates.


K

.nosilent Displays commands before MAKE executes them.


s

.noswap Tells MAKE not to swap iteself out of memory before executing a command.
S

.path.ext Tells MAKE to search for files with the extension .ext in path directories
To tell MAKE to look for files with the .c extension in C:\SOURCE or C:\CFILES and to look
for files with the .obj extension in C:\OBJS:
.path.c = C:\CSOURCE;C:\CFILES .path.obj = C:\OBJS
.precious Saves the target or targets even if the build fails If a MAKE build fails, MAKE deletes the
target file. The .precious directive prevents the file deletion, which you might desire for
certain kinds of targets. For example, if your build fails to add a module to a library, you
might not want the library to be deleted. The syntax for .precious is:
.precious: <target> [<target>...]
.silent -s MAKE executes commands without printing them first.

188
3.1 C++ Reference RAD Studio Command Line Utilities

.suffixes Determines the implicit rule for ambiguous dependencies. The .suffixes directive tells MAKE
the order (by file extensions) for building implicit rules. The syntax of .suffixes is:
.suffixes: .<ext> [.<ext> ...]
where .<ext> represents the dependent file extensions you list in your implicit rules.
For example, you could include the line .suffixes: .asm .c .cpp to tell MAKE to
interpret implicit rules beginning with the ones dependent on .ASM files, then .C files, then
.CPP files, regardless of what order they appear in the makefile.
The following .suffixes example tells MAKE to look for a source file first with an .ASM
extension, next with a .C extension, and finally with a .CPP extension. If MAKE finds
MYPROG.ASM, it builds MYPROG.OBJ from the assembler file by calling TASM. MAKE
then calls ILINK32; otherwise, MAKE searches for MYPROG.C to build the .OBJ file or it
searches for MYPROG.CPP.
.suffixes: .asm .c .cpp
myprog.exe: myprog.obj
bcc32 myprog.obj
.cpp.obj:
bcc32 -P -c $<
.asm.obj:
tasm /mx $
.c.obj:
bcc32 -P- -c $<
.swap -S Tells MAKE to swap itself out of memory before executing a command.
!undef Clears the definition of a macro. After this, the macro is undefined. !undef (undefine) causes
an !ifdef MacroName test to fail. The syntax of the !undef directive is:
!undef MacroName

Using Macros in Directives


You can use the $d macro with the !if conditional directive to perform some processing if a specific macro is defined. Follow the
$d with macro name enclosed in parentheses or braces, as shown in the following example:
!if $d(DEBUG) #If DEBUG is defined,
bcc32 -v f1.cpp f2.cpp #compile with debug information;
!else #otherwise
bcc32 -v- f1.cpp f2.cpp #don't include debug information.
!endif

Null Macros
you can substitute the characters .obj for the characters .cpp by using the following MAKE command:
NULLMACRO =
Either of the following lines can define a null macro on the MAKE command line:.
NULLMACRO =""
-DNULLMACRO 3
!if and Other Conditional Directives
The !if directive works like C if statements. As shown here, the syntax of !if and the other conditional directives resembles
compiler conditionals:

189
Command Line Utilities RAD Studio 3.1 C++ Reference

!if condition !if condition !if condition !ifdef macro


!endif !else !elif condition !endif
!endif !endif

The following expressions are equivalent:


!ifdef macro and !if $d(macro)
ifndef macro and !if !$d(macro)
These rules apply to conditional directives:

• One !else directive is allowed between !if, !ifdef, or !ifndef and !endif directives.
• Multiple !elif directives are allowed between !if, !ifdef, or !ifndef, !else and !endif.
• You can't split rules across conditional directives.
• You can nest conditional directives.
• !if, !ifdef, and !ifndef must have matching !endif directives within the same file.
The following information can be included between !if and !endif directives:
• Macro definition
• Explicit rule
• Implicit rule
• Include directive
• !error directive
• !undef directive
In an if statement, a conditional expression consists of decimal, octal, or hexadecimal constants and the operators shown in the
following table:

Operator Description Operator Description


- Negation ?: Conditional expression
~ Bit complement ! Logical NOT
+ Addition >> Right shfit
- Subtraction << Left shift
* Multiplication & Bitwise AND
/ Division | Bitwise OR
% Remainder ^ Bitwise XOR
&& Logical AND >+ Greater than or equal to *
|| Logical OR <+ Less than or equal to *
> Greater than == Equality *
3 < Less than != Inequality *

• The Operator also works with string expressions.


MAKE evaluates a conditional expression as either a 32-bit signed integer or a character string.
See Also
Using MAKE.EXE ( see page 183)

MAKE Macros ( see page 191)

190
3.1 C++ Reference RAD Studio Command Line Utilities

MAKE Rules and Commands ( see page 193)

3.1.1.14 MAKE Macros


A macro is a variable that MAKE expands into a string whenever MAKE encounters the macro in a makefile. For example, you
can define a macro called LIBNAME that represents the string "mylib.lib." To do this, type the line LIBNAME = mylib.lib at the
beginning of your makefile. Then, when MAKE encounters the macro $(LIBNAME), it substitutes the string mylib.lib. Macros let
you create template makefiles that you can change to suit different projects.

To use a macro in a makefile, type $(MacroName) where MacroName is a defined macro. You can use either braces or
parentheses to enclose MacroName.

MAKE expands macros at various times depending on where they appear in the makefile:

• Nested macros are expanded when the outer macro is invoked.


• Macros in rules and directives are expanded when MAKE first looks at the makefile.
• Macros in commands are expanded when the command is executed.
If MAKE finds an undefined macro in a makefile, it looks for an operating system environment variable of that name (usually
defined with SET) and uses its definition as the expansion text. For example, if you wrote $(PATH) in a makefile and never
defined PATH, MAKE would use the text you defined for PATH in your AUTOEXEC.BAT. See your operating system manuals
for information on defining environment variables.
Syntax
<MacroName> = <expansion_text>

Element Description
<MacroName> Is case-sensitive (MACRO1 is different from Macro1). Limited to 512 characters.
<expansion_text> Is limited to 4096 characters. Expansion characters may be alphanumeric, punctuation, or spaces.

You must define each macro on a separate line in your makefile and each macro definition must start on the first character of the
line. For readability, macro definitions are usually put at the top of the makefile. If MAKE finds more than one definition of
MacroName, the new definition overwrites the old one.

You can also define macros using the -D command-line option. No spaces are allowed before or after the equal sign (=);
however, you can define more than one macro by separating the definitions with spaces. The following examples show macros
defined at the command line:
make -Dsourcedir=c:\projecta
make -Dcommand="bcc32 -c"
make -Dcommand=bcc32 option=-c
Note: Macros defined in makefiles overwrite macros defined on the command line.

String Substitution in MAKE Macros


MAKE lets you temporarily substitute characters in a previously defined macro. For example, if you define the following macro:
3
SOURCE = f1.cpp f2.cpp f3.cpp

you can substitute the characters .obj for the characters .cpp by using the following MAKE command:
$(SOURCE:.cpp=.obj)
This substitution does not redefine the macro.

Rules for macro substitution:

• Syntax: $(MacroName:original_text=new_text)

191
Command Line Utilities RAD Studio 3.1 C++ Reference

• No space before or after the colon


• Characters in original_text must exactly match the characters in the macro definition (text is case-sensitive)
MAKE also lets you use macros within substitution macros. For example:
MYEXT=.C
SOURCE=f1.cpp f2.cpp f3.cpp
$(SOURCE:.cpp=$(MYEXT)) #Changes 'f1.cpp' to 'f1.C', etc.
The caret (^) symbol causes MAKE to interpret the next character literally. This is useful for inserting a new-line character. For
example:
MYEXT=.C
SOURCE=f1.cpp f2.cpp f3.cpp
($(SOURCE):.cpp=$(MYEXT)^
) # changes 'f1.cpp f2.cpp f3.cpp' to:
# f1.C
# f2.C
# f3.C
Here, the caret tells MAKE to change each occurrence of .cpp to .C followed by the new-line character.

You can use this to create explicit rules that generate response files for TLIB.EXE. For example:
myfile.lib: file1.obj file2.obj file3.obj
TLIB $@ @&&!
+-$(**: = &^
+-)
!
Here, MAKE substitutes all space characters in the dependency list with a space followed by an ampersand (&) followed by the
new-line character followed by "+-". The resulting response file looks like this:
+-file1.obj &
+-file2.obj &
+-file3.obj &
+-
Default MAKE Macros
MAKE contains several default macros you can use in your makefiles. The following table lists the macro definition and what it
expands to in explicit and implicit rules.

Macro Expands in Implicit Rule Expands in Explicit Rule


$* path\dependent file path\target file
$< path\dependent file+ext path\target file+ext
$: path for dependents path for target
$. dependent file+ext target file + ext
$& dependent file target file
3 $** path\dependent file+ext all dependents file+ext
$? path\dependent file+ext old dependents

Macro Expands to Comment


_ _MSDOS_ _ 1 If running under DOS

192
3.1 C++ Reference RAD Studio Command Line Utilities

_ _MAKE_ _ 0x0370 MAKE's hex version number


MAKE make MAKE's executable file name
MAKEFLAGS options The options typed on the command line
MAKEDIR directory Directory where MAKE.EXE is located

Modifying Default MAKE Macros


If the default macros don't give you the exact string you want, macro modifiers let you extract parts of the string to suit your
purpose. Macro modifiers are usually used with $< or $@.

To modify a default macro, use this syntax:


$(MacroName [modifier])
The following table lists macro modifiers and provides examples of their use:

Modifier Part of File Name Expanded Example Result


D Drive and directory $(<D) C:\PROJECTA\
F Base and extension $(<F) MYSOURCE.C
B Base only $(<B) MYSOURCE
R Drive, directory, and base $(<R) C:\PROJA\SOURCE

See Also
Using MAKE.EXE ( see page 183)

MAKE Directives ( see page 186)

MAKE Rules and Commands ( see page 193)

3.1.1.15 MAKE Rules (Explicit and Implicit) and Commands


You write explicit and implicit rules to instruct MAKE how to build the targets in your makefile. In general, these rules are defined
as follows:

• Explicit rules are instructions for specific files.


• Implicit rules are general instructions for files without explicit rules.
All the rules you write follow this general format:
Dependency line
Command line
While the dependency line has a different syntax for explicit and implicit rules, the command line syntax stays the same for both
rule types.

MAKE supports multiple dependency lines for a single target, and a single target can have multiple command lines. However,
3
only one dependency line should contain a related command line. For example:
Target1: dependent1 dep2 dep3 dep4 dep5
Target1: dep6 dep7 dep8
bcc32 -c $**
Explicit Rule Syntax
Explicit rules specify the instructions that MAKE must follow when it builds specific targets. Explicit rules name one or more
targets followed by one or two colons. One colon means one rule is written for the target(s); two colons mean that two or more

193
Command Line Utilities RAD Studio 3.1 C++ Reference

rules are written for the target(s).

Explicit rules follow this syntax:


<target> [<target>...]:[:][{<path>}] [<dependent[s]>...]
[<commands>]

Element Description
<target> Specifies the name and extension of the file to be built (a target must begin a line in the makefile -- you cannot
precede the target name with spaces or tabs). To specify more than one target, separate the target names with
spaces or tabs. Also, you cannot use a target name more than once in the target position of an explicit rule.
<path> Is a list of directories that tells MAKE where to find the dependent files. Separate multiple directories with
semicolons and enclosed the entire path specification in braces.
<dependent> Is the file (or files) whose date and time MAKE checks to see if it is newer than target. Each dependent file must
be preceded by a space. If a dependent appears elsewhere in the makefile as a target,
MAKE updates or creates that target before using the dependent in the original target (this in known as a linked
dependency).
<commands> Are any operating system command or commands. You must indent the command line by at least one space or
tab, otherwise they are interpreted as a target. Separate multiple commands with spaces.

If a dependency or command line continues on the following line, use a backslash (\) at the end of the first line to indicate that
the line continues. For example:
MYSOURCE.EXE: FILE1.OBJ\ #Dependency line
FILE3.OBJ #Dependency line continued
bcc32 file1.obj file3.obj #Command line

Single Targets with Multiple Rules


A single target can have more than one explicit rule. To specify more than a single explicit rule, use a double colon (::) after the
target name.

The following example shows targets with multiple rules and commands:
.cpp.obj:
bcc32 -c -ncobj $<

.asm.obj:
tasm /mx $<, asmobj\

mylib.lib :: f1.obj f2.obj #double colon specifies multiple rules


echo Adding C files
tlib mylib -+cobjf1 -+cobjf2

mylib.lib :: f3.obj f4.obj


echo Adding ASM files
tlib mylib -+asmobjf3 -+asmobjf4
3 Implicit Rule Syntax
An implicit rule specifies a general rule for how MAKE should build files that end with specific file extensions. Implicit rules start
with either a path or a period. Their main components are file extensions separated by periods. The first extension belongs to the
dependent, the second to the target.

If implicit dependents are out-of-date with respect to the target, or if the dependents don't exist, MAKE executes the commands
associated with the rule. MAKE updates explicit dependents before it updates implicit dependents.

Implicit rules follow this basic syntax:

194
3.1 C++ Reference RAD Studio Command Line Utilities

[{>source_dir>}].<source_ext>[{target_dir}].<target_ext>:
[<commands>]

Element Description
<source_dir> Specifies the directory (or directories) containing the dependent files. Separate multiple directories with a
semicolon.
.<source_ext> Specifies the dependent filename extension.
<target_dir> Specifies the directory where MAKE places the target files. The implicit rule will only be used for targets in
this directory. Without specifying a target directory, targets from any directory will match the implicit rule.
.<target_ext> Specifies the target filename extension. Macros are allowed here.
: (colon) Marks the end of the dependency line.
<commands> Are any operating system command or commands. You must indent the command line by at least one
space or tab; otherwise they are interpreted as a target.

If two implicit rules match a target extension but no dependent exists, MAKE uses the implicit rule whose dependent's extension
appears first in the .SUFFIXES list.

Explicit Rules with Implicit Commands


A target in an explicit rule can get its command line from an implicit rule. The following example shows an implicit rule followed
by an explicit rule without a command line:
.c.obj:
bcc32 -c $< #This command uses a macro $< described later
myprog.obj: #This explicit rule uses the command: bcc32 -c myprog.c
The implicit rule command tells MAKE to compile MYPROG.C (the macro $< replaces the name myprog.obj with myprog.c).

MAKE Command Syntax


Commands immediately follow an explicit or implicit rule and must begin on a new line with a space or tab. Commands can be
any operating system command, but they can also include MAKE macros, directives, and special operators that your operating
system won’t recognize (however, note that | can't be used in commands).

Here are some sample commands:


cd..
bcc32 -c mysource.c
COPY *.OBJ C:\PROJECTA
bcc32 -c $(SOURCE) #Macros in "Using MAKE macros"
Commands follow this general syntax:
[<prefix>...] <commands>
Command Prefixes

Commands in both implicit and explicit rules can have prefixes that modify how MAKE treats the commands. The following table
lists the prefixes you can use in makefiles:
3
Prefix Description
@ Does not display the command while it's being executed.
-<num> Stops processing commands in the makefile when the exit code returned from command exceeds the integer num.
Normally, MAKE aborts if the exit code is nonzero. No space is allowed between - and <num>.
- Continues processing commands in the makefile, regardless of the exit codes they return.

195
Command Line Utilities RAD Studio 3.1 C++ Reference

& Expands either the macro $**, which represents all dependent files, or the macro $?, which represents all dependent
files stamped later than the target. Execute the command once for each dependent file in the expanded macro.
! Behaves like the & prefix.

Using @

The following command uses the @ prefix, which prevents MAKE from displaying the command onscreen:
diff.exe : diff.obj
@bcc32 diff.obj
Using -<num> and —

The prefixes -<num> and - (hyphen) control the makefile processing when errors occur. You can choose to continue with the
MAKE process if any error occurs, or you can specify a number of errors to tolerate.

In the following example, MAKE continues processing if BCC32 returns errors:


target.exe : target.obj
target.obj : target.cpp
-bcc32 -c target.cpp
Using &

The & prefix issues a command once for each dependent file. It is especially useful for commands that don't take a list of files as
parameters. For example:
copyall : file1.cpp file2.cpp
&copy $** c:\temp
invokes COPY twice, as follows:
copy file1.cpp c:\temp
copy file2.cpp c:\temp
Without the & modifier, MAKE would call COPY only once. Note: the & prefix only works with $** and $! macros.

MAKE Command Operators


While you can use any operating system command in a MAKE command section, you can also use the following special
operators:

Operator Description
< Use input from a specified file rather than from standard input.
> Send the output from command to file.
>> Append the output from command to file.
<< Create a temporary inline file and use its contents as standard input to command. Also, create temporary
response file when -N is used. Note: this is only for use with Microsoft's NMAKE.
&& Create a temporary response file and insert its name in the makefile.
<delimiter> Use delimiters with temporary response files. You can use any character other than # as a delimiter. Use << and
3 && as a starting and ending delimiter for a temporary file. Any characters on the same line and immediately
following the starting delimiter are ignored. The closing delimiter must be written on a line by itself.

See Also
Using MAKE.EXE ( see page 183)

MAKE Macros ( see page 191)

MAKE Directives ( see page 186)

196
3.1 C++ Reference RAD Studio Command Line Utilities

3.1.1.16 Message Options


Use the -w option to specify message options for the CodeGear C++ compiler:

• To enable a particular warning message, enter the -w option with a one- to three-letter option code.
• To disable the warning message, enter the -w- option with a one- to three- letter option code.
Examples
To display all warning and error messages, include the -w command option in your BCC32 command:
-w
To enable reporting of the warning "Mixing pointers to different 'char' types" (option code ucp, Default OFF), include the following
flag in your BCC32 command:
-wucp
To disable reporting of the warning "Declaration ignored" (option code dig, Default ON), include the following flag in your BCC32
command:
-w-dig
To display help on the warning message codes, enter a compiler command that contains only the -h and -w options:
bcc32 -h -w
CodeGear C++ 5.92 for Win32 Copyright (c) 1993, 2007 CodeGear
Available options (* = default setting, xxx = has sub-options: use -h -X):
(Note: -X- or -w-XXX will usually undo whatever was set or unset by -X)
-w Display all warnings
-w! Return non-zero from compiler on warnings
-wamb 8000 Ambiguous operators need parentheses
-wamp 8001 Superfluous & with function
* -wasc 8002 Restarting compile using assembly
-wasm 8003 Unknown assembler instruction
* -waus 8004 '%s' is assigned a value that is never used
* -wali 8086 Incorrect use of #pragma alias "aliasName"="substituteName"
* -watr 8100 '%s' attribute directive ignored
-wbbf 8005 Bit fields must be signed or unsigned int
* -wbei 8006 Initializing %s with %s
* -wbig 8007 Hexadecimal value contains too many digits
* -wccc 8008 Condition is always %s
-wcln 8009 Constant is long
* -wcom 8010 Continuation character \ found in // comment
* -wcpt 8011 Nonportable pointer comparison
* -wcsu 8012 Comparing signed and unsigned values
* -wcod 8093 Incorrect use of #pragma codeseg [seg_name] ["seg_class"] [grou

-wdef 8013 Possible use of '%s' before definition


* -wdig 8014 Declaration ignored
* -wdpu 8015 Declare '%s' prior to use in prototype
* -wdsz 8016 Array size for 'delete' ignored
* -wdup 8017 Redefinition of '%s' is not identical
* -weas 8018 Assigning %s to %s
* -weff 8019 Code has no effect 3
* -wext 8020 '%s' is declared as both external and static
-wexc 8101 Extern C linkage ignored
* -whch 8021 Handler for '%s' hidden by previous handler for '%s'
* -whid 8022 '%s' hides virtual function '%s'
* -wias 8023 Array variable '%s' is near
* -wibc 8024 Base class '%s' is also a base class of '%s'
* -will 8025 Ill-formed pragma
-winl 8026 Functions %s are not expanded inline
-winl 8027 Functions containing %s are not expanded inline

197
Command Line Utilities RAD Studio 3.1 C++ Reference

* -wifr 8085 Function '%s' redefined as non-inline


-wimp 8102 Implicit conversion of '%s' to '%s'
* -wlin 8028 Temporary used to initialize '%s'
* -wlvc 8029 Temporary used for parameter '%s'
* -wlvc 8030 Temporary used for parameter '%s' in call to '%s'
* -wlvc 8031 Temporary used for parameter %d
* -wlvc 8032 Temporary used for parameter %d in call to '%s'
* -wmpc 8033 Conversion to '%s' will fail for members of virtual base '%s'
* -wmpd 8034 Maximum precision used for member pointer type '%s'
* -wmsg 8035 %s
* -wmes 8095 Incorrect use of #pragma message( "string" )
* -wmcs 8096 Incorrect use of #pragma code_seg(["seg_name"[,"seg_class"]])
* -wmcc 8098 Multi-character character constant
-wnak 8036 Non-ANSI keyword used: '%s'
-wnak 8036 Non-ANSI keyword used: '%s'
* -wncf 8037 Non-const function %s called for const object
* -wnci 8038 Constant member '%s' is not initialized
* -wncl 8039 Constructor initializer list ignored
* -wnfd 8040 Function body ignored
* -wngu 8041 Negating unsigned value
* -wnin 8042 Initializer for object '%s' ignored
* -wnma 8043 Macro definition ignored
* -wnmu 8044 #undef directive ignored
-wnod 8045 No declaration for function '%s'
* -wnop 8046 Pragma option pop with no matching option push
* -wnsf 8047 Declaration of static function '%s(...)' ignored
* -wnst 8048 Use qualified name to access member type '%s'
* -wntd 8049 Use '< <' for nested templates instead of '<<'
* -wnto 8050 No type OBJ file present. Disabling external types option.
* -wnvf 8051 Non-volatile function %s called for volatile object
* -wnpp 8083 Pragma pack pop with no matching pack push
* -wobi 8052 Base initialization without a class name is now obsolete
* -wobs 8053 '%s' is obsolete
* -wofp 8054 Style of function definition is now obsolete
* -wosh 8055 Possible overflow in shift operation
* -wovf 8056 Integer arithmetic overflow
* -wonr 8097 Not all options can be restored at this time
* -wpar 8057 Parameter '%s' is never used
* -wpch 8058 Cannot create pre-compiled header: %s
* -wpck 8059 Structure packing size has changed
* -wpia 8060 Possibly incorrect assignment
-wpin 8061 Initialization is only partially bracketed
* -wpow 8062 Previous options and warnings not restored
* -wpre 8063 Overloaded prefix 'operator %s' used as a postfix operator
* -wpro 8064 Call to function with no prototype
* -wpro 8065 Call to function '%s' with no prototype
-wprc 8084 Suggest parentheses to clarify precedence
* -wpcm 8094 Incorrect use of #pragma comment( <type> [,"string"] )
* -wpsb 8099 Static `main' is not treated as an entry point
* -wrch 8066 Unreachable code
* -wret 8067 Both return and return with a value used
* -wrng 8068 Constant out of range in comparison
* -wrpt 8069 Nonportable pointer conversion
* -wrvl 8070 Function should return a value
-wsig 8071 Conversion may lose significant digits
* -wspa 8072 Suspicious pointer arithmetic
3 -wstu 8073 Undefined structure '%s'
-wstv 8074 Structure passed by value
* -wsus 8075 Suspicious pointer conversion
-wstl 8087 '%s::operator==' must be publicly visible to be contained by a '% s'
-wstl 8089 '%s::operator<' must be publicly visible to be contained by a '%s'
-wstl 8090 '%s::operator<' must be publicly visible to be used with '%s'
-wstl 8091 %s argument %s passed to '%s' is a %s iterator: %s iterator required
-wstl 8092 %s argument %s passed to '%s' is not an iterator: %s iterator required
* -wtai 8076 Template instance '%s' is already instantiated
* -wtes 8077 Explicitly specializing an explicitly specialized class member makes no sense

198
3.1 C++ Reference RAD Studio Command Line Utilities

* -wthr 8078 Throw expression violates exception specification


-wucp 8079 Mixing pointers to different 'char' types
-wuse 8080 '%s' is declared but never used
* -wvoi 8081 void functions may not return a value
* -wzdi 8082 Division by zero

3.1.1.17 Module Definition Files


You use module definition files with ILINK32. A module definition file is an ASCII text file that provides information to ILINK32
about the contents and system requirements of a Windows application. Use IMPDEF to create a module definition file.

The module definition file names the .EXE or .DLL, identifies the application type, lists imported and exported functions,
describes the code section and data segment attributes, lets you specify attributes for additional code sections and data
segments, specifies the size of the stack, and provides for the inclusion of a stub program.

CODE Statement
Defines the default attributes of code sections. Code sections can have any name, but must belong to section classes whose
name ends in CODE (such as CODE or MYCODE).
CODE [PRELOAD | LOADONCALL]
[EXECUTEONLY | EXECUTEREAD]
• PRELOAD means code is loaded when the calling program is loaded.
• LOADONCALL (the default) means the code is loaded when called by the program.
• EXECUTEONLY means a code section can only be executed.
• EXECUTEREAD (the default) means the code section can be read and executed.
• FIXED (the default) means the section remains at a fixed memory location.
• MOVEABLE means the sction can be moved.
• DISCARDABLE means the section can be discarded if it is no longer needed (this implies MOVEABLE).
• NONDISCARDABLE (the default) means the section can not be discarded.
DATA Statement
Defines attributes of data segments:
DATA [NONE | SINGLE | MULTIPLE]
[READONLY | READWRITE]
[PRELOAD | LOADONCALL]
[SHARED | NONSHARED]
• NONE means that there is no data section created. This option is available only for libraries.
• SINGLE (the default for .DLLs) means a single data section is created and shared by all processes.
• MULTIPLE (the default for .EXEs) means that a data section is created for each process.
• READONLY means the data section can be read only.
• READWRITE (the default) means the data section can be read and written to.
• PRELOAD means the data section is loaded when a module that uses it is first loaded. 3
• LOADONCALL (the default) means the data section is loaded when it is first accessed. (LOADONCALL is ignored for 32-bit
applications.)
• SHARED means one copy of the data section is shared among all processes.
• NONSHARED (the default for programs .DLLs) means a copy of the data section is loaded for each process needing to use
the data section.

199
Command Line Utilities RAD Studio 3.1 C++ Reference

DESCRIPTION Statement (optional)


Inserts text into the application module and is typically used to embed author, date, or copyright information:
DESCRIPTION 'Text'
Text is an ASCII string delimited with single quotes.

EXETYPE Statement
Defines the default executable file (.EXE) header type for applications. You can leave this section in for 32-bit applications for
backward compatibility, but if you need to change the EXETYPE, see the NAME statement.
EXETYPE [WINDOWAPI] | [WINDOWCOMPAT]
• WINDOWAPI is a Windows executable, and is equivalent to the ILINK32 option -aa.
• WINDOWCOMPAT is a Windows-compatible character-mode executable, and is equivalent to the ILINK32 option -ap.
EXPORTS Statement
Defines the names and attributes of functions to be exported. The EXPORTS keyword marks the beginning of the definitions. It
can be followed by any number of export definitions, each on a separate line.
EXPORTS
<EsportName> [<Ordinal>]
[RESIDENTNAME] [<Parameter>]
• <ExportName> specifies an ASCII string that defines the symbol to be exported as follows: <EntryName>
[=<InternalName>] <EntryName> is the name listed in the executable file's entry table and is externally visible.
<InternalName> is the name used within the application to refer to this entry.
• <Ordinal> defines the function's ordinal value as follows: @<ordinal> where <ordinal> is an integer value that
specifies the function's ordinal value. When an application or DLL module calls a function exported from a DLL, the calling
module can refer to the function by name or by ordinal value. It is faster to refer to the function by ordinal because string
comparisons aren't required to locate the function. To use less memory, export a function by ordinal (from the point of view of
that function's DLL) and import/call a function by ordinal (from the point of view of the calling module). When a function is
exported by ordinal, the name resides in the nonresident name table. When a function is exported by name, the name resides
in the resident name table. The resident name table for a module is in memory whenever the module is loaded; the
nonresident name table isn't.
• RESIDENTNAME specifies that the function's name must be resident at all times. This is useful only when exporting by
ordinal (when the name wouldn't be resident by default).
• <Parameter> is an optional integer value that specifies the number of words the function expects to be passed as
parameters.
HEAPSIZE Statement
Defines the number of bytes the application needs for its local heap. An application uses the local heap whenever it allocates
local memory.
HEAPSIZE <Reserve>[, <Commit>]
• <Reserve> can be a decimal or hex value, the default of which is 1MB. To help with backward (16-bit) compatibility for 32-bit
ports, the linker uses the default value of 1MB if you specify in the .DEF ile a reserve value less than 64K.
• <Commit> is a decimal or hex value. The commit size is optional, and if not specified defaults to 4K. The minimum commit
3 size you can specify is 0. In addition, the specified or default commit size must always be smaller or equal to the reserve size.
Reserved memory refers to the maximum amount of memory that can be allocated either in physical memory or in the paging
file. In other words, reserved memory specifies the maximum possible heap size. The operating system guarantees that the
specified amount of memory will be reserved and, if necessary, allocated.
The meaning of committed memory varies among operating systems. In Windows NT, commited memory refers to the amount of
physical memory allocated for the heap at application load/initialization time. Committed memory causes space to be
allocated either in physical memory or in the paging file. A higher commit value saves time when the application needs more
heap space, but increases memory requirements and possible startup time.

200
3.1 C++ Reference RAD Studio Command Line Utilities

You can override any heap reserve or commit size specified in the .DEF file with the -H or -Hc ILINK32 command-line options. -H
lets you specify a heap reserve size less than the 64K minimum allowed in the .DEF file.
IMPORTS Statement
Defines the names and attributes of functions to be imported from DLLs. The IMPORTS keyword marks the beginning of the
definitions followed by any number of import definitions, each on a separate line.
IMPORTS [<InternalName>=]<ModuleName>.<Entry>
• <InternalName> is an ASCII string that specifies the unique name the application uses to call the function.
• <ModuleName> specifies one or more uppercase ASCII characters that define the name of the executable module containing
the function. The module name must match the name of the executable file. For example, the file SAMPLE.DLL has the
module name SAMPLE.
• <Entry> specifies the function to be imported--either an ASCII string that names the function or an integer that gives the
function's ordinal value.
Instead of listing imported DLL functions in the IMPORTS statement, you can either specify an import library for the DLL in the
ILINK32 command line, or include the import library for the DLL in the project manager in the IDE.
You must use either __declspec(dllimport) or __import to import any function, class, or data you want imported. The prefered
method is to use __declspec(dllimport)
The IMPORTS keyword can also be applied to (global) variables, as follows:
[ in the dll source file (dll.cpp) ] int sample = 100;

[ dll.def ] EXPORTS _sample

[ in application source file (app.cpp) ]


int _declspec(dllimport) sample;

[ app.def ]
IMPORTS
dll._sample
LIBRARY Statement
Defines the name of a DLL module. A module definition file can contain either a LIBRARY statement to indicate a .DLL or a
NAME statement to indicate a .EXE. A library's module name must match the name of the executable file. For example, the
library MYLIB.DLL has the module name MYLIB.
LIBRARY <LibrarName> [INITGLOBAL | INITINSTANCE]
• <LibraryName> (optional) is an ASCII string that defines the name of the library module. If you don't include a LibraryName,
ILINK32 uses the file name with the extension removed. If the module definition file includes neither a NAME nor a LIBRARY
statement, ILINK32 assumes a NAME statement without a ModuleName parameter.
• INITGLOBAL means the library-initialization routine is called.
• INITINSTANCE means the library-initialization routine is called each time a new process uses the library.
NAME Statement
Is the name of the application's executable module. The module name identifies the module when exporting functions. NAME
must appear before EXETYPE. If NAME and EXETYPE don't specify the same target type, the linker uses the type listed with
NAME. 3
NAME <ModuleName> [WINDOWSAPI] | [WINDOWCOMPAT]
• <ModuleName> (optional) specifiesone or more uppercase ASCII characters that name the executable module. The name
must match the name of the executable file. For example, an application with the executable file SAMPLE.EXE has the
module name SAMPLE. If <ModuleName> is missing, ILINK32 assumes that the module name matches the file name of the
executable file. For example, if you do not specify a module name and the executable file is named MYAPP.EXE, ILINK32
assumes that the module name is MYAPP. If the module definition file includes neither a NAME nor a LIBRARY statement,
ILINK32 assumes a NAME statement without a <ModuleName> parameter.

201
Command Line Utilities RAD Studio 3.1 C++ Reference

• WINDOWSAPI specifies a Windows executable, and is equivalent to the ILINK32 option -aa.
• WINDOWCOMPAT specifies a Windows-compatible character-mode executable, and is equivalent to the ILINK32 option -ap.
SECTIONS Statement
Lets you set attributes for one or more section in the image file. you can use this You can use this statement to override the
default attributes for each different type of section.
SECTIONS<section_name> [CLASS '<ClassName>'] <attributes>
• SECTIONS marks the beginning of a list of section definitions.
• After the SECTIONS keyword, each section definition must be listed on a separate line. Note that the SECTIONS keyword
can be on the same line as the first definition or on a preceding line. In addition, the .DEF file can contain one or more
SECTIONS statements. The SEGMENTS keyword is supported as a synonym for SECTIONS.
• <ClassName> is case sensitive. The CLASS keyword is supported for compatibility but is ignored.
• <Attributes> is one or more of the following: EXECUTE, READ, SHARED, and WRITE.
SEGMENTS Statement
Defines the attributes of additional code and data sections. The SEGMENTS keyword is supported as a synonym for
SECTIONS. The syntax is:
SEGMENTS

<SegmentName> [CLASS '<ClassName>']

[<MinAlloc>]
[SHARED | NONSHARED]
[PRELOAD | LOADONCALL]
• <SegmentName> is a character string that names the new segment. It can be any name, including the standard segment
names _TEXT and _DATA, which represent the standard code and data segments.
• <ClassName> (optional) is the class name of the specified segment. If no class name is specified, ILINK32 uses the class
name CODE.
• <MinAlloc> (optional) is an integer that specifies the minimum allocation size for the segment. ILINK32 ignores this value.
• SHARED means one copy of the segment is shared among all processes.
• NONSHARED (the default for .EXEs and .DLLs) means a copy of the segment is loaded for each process needing to use the
data segment.
• PRELOAD means that the segment is loaded immediately.
• LOADONCALL means that the segment is loaded when it is accessed or called (this is ignored by ILINK32). The Resource
Compiler may override the LOADONCALL option and preload segments instead.
STACKSIZE Statement
Defines the number of bytes the application needs for its local stack. An application uses the local stack whenever it makes
function calls.
STACKSIZE <Reserve>[, <Commit>]
• <Reserve> can be a decimal or hex value, the default of which is 1MB. To help with backward (16-bit) compatibility, the linker
3 uses the default value of 1MB if you specify in the .DEF file a reserve value less than 64K.
• <Commit> is a decimal or hex value. The commit size is optional, and if not specified defaults to 8K. The minimum commit
size you can specify is 4K. In addition, the specified or default commit size must always be smaller or equal to the reserve
size.
Reserved memory refers to the maximum amount of memory that can be allocated either in physical memory or in the paging
file. In other words, reserved memory specifies the maximum possible stack size.
The operating system guarantees that the specified amount of memory will be reserved and, if necessary, allocated.

202
3.1 C++ Reference RAD Studio Command Line Utilities

The meaning of committed memory varies among operating systems. In Windows NT, commited memory refers to the amount of
physical memory allocated for the stack at application load/initialization time. Committed memory causes space to be
allocated either in physical memory or in the paging file. A higher commit value saves time when the application needs more
stack space, but increases memory requirements and possible startup time.
You can override any stack reserve or commit size specified in the .DEF file with the ILINK32 -S or -Sc command-line options. -S
lets you specify a stack reserve size less than the 64K minimum allowed in the .DEF file.
Note: Do not use the STACKSIZE statement when compiling .DLLs.
STUB Statement
Appends a DOS executable file specified by FileName to the beginning of the module. The executable stub displays a warning
message and terminates if the user attempts to run the executable stub in the wrong environment (running a Windows
application under DOS, for example).
STUB '<FileName>'
• <FileName> is the name of the DOS executable file to be appended to the module. The name must have the DOS file name
format. If the file named by FileName is not in the current irectory, ILINK32 searches for the file in the directories specified by
the PATH environment variable.
C++Builder adds a built-in stub to the beginning of a Windows application unless a different stub is specified with the STUB
statement. You should not use the STUB statement to include WINSTUB.EXE because the linker does this automatically.
SUBSYSTEM Statement
Lets you specify the Windows subsystem and subsystem version number for the application being linked.
SUBSYSTEM [<subsystem>,]<subsystemID>
• <Subsystem> (optional) can be any one of the following values: WINDOWS, WINDOWAPI, WINDOWCOMPAT. If you do not
specify a subsystem, the linker defaults to a WINDOWS subsystem.
• <SubsystemID> must use the format d.d where d is a decimal number. For example, if you want to specify Windows 4.0, you
could use either one of the following two SUBSYSTEM statements: SUBSYSTEM 4.0 SUBSYSTEM WINDOWS 4.0
You can override any SUBSYSTEM statement in a .DEF file using the -a and -V ILINK32 command-line options.
See Also
ILINK32 ( see page 174)

IMPDEF ( see page 179)

3.1.1.18 Using Precompiled Header Files


Precompiled header files can dramatically increase compilation speed by storing an image of the symbol table on disk in a file,
then later reloading that file from disk instead of parsing all the header files again. Directly loading the symbol table from disk is
much faster than parsing the text of header files, especially if several source files include the same header file.

To use precompiled header files, specify the various -H options in your BCC32 command.

Precompiled Header Options

Compiler Description Details 3


Option
-H Generate When you enable this option, the compiler generates and uses precompiled headers. The
and use default file name is BC32DEF.CSM for the command-line compiler.
-Hu Use but do When you enable this option, the compiler uses preexisting precompiled header files; new
not generate precompiled header files are not generated.

203
Command Line Utilities RAD Studio 3.1 C++ Reference

Do not When you enable this option, the compiler does not generate or use precompiled headers.
H generate or Default = Do not generate or use (-H-)
use
-Hc Cache When you enable this option, the compiler caches the precompiled headers it generates. This
precompiled is useful when you are precompiling more than one header file. To use this option, you must
headers also enable the Generate and Use (-H) precompiled header option. Default = Off.
-He Generate When you enable this option, the compiler generates a file or files that contain debug type
external type information for all the symbols contained in the precompiled headers. The filenames end with
files .#xx extension, where xx is 00 for the first file generated and is incremented for each additional
(precompiled type-information file required. Using this option dramatically decreases the size of your .OBJ
headers) files, because debug type information is centralized and is not duplicated in each .OBJ file.
Default = On.
-H=<filename> Precompiled Use this option to specify the name of your precompiled header file. When you set this option,
header the compiler generates and uses the precompiled header file that you specify.
filename
-Hh=<xxx> or Stop This option terminates compiling the precompiled header after processing the file specified as
-H\”<xxx>\” precompiling xxx. You can use this option to reduce the disk space required for precompiled headers.
after header The -Hh syntax is generally easier to use than the -H syntax. Examples:
file option
-Hh=myhdr.h
-H\"myhdr.h\"
-Hh="C:\Program Files\myhdr.h"
-H\"C:\Program Files\myhdr.h\"
When you use this option, the file you specify must be included from a source file for the
compiler to generate a precompiled header file.
You can also use #pragma hdrstop in your source file to specify when to stop the generation of
precompiled headers.
You cannot specify a header file that is included from another header file. For example, you
cannot list a header included by windows.h because doing this would cause the precompiled
header file to be closed before the compilation of windows.h was completed.

See Also
ILINK32.EXE ( see page 174)

3.1.1.19 RLINK32.DLL, the Resource Linker (C++)


RLINK32.DLL is the resource linker that binds resources, in .RES file form, to an .EXE file, and marks the resulting .EXE file as a
Windows executable. RLINK32.DLL also:

• Links the resources by fixing up string tables and message tables and then binding these linked resources into the
executable.
• Is called by ILINK32 and is used for 32-bit resources.
See Also
3
BRC32.EXE ( see page 163)

ILINK32.EXE ( see page 174)

3.1.1.20 TDUMP.EXE, the File Dumping Utility


TDUMP.EXE produces a file dump that shows the structure of a file.

204
3.1 C++ Reference RAD Studio Command Line Utilities

TDUMP breaks apart a file structurally and uses the file's extension to determine the output display format. TDUMP recognizes
many file formats, including .EXE, .OBJ, and .LIB files. If TDUMP doesn't recognize an extension, it produces a hexadecimal
dump of the file. You can control the output format by using the TDUMP command-line options when you start the program.

TDUMP's ability to peek at a file's inner structure displays not only a file's contents, but also how a file is constructed. Moreover,
because TDUMP verifies that a file's structure matches its extension, you can also use TDUMP to test file integrity.

Command Line Syntax


TDUMP [<options>] <inputfile> [<listfile>] [<options>]

• <inputfile> is the file whose structure you want to display (or “dump”).
• <listfile> is an optional output filename (you can also use the standard DOS redirection command (>).
• <options> are any of the TDUMP command line options.
To display command line help, enter:
tdump
You can use either the / or the - switch character. For example, these two commands are equivalent:
TDUMP -e1 -v demo.exe
TDUMP /el /v demo.exe
TDUMP Options

Option Description
-a, -a7 TDUMP automatically adjusts its output display according to the file type. You can force a file to be displayed as ASCII
by including the -a or -a7 option.
-a produces an ASCII file display, which shows the offset and the contents in displayable ASCII characters. A
character that is not displayable (like a control character) appears as a period.
-a7 converts high-ASCII characters to their low-ASCII equivalents. This is useful if the file you are dumping sets
high-ASCII characters as flags (WordStar files do this).
-b# Allows you to display information beginning at a specified offset. For example, if you want a dump of MYFILE starting
from offset 100, you would use: TDUMP -b100 MYFILE
-C Causes TDUMP to dump information found in COFF format files (.OBJ and .LIB). This option is useful when linking
with Microsoft .OBJ and .LIB files.
-d Causes TDUMP to dump any CodeGear 32-bit debug information found in the .OBJ file. If you do not specify this
option, TDUMP displays raw data only.

205
Command Line Utilities RAD Studio 3.1 C++ Reference

-e, -el, All four options force TDUMP to display the file as an executable (.EXE) file.
-er, An .EXE file display consists of information contained within a file that is used by the operating system when loading a
-ex file. If symbolic debugging information is present (Turbo Debugger or Microsoft CodeView), TDUMP displays it.
TDUMP displays information for DOS executable files, NEW style executable files ( Microsoft Windows and OS/2
.EXEs and DLLs ), Linear Executable files, and Portable Executable (PE) files used by Windows NT and Windows
95/98 and Windows 2000.
• -e Displays file as Executable (EXE/DLL, DOS, Win16, OS/2, PE)
• -ea[:v] Displays All Exports unsorted, or (:v) sort by RVA (default dumps only named exports, sorting on the
name) a[:v] Displays All Exports unsorted, or (:v) sort by RVA (default dumps only named exports, sorting on the
name)
• -ed Disables EXE debug information
• -ee[=x] Lists Exports only from EXE/DLL (optional x lists matches only)
• -el Suppresses line numbers in the display
• -eiID Includes only .EXE table ID (HDR, OBJ, FIX, NAM, ENT)
• -em[=x] Lists Imports only from EXE/DLL (optional x lists matches only)
• -em.[x] Lists Imported modules only from EXE/DLL (optional x search string)
• -ep Disables EXE PE header display
• -er Prevents the relocation table from displaying
• -ex Prevents the display of New style executable information. This means TDUMP only displays information for
the DOS "stub" program

-h Displays the dump file in hexadecimal (hex) format. Hex format consists of a column of offset numbers, 16 columns of
hex numbers, and their ASCII equivalents (a period appears where no displayable ASCII character occurs).
If TDUMP doesn't recognize the input file's extension, it displays the file in hex format (unless an option is used to
indicate another format).
-i Specifies the debug table(s) to use.
-l, -li, Displays the output file in library (.LIB) file format. A library file is a collection of object files (see the -o option for more
-le on object files). The library file dump displays library-specific information, object files, and records in the object file.
The -li option tells TDUMP to display a short form of "impdef" records when dumping import libraries. You can also
specify a search string using the following syntax:
-li=<string>
For example, this command:
tdump —li=codeptr import32.lib
results in the following output:
Impdef:(ord) KERNEL32.0336=ISBADCODEPTR
This output shows that the function is exported by ordinal, whose ordinal value is 336 (decimal). In addition, the output
displays the module and function name.
If you enter the following command:
tdump —li=walk import32.lib
3 TDUMP displays:
Impdef:(name) KERNEL32.????=HEAPWALK
This shows the output of a function exported by name.
-le Tells TDUMP to display a short form of the "expdef" records when dumping OBJ files. You can also specify a search
string using the following syntax: -le=<string>
-m Leaves C++ names occurring in object files, executable files, and Turbo Debugger symbolic information files in
"mangled" format. This option is helpful in determining how the C++ compiler "mangles" a given function name and its
arguments.

206
3.1 C++ Reference RAD Studio Command Line Utilities

o, -oc, • -o displays the file as an object (.OBJ) file. An object file display contains descriptions of the command records
-oi, that pass commands and data to the linker, telling it how to create an .EXE file. The display format shows each
-ox record and its associated data on a record-by-record basis.
• -oc causes TDUMP to perform a cyclic redundancy test (CRC) on each encountered record. The display differs
from the -o display only if an erroneous CRC check is encountered (the TDUMP CRC value differs from the
record's CRC byte).
• -oi<id> includes only specified record types in the object module dump. Replace <id> with the name of the record
to be displayed. For instance: TDUMP -oiPUBDEF MYMODULE.OBJ produces an object module display for
MYMODULE.OBJ that displays only the PUBDEF records.
The -ox and -oi options are helpful in finding errors that occur during linking. By examining the spelling and case of
the EXTDEF symbol and the PUBDEF symbol, you can resolve many linking problems. For instance, if you
receive an "unresolved external" message from the linker, use TDUMP -oiEXTDEF to display the external
definitions occurring in the module causing the error. Then, use TDUMP -oiPUBDEF on the module containing the
public symbol the linker could not match.
Another use for the -oi switch is to check the names and sizes of the segments generated in a particular module. For
instance: TDUMP -oiSEGDEF MYMODULE.OBJ displays the names, attributes, and sizes of all of the segments
in MYMODULE.
Note: To get a list of record types for -oi and -ox, use the command line options -oi? and -ox?.

-r Causes TDUMP to display raw data.


-R Causes TDUMP to dump relocation tables from 32-bit PE (Win32) format images. The default is to suppress these
dumps.

207
Command Line Utilities RAD Studio 3.1 C++ Reference

-s, Tells TDUMP to display strings. By default -s displays all strings in a given file. You can specify a string, or part of a
-su, string, using the following syntax:
-s[xx] -s=<string>
For example, the command:
TDUMP -s=black GoGame.exe
results in the following output of all strings containing 'black':
56840: IDI_BLACK
81965: Capture Black
85038: black.bmp
The optional string argument is case insensitive. To specify several words of a string, use quotes. For example:
TDUMP -s="game of go" GoGame.exe
The -su option is used in the same manner, with an optional string argument, and tells TDUMP to display Unix-style
strings, meaning with no offset.
For example, the command:
TDUMP -su=black GoGame.exe
results in the following output:
IDI_BLACK
Capture Black
black.bmp
For the -s[xx] switch, xx can be:
• # - minimum string length to look for (default: 4)
• b# - Beginning file offset (-b# is the same as -sb#)
• e# - Ending file offset
• f - Format (wrap) long strings
• s - Search string with case sensitivity (default: no)
• u - unix format: no offset (or decimal offsets, -h for hex)
• =x - search string = x

-um Displays mangled names as unmangled. You do not need to reformat the text to edit out only the mangled names
before using this option. You can pass output that has mangled names anywhere in the text, and only the mangled
names will be affected.
-v Verbose display. If used with an .OBJ or .LIB file, TDUMP produces a hexadecimal dump of the record's contents
without any comments about the records.
If you use TDUMP on a Turbo Debugger symbol table, it displays the information tables in the order in which it
encounters them. TDUMP doesn't combine information from several tables to give a more meaningful display on a
per-module basis.
-x Specifies the debug table(s) to exclude.

3 3.1.1.21 TLIB.EXE, the Library Manager


TLIB is a utility that manages libraries of .OBJ (object module) files. A library is a convenient way to deal with a collection of
object modules as a unit.

The libraries included with the CodeGear C++ compiler were built with TLIB. You can use TLIB to build your own libraries, or to
modify the CodeGear C++ libraries, your libraries, libraries furnished by other programmers, or commercial libraries you've
purchased.

208
3.1 C++ Reference RAD Studio Command Line Utilities

When TLIB modifies an existing library, TLIB creates a copy of the original library and gives it a .BAK extension.

You can use TLIB to:

• Create a new library from a group of object modules.


• Add object modules or other libraries to an existing library.
• Remove object modules from an existing library.
• Replace object modules from an existing library.
• Extract object modules from an existing library.
• List the contents of a new or existing library.
TLIB can also create (and include in the library file) an extended dictionary, which can be used to speed up linking.
Although TLIB is not essential for creating executable programs with the CodeGear C++ compiler, it is a useful programming
productivity tool that can be indispensable for large development projects.
Command Line Syntax
TLIB <libname> [<options>] [<operations>] [@<respfile>] [, <listfile>]

To display command line help, enter:


tlib

Element Description
<libname> The DOS path name of the library you want to create or manage. Every TLIB command must be given a
libname. Wildcards are not allowed. TLIB assumes an extension of .LIB if none is given. Use only the .LIB
extension because both BCC32 and the IDE require the .LIB extension in order to recognize library files. Note: If
the named library does not exist and there are add operations, TLIB creates the library.
<options> TLIB accepts five general options (C, L, P, O, and 8) as well as five default action options (a, d, e, u, and x). See
the headings immediately following this table for details about the TLIB <options> and about the default action
options.
<operations> Describes the actions you want TLIB to do and consists of a sequence of two-character operation codes. If you
only want to examine the contents of the library, do not give any operations. For more information, see the
heading later in this topic.
@<respfile> The path and name of the response file you want to include. You can specify more than one response file. For
more details, see the heading later in this topic.
<listfile> The name of the text file that TLIB will produce to hold a listing of the library contents. The listfile name (if given),
must be preceded by a comma. No listing is produced if you don't give a file name. The listing is an alphabetical
list of each module. The entry for each module contains an alphabetical list of each public symbol defined in that
module. The default extension for the listfile is .LST.

TLIB General Command Options


TLIB recognizes five <options>:
3
• /C (case-sensitive; see further information below)
• /l (produces a listing file on standard output)
• /P (page size; see further information below)
• /0 (zero; purges comment records)
• /8 (displays warnings and messages encoded as UTF8)

209
Command Line Utilities RAD Studio 3.1 C++ Reference

TLIB /C Option: Using Case-Sensitive Symbols in a Library


When you add a module to a library, TLIB maintains a dictionary of all public symbols defined in the modules of the library. All
symbols in the library must be distinct. If you try to add a module to the library that duplicates a symbol, TLIB displays an error
message and doesn't add the module.

Normally, when TLIB checks for duplicate symbols in the library, uppercase and lowercase letters are not treated differently (for
example, the symbols lookup and LOOKUP are treated as duplicates). You can use the /C option to add a module to a library
that includes symbols differing only in case.

Don't use /C if you plan to use the library with other linkers or let other people use the library.

TLIB normally rejects symbols that differ only in case because some linkers aren't case-sensitive. ILINK32 has no problem
distinguishing uppercase and lowercase symbols. As long as you use your library only with ILINK32, you can use the TLIB /C
option without any problems.

TLIB /P option: Setting the Page Size to Create a Large Library


The library page size determines the maximum combined size of all object modules in the library, which cannot exceed 65,536
pages. The default (and minimum) page size of 16 bytes allows a library of about 1 MB in size. To create a larger library, use the
/P option to increase the page size. The page size must be a power of 2, and it cannot be smaller than 16 or larger than 32,768.

All modules in the library must start on a page boundary. For example, in a library with a page size of 32 (the lowest possible
page size higher than the default 16), an average of 16 bytes will be lost per object module in padding. If you attempt to create a
library that is too large for the given page size, TLIB will issue an error message and suggest that you use /P with the next
available higher page size.

TLIB Default Action Options


The default action options allow you to specify an action or several actions that are used for every subsequent module that does
not have an explicit command specified, or until a different action flag is set. Using the default action options enables you to
specify modules in a TLIB command without having to prefix each module with a command or action symbol. The TLIB default
action options perform actions similar to those performed by the TLIB operation flags described in TLIB Operations List.

TLIB Default Action Options

Symbol Description
/a Add the module to the library.
/d Remove the module from the library.
/e Extract the module without removing it.
/u Replace the module in the library.
/x Extract the module and remove it.

TLIB Operations List


The operation list describes the actions you want TLIB to do and consists of a sequence of operations given one after the other.
3 Each operation consists of a one- or two-character action symbol followed by a file or module name.:
<symbol> modulename
You can put whitespace around either the action symbol or the file or module name, but not in the middle of a two-character
action or in a name. You can put as many operations as you like on the command line, up to DOS's COMMAND.COM-imposed
line-length limit of 127 characters. The order of the operations is not important. TLIB always applies the operations in a specific
order:

To replace a module, remove it, then add the replacement module.

210
3.1 C++ Reference RAD Studio Command Line Utilities

1. All extract operations are done first.


2. All remove operations are done next.
3. All add operations are done last.
TLIB finds the name of a module by stripping any drive, path, and extension information from the given file name.
Note that TLIB always assumes reasonable defaults. For example, to add a module that has an .OBJ extension from the current
directory, you need to supply only the module name, not the path and .OBJ extension.
Wildcards are never allowed in file or module names.
TLIB recognizes three action symbols (*, +, -), which you can use singly or combined in pairs for a total of five distinct operations.
The order of the characters is not important for operations that use a pair of characters.
To create a library, you add modules to a library that does not yet exist.
TLIB Action Symbols

Symbol Name Description


+ Add TLIB adds the named file to the library. If the file has no extension, TLIB assumes an extension of .OBJ. If
the file is itself a library (with a .LIB extension), then the operation adds all of the modules in the named
library to the target library.
If a module being added already exists, TLIB displays a message and does not add the new module.
— Remove TLIB removes the named module from the library. If the module does not exist in the library, TLIB displays
a message.
A remove operation needs only a module name. TLIB lets you enter a full path name with drive and
extension included, but ignores everything except the module name.
* Extract TLIB creates the named file by copying the corresponding module from the library to the file. If the module
does not exist, TLIB displays a message and does not create a file. If the named file already exists, it is
overwritten.
You can't directly rename modules in a library. To rename a module, extract and remove it, rename the file
just created, then add it back into the library.
—* or Extract TLIB copies the named module from the library to the file. If the module does not exist, TLIB displays a
*— and message and does not create a file. If the named file already exists, it is overwritten. TLIB removes the file
remove name and then removes it from the library.
—+ or Replace TLIB replaces the named module with the corresponding file.
+—

Using TLIB Response Files


A response file is an ASCII text file that contains all or part of a TLIB command. Using TLIB response files, you can build TLIB
commands that are longer than one command line. If you need to perform a large number of operations or perform operations
several times, response files can make your job easier.

Response files can:

• Contain more than one line of text; use the ampersand character (&) at the end of a line to indicate that another line follows.
• Include a partial list of commands. You can combine options from the the command line with options in a response file.
• Be used with other response files in a single TLIB command line. 3
TLIB Examples
These simple examples demonstrate some of the different things you can do with TLIB:

Example 1

To create a library named MYLIB.LIB with modules X.OBJ, Y.OBJ, and Z.OBJ, type:
tlib mylib +x +y +z

211
Command Line Utilities RAD Studio 3.1 C++ Reference

Example 2

To create a library named MYLIB.LIB and get a listing in MYLIB.LST too, type:
tlib mylib +x +y +z, mylib.lst
Example 3

To get a listing in CS.LST of an existing library CS.LIB, type:


tlib cs, cs.lst
Example 4

To replace module X.OBJ with a new copy, add A.OBJ and delete Z.OBJ from MYLIB.LIB, type:
tlib mylib -+x +a -z
Example 5

To extract module Y.OBJ from MYLIB.LIB and get a listing in MYLIB.LST, type:
tlib mylib *y, mylib.lst
Example 6

To create a new library named ALPHA, with modules A.OBJ, B.OBJ, ..., G.OBJ using a response file:

1. First create a text file, ALPHA.RSP, with: +a.obj +b.obj +c.obj & +d.obj +e.obj +f.obj & +g.obj
2. Then use the TLIB command, which produces a listing file named ALPHA.LST: tlib alpha @alpha.rsp, alpha.lst
Example 7
To update modules Y.OBJ and Z.OBJ and delete modules A.OBJ and B.OBJ from MYLIB.LIB:
tlib mylib /u Y.obj Z.obj /d A.obj B.obj

3.1.1.22 Using TOUCH.EXE


TOUCH.EXE updates a file's date stamp so that it reflects your system’s current time and date.

Command Line Syntax


touch [<options>] <filename> [<filename>...]

If TOUCH cannot find a file that matches the name you specify, it creates a zero-length file with the correct date stamp. To
suppress automatic file creation, use the -c option.

Because TOUCH is a 32-bit executable, it accepts long file names. In addition, you can use file names that contain the wildcard
characters * and ? to “touch” more than a single file at a time. Use the -s option to update matching files in all subdirectories.

Before you use TOUCH, make sure your system's internal clock is set correctly.

TOUCH Options
TOUCH.EXE supports several command line options.
3 TOUCH Options

Option Description
-c Don't generate file if it doesn't already exist.
-d<mm>-<dd>-<yy> Sets the date of the file to the specified date.
-r<filename> Sets the time and date of file to match those of <filename>.
-h Displays help information (same as typing TOUCH without options or filenames.

212
3.1 C++ Reference RAD Studio Command Line Utilities

-s Recurses through subdirectories.


t<hh>:<mm>:<ss>- Sets the time of the file to the specified time.
-v Verbose mode. Shows each file that has been TOUCHed.

See Also
Using MAKE ( see page 183)

3.1.1.23 TRIGRAPH
Trigraphs are three-character sequences that replace certain characters used in the C language that are not available on some
keyboards. Translating trigraphs in the compiler would slow compilation down considerably, so CodeGear C++ provides a filter
named TRIGRAPH.EXE to handle trigraph sequences.

Command Line Syntax


trigraph [-u] <filename> [...]

TRIGRAPH Options
TRIGRAPH has three command options:

• -nXXX writes output files to the directory named in XXX.


• -u means to Undo insert trigraphs.
• -xXXX creates output files with the extension XXX.
The following table shows the trigraph sequences the TRIGRAPH recognizes:
TRIGRAPH Character Sequences
The following table shows the trigraph sequences the TRIGRAPH recognizes:

Trigraph Character
??= #
??( [
??) ]
??/ \
??' ^
??< {
??> }
??- ~

3.1.1.24 RC.EXE, the Microsoft SDK Resource Compiler 3

RC is the command-line version of the standard Microsoft SDK resource compiler. It accepts a resource script file (.RC) as input
and produces a resource object file (.RES) as output.

Both C++Builder 2009 and Delphi 2009 give you a choice of resource compilers. On the Project Options Resource
Compiler dialog box, you can select either of the following:

• BRCC32.exe, the CodeGear resource compiler

213
Command Line Utilities RAD Studio 3.1 C++ Reference

• RC.exe, the Microsoft platform SDK Resource Compiler


RC supports Unicode characters in resource files and file names, as well as new Vista resource types such as icons with alpha
channel.
The actual filename of the RC compiler in the RAD Studio environment is ERC.exe.
Differences Between BRCC32 and RC
If you choose to use RC, several differences between BRCC32 and RC need to be addressed in existing .RC files, as follows:

• To use Windows types or constants with RC, you need to explicitly #include <winresrc.h> for both C++ and Delphi.
• RC does not handle image data inline as BRCC32 does. To use an image with RC, you need to save the image and refer to
the image inline.
• RC handles line continution differently than BRCC32. The simplest change is to combine strings with embedded newlines (\n).
• For RC, the order of command elements requires that all command options must come first, before the name of the resource
file.
• RC does not allow trailing commas after the string in a STRINGLIST.
• RC treats strings as C-style strings. This means that you need to do either of the following:
• Escape a single backslash (\) in filenames by using a double backslash (\\).
• Use a forward slash (/) in place of a single backslash (\).
• For RC, specifying #include <dirname> does not search the current directory. To search the current directory, use
#include "dirname".
• To embed a double-quote character in a string, use two consecutive double-quote characters ("") instead of using the
backslash escape character.
• RCDATA and byte values are handled differently. For example:
• BRCC32 treats '11 aa 22 bb' as a string of bytes.
• For RC, you would need to specify 0xaa11 0xbb22.
See Also
BRC32.EXE ( see page 163)

Microsoft Resouce Compiler

Using RC Compiler to Build Resources

Compiling Resources with RC - From Digital Mars

Resource Compiler Options

3.1.1.25 WSDLIMP.EXE, the Command Line WSDL Import Tool


WSDLIMP generates code to represent the types and APIs that a WSDL document defines. This code can be used to write client
applications that call on the Web Service that the WSDL (Web Services Description Language) document describes. If you want
to write a server that implements the Web Service, one of the command line options tells the importer to generate
3 implementation classes that you can then complete by filling in the bodies of the generated methods.

Note: WSDLIMP ignores any definitions in the WSDL document for which it can't generate code. That is, it can only import Web
Services that use SOAP or document literal encoding.

Borland WSDLIMP Version 2.3 - $Rev: 16699 $


Copyright (c) 2008 Borland Software Corporation
Usage: WSDLIMP [options] <WSDL[File|URL]|UDDI BindingKey>

214
3.1 C++ Reference RAD Studio Command Line Utilities

Code Generation Options:


-C Generate C++ code -P Generate Pascal code
[ -option{+|-} default shown ]
-Oa- Process optional/nillable elements -Op+ Process inc/imported schemas
-Od+ Generate Complex Type Destructors -Oq- Quiet mode (Suppress Headers)
-Of- Process Faults -Og- Use OLE GUIDs for interface
-Oi- Ignore Schema errors -Os- Generate Server skeleton code
-Ok- Map pure collections to classes -Ot- Output unused types
-Ol- Generate Literal types -Ou+ Unwrap Literal Parameters
-Om- Allow out parameters -Ov+ Verbose Info. in file
-On- Declare Types in Namespace -Ow+ Map strings to WideStrings
-Oo+ One out param becomes return -Ox+ Strong class Aliases
Other options:
-D<path> Output directory path -=+ Output filename after'=' in URL
-U<url of UDDI Registry> UDDI Registry [NOTE: input must be UDDI bindingkey(s)

@<Resp> Response file with list of WSDL|UDDIBindingKey to import

Proxy/Server Authentication:
-user:userName -pass:Password [-proxy:Proxy]
WSDLIMP.EXE imports a WSDL document, generating the code that lets your application call on the Web Service that the
WSDL document describes. This is the command-line version of the Web Services importer, which is available on the Web
Services tab of the new items dialog.

You can configure the output using the WSDLIMP command-line options when you start the program. These options let you
specify whether the importer generates Object Pascal or C++ code, whether you want to generate implementation classes
because you are writing a server, and how to handle various types of definitions in the WSDL document.

WSDLIMP Command Line Syntax


The command-line syntax for WSDLIMP is:
WSDLIMP [<options>] <Inputfile|URL>
<Inputfile> is a physical WSDL document to import.

<URL> is the URL for accessing a WSDL document that is published on the Web.

<options> stand for any of the WSDLIMP command-line options.

WSDLIMP Command Line Options


The following table lists the command-line options for WSDLIMP:

Options Description
-C Generate C++ code to represent the definitions in the WSDL file. You must use either this option or the –P
option, but not both.
-P Generate Object Pascal code to represent the definitions in the WSDL file. You must use either this option or
the –C option, but not both.
-S Generate implementation classes for the APIs that the WSDL document defines. This option is used when you
want to write a server that implements the Web Service that the WSDL document describes.
-Oa When the importer encounters a type that maps to a class with no members, change the imported code to an 3
array. This option exists because in some cases when the WSDL document does not make consistent use of
schema definitions, the importer has problems importing array types, which results in a type that is represented
by a class with no members. This option is always safe to use unless the WSDL document describes a Web
Service that uses document literal encoding. Document literal encoding can also give rise to an empty class
when a method has no return value.
-Oi Ignore ill-formed schemas when importing the WSDL document and attempt to import the Web Service
anyway. This allows the importer to handle cases where the WSDL document is not completely well-formed but
the intent is clear.

215
C++ Compiler Errors And Warnings (C++) RAD Studio 3.1 C++ Reference

-Oo Treat methods with a single output parameter as functions, mapping the single output parameter to the return
value.
-Oq Do not generate a header comment at the top of each generated file. The header comments indicate what
options were used, list any warnings about the generated code, and so on.
-Oi Generate type definitions for the two types that represent the input and output of a call when the Web Service
uses document literal encoding. This option is only used with the –Ou+ option. When you do not specify –Ou+,
the two type definitions are always generated.
-Ou+ Unwind the literal parameters of document literal encoding to generate method calls. When this option is
selected, the importer converts the two types that
-Ov Unwind the literal parameters of document literal encoding to generate method calls. When this option is
selected, the importer converts the two types that
-Ov Generate code comments (verbose information).
-R:<namelist> Map strings in the WSDL document to the WideString type. WideStrings are more robust, because they can
handle extended characters, but they are not as efficient as using AnsiStrings (the default).
-D<path> Specifies the directory where WSDLIMP writes the files that it generates.
@<path> Specifies a text file where each line lists a URL or WSDL file to import. You can optionally add
'=OutputFileName' after the URL or file name to specify where to place the generated code for each imported
WSDL document.

See Also
Using the Web Services Importer ( see page 2302)

3.1.2 C++ Compiler Errors And Warnings (C++)


This section describes the RAD Studio C++ compiler error and warning messages.

Topics
Name Description
E2066: Invalid MOM inheritance (C++) ( see page 256) The compiler issues this error if the currently compiled class doesn't have the
same MOM (Microsoft Object Model) related flags set as its direct parent.
This compiler error message is deprecated.
E2525: You must define _PCH_STATIC_CONST before including xstring to use You attempted to use a feature defined in xstring, part of the Dinkumware
this feature (C++) ( see page 257) standard C++ library. The C++ compiler could not generate a precompiled
header because there is a constant (defined in xstring) in the header. If you want
to include xstring, you should first set the define _PCH_STATIC_CONST.
E2526: Property 'name' uses another property as getter/setter; Not allowed (C++) Properties typically have both a getter and a setter, but a property cannot serve
( see page 257) as either the getter or setter of another property.
E2008: Published property access functions must use __fastcall calling The calling convention for access functions of a property (read, write, and stored)
convention (C++) ( see page 257) declared in a __published section must be __fastcall. This also applies to hoisted
properties.
E2122: Function call terminated by unhandled exception 'value' at address 'addr' This message is emitted when an expression you are evaluating while debugging
(C++) ( see page 257) includes a function call that terminates with an unhandled exception. For
3 example, if in the debugger's evaluate dialog, you request an evaluation of the
expression foo()+1 and the execution of the function foo() causes a GP fault, this
evaluation produces the above error message.
You may also see this message in the watches window because it also displays
the results of evaluating an expression.
E2506: Explicit specialization of 'specifier' is ambiguous: must specify template In the following code, explicit template arguments are necessary:
arguments (C++) ( see page 257)

216
3.1 C++ Reference RAD Studio C++ Compiler Errors And Warnings (C++)

E2483: Array dimension 'specifier' could not be determined (C++) ( see page If, during instantiation of a type, an array dimension cannot be
258) computed—usually this is due to some other error which would be
reported—then this error will result.
For example, if an array dimension is dependent upon a template parameter but
an error occurs while it is being parsed and the template argument being
substituted does not yield a legal constant expression, this error is displayed.
E2509: Value out of range (C++) ( see page 258) The inline assembler has detected a numeric overflow in one of your
expressions. Make sure all of your numbers can fit in 32 bits.
E2510: Operand size mismatch (C++) ( see page 258) Help is not available for this item.
E2050: __declspec(delphireturn) class 'class' must have exactly one data This is an internal compiler error. A class marked as a delphireturn class has
member (C++) ( see page 258) more than one non-static data member.
E2530: Unrecognized option, or no help available (C++) ( see page 258) You have entered a command element that the C++ compiler cannot parse, or
the option you entered has no associated help. Try again.
E2527: Option 'name' cannot be set via 'name' (C++) ( see page 258) An attempt was made in a source file to set an option that cannot be set after
either parsing or compiling of the file starts. Instead, set this option on the
command line or in a .cfg file.
For example, if a source file contains a #pragma option push —v, you need
to remove the push or set /unset this option either on the command line or in a
.cfg file.
E2528: Option 'name' must be set before compilation begins (C++) ( see page An attempt was made in a source file to set an option that must be set before
258) compiling starts. Instead, set this option on the command line, in a .cfg file, or
at the top of the source file before the line int foo(); .
E2074: Value after -g or -j should be between 0 and 255 inclusive (C++) ( see Both the -g and the -j command line options can be followed by an optional
page 259) number. The compiler expects this number to be between 0 and 255 inclusive.
E2492: Properties may only be assigned using a simple statement, e.g. \"prop = Assignments to properties should be made in simple assignment statements. If
value;\" (C++) ( see page 259) property assignments could become Lvalues, which happens when property
assignments are embedded in larger statements, the getter is called to create the
Lvalue, with all the side effects that getter causes. The compiler allows only one
call to either the getter or the setter in a statement.
For example:
E2505: Explicit instantiation requires an elaborated type specifier (i.e.,"class The following code is illegal:
foo<int>") (C++) ( see page 259)
E2100: Invalid template declarator list (C++) ( see page 259) It is illegal for a declarator list to follow a template class declaration. For example:
E2102: Cannot use template 'template' without specifying specialization The generic form of a template must be referenced using specialization
parameters (C++) ( see page 260) parameters. For example, for a template class named foo, taking two template
parameters, then a legal reference might have the form
E2107: Invalid use of template 'template' (C++) ( see page 260) This error results when attempting to use a template template parameter in any
way other than to reference a template specialization, or to pass that parameter
in turn as a template template argument to another template. For example:
E2105: 'template' qualifier must specify a member template name (C++) ( see When parsing code that depends in some way upon a template parameter, it is
page 260) sometimes impossible to know whether a member name will resolve to a
template function name, or a regular parameter. In the following code, a
'template' qualifier is required in order to know if the '<' (less-then) operator
should be parsed as the beginning character of a template argument list, or as a
regular less-than operator:
E2066: Information not available (C++) ( see page 261) Help is not available for this item.
E2471: pragma checkoption failed: options are not as expected (C++) ( see You can use #pragma checkoption to check that certain switches are in the state
page 261) that you expect. If #pragma checkoption detects that a switch is not in the
expected state, the compiler displays this error.
You can use the following syntax:
E2504: 'dynamic' can only be used with non-template member functions (C++) You tried to use dynamic with a template member function. Dynamic functions
( see page 261) are allowed for classes derived from TObject. Dynamic functions occupy a slot in
every object that defines them, not in any descendants. That is, dynamic
functions are virtual functions stored in sparse virtual tables. If you call a dynamic
function, and that function is not defined in your object, the virtual tables of its
ancestors are searched until the function is found.
E2191: '__far16' may only be used with '__pascal' or '__cdecl' (C++) ( see This is an internal compiler error. The compiler emits this message if the keyword
page 261) __far16 is mixed with one of the keywords __pascal or __cdecl, all in the same 3
declaration.
E2199: Template friend function 'function' must be previously declared (C++) ( Not used
see page 262)

217
C++ Compiler Errors And Warnings (C++) RAD Studio 3.1 C++ Reference

E2502: Error resolving #import: problem (C++) ( see page 262) Where problem can be any of the following relating to problems with the various
attributes of #include ( see page 692):
unexpected import directive value attribute 'attribute'A value was supplied for the
indicated attribute. None was expected.
missing ')' in import directive attribute 'attribute'The value for the indicated
attribute was incorrectly specified : a closing parenthesis is missing.
unrecognized import directive attribute 'attribute'The indicated token is not a
legitimate attribute for the #import directive.
invalid values for raw_property_prefixes attributeThe values for the
raw_property_prefixes attribute were incorrectly specified.
unexpected duplicate property 'property'The indicated #import attribute was
specified more than once -- this is an... more ( see page 262)
E2501: Unable to open import file 'filename' (C++) ( see page 262) This error occurs when you use:
E2494: Unrecognized __declspec modifier (C++) ( see page 262) A _declspec modifier was given that is not valid.
E2493: Invalid GUID string (C++) ( see page 263) The GUID string does not have the form of a Globally Unique Identifier.
E2499: Invalid __declspec(uuid(GuidString)) format (C++) ( see page 263) This error happens when you used the wrong format to define your GuidString.
GUIDs are defined for structs in the following way:
E2496: Invalid call to uuidof(struct type|variable) (C++) ( see page 263) The uuidof operator was given an incorrect argument.
E2511: Unterminated macro argument (C++) ( see page 263) A macro argument that was started on the line listed has not been properly
terminated
E2489: Maximum option context replay depth exceeded; check for recursion If this error is triggered, it means that recursive template instantiation has gone
(C++) ( see page 263) too deep. Check for compile-time recursion in your program, and limit it to no
more than 256 levels.
E2488: Maximum token reply depth exceeded; check for recursion (C++) ( see If this error is triggered, it means that recursive template instantiation has gone
page 263) too deep. Check for compile-time recursion in your program, and limit it to no
more than 256 levels.
E2491: Maximum VIRDEF count exceeded; check for recursion (C++) ( see Too many VIRDEF symbols were allocated. The compiler imposes a limit to the
page 263) number of VIRDEFs allowed per translation unit. Currently this limit is in the order
of 16384 VIRDEFs.
One way this could happen is if a program has more than 16384 functions.
E2230: In-line data member initialization requires an integral constant expression Static const class members, which are initialized in the body of the class, have to
(C++) ( see page 264) be initialized with a constant expression of integral type.
E2241: VCL style classes need virtual destructors (C++) ( see page 264) Destructors defined in VCL style classes have to be virtual.
E2524: Anonymous structs/unions not allowed to have anonymous members in The C++ compiler requires that the members of an anonymous struct or union be
C++ (C++) ( see page 264) named.
E2246: x is not abstract public single inheritance class hierarchy with no data Internal compiler error. In some cases, the compiler will enforce restrictions on a
(C++) ( see page 264) class hierarchy. In this case, the restrictions would be that all classes are abstract
classes, and all classes only have one parent.
E2249: = expected (C++) ( see page 264) The compiler expected an equal sign in the position where the error was reported
but there was none. This is usually a syntax error or typo.
E2267: First base must be VCL class (C++) ( see page 264) Internal compiler error. In some cases, the compiler will enforce restrictions on a
class hierarchy. In this case, the restrictions would be that the first parent of a
class is a Delphi style class.
E2472: Cannot declare a member function via instantiation (C++) ( see page If a declaration within a template class acquires a function type through a type
265) dependent on a template-parameter and this results in a declaration that does
not use the syntactic form of a function declarator to have function type, the
program is ill-formed. For example:
E2515: Cannot explicitly specialize a member of a generic template class (C++) You are trying to make a generic template into a specialized member. For
( see page 265) example, the following code is illegal:
E2474: 'function' cannot be declared as static or inline (C++) ( see page 265) You attempted to declare a symbol as static or inline and this type of symbol
cannot be defined as static or inline. Certain functions, like 'main' and 'WinMain'
cannot be declared static or inline. 'main' is the entrypoint of console applications,
and 'WinMain' is the entry point of Windows applications.
For example, this error is displayed in the following cases:
E2498: Need previously defined struct GUID (C++) ( see page 266) This happens when you use the __uuidof operator without including a header
3 that defines the GUID struct. So the following program code would display this
error:
E2295: Too many candidate template specializations from 'specifier' (C++) ( When reference a class template specialization, it is possible that more than one
see page 266) possible candidate might result from a single reference. This can only really
happen among class partial specializations, when more than one partial
specialization is contending for a possible match:
E2475: 'function' cannot be a template function (C++) ( see page 266) Certain functions, like 'main' and 'WinMain' cannot be declared as a template
function. 'main' is the entrypoint of console applications, and 'WinMain' is the
entry point of Windows applications.
For example:

218
3.1 C++ Reference RAD Studio C++ Compiler Errors And Warnings (C++)

E2299: Cannot generate template specialization from 'specifier' (C++) ( see This error will result if an attempt is made to reference a template class or
page 267) function in a manner which yields no possible candidate specializations. For
example:
E2300: Could not generate a specialization matching type for 'specifier' (C++) ( This error is no longer generated by the compiler.
see page 267)
E2497: No GUID associated with type:'type' (C++) ( see page 267) A variable or type was used in a context requiring a GUID, but the type does not
have a GUID associated with it. GUIDs are associated with types using
_declspec (uuid(GUID)).
E2522: Non-const function 'function' called for const object (C++) ( see page Data type mismatch resulting in an erroneous function call. The object of the call
267) (a non-const function) should be a const object.
E2523: Non-volatile function 'name' called for volatile object (C++) ( see page Data type mismatch. The error is the result of an erroneous function call. The
267) object of the call (a non-volatile function) should be a volatile object.
E2513: Cannot emit RTTI for 'parameter' in 'function' (C++) ( see page 267) The compiler issues this error if it cannot generate RTTI information for the return
type of a parameter. See Runtime type information for more information.
E2512: Cannot emit RTTI for return type of 'function' (C++) ( see page 267) The compiler issues this error if the it cannot generate RTTI information for the
return type of a function. See Runtime type information for more information.
E2507: 'class' is not a direct base class of 'class' (C++) ( see page 268) The first type is not a direct base class of the second type. A direct base class
refers to the immediate derivations of that class, and not the derivations of its
subclasses.
E2529: Path 'path' exceeds maximum size of 'n' (C++) ( see page 268) In looking up include files, the C++ compiler has encountered a file whose path
name contains more characters than are allowed in the Windows maximum.
Rename the path to a shorter name.
E2495: Redefinition of uuid is not identical (C++) ( see page 268) GUID's attached to structs have to be the same across multiple declarations and
definitions of the same struct. So the following example would cause this error:
E2500: __declspec(selectany) is only for initialized and externally visible You cannot use __declspec(selectany) with static variables, unitialized variables,
variables (C++) ( see page 268) etc.
E2482: String constant expected (C++) ( see page 268) The compiler expected a string constant at this location but did not receive one.
This error is no longer generated by the compiler.
E2481: Unexpected string constant (C++) ( see page 268) There are times when the compiler does not expect a string constant to appear in
the source input. For example:
E2386: Cannot involve parameter 'parameter' in a complex partial specialization When declaring or defining a template class partial specialization, it is illegal to
expression (C++) ( see page 268) involve any of the non-type template parameters in complex expressions. They
may only be referenced by name. For example:
E2387: Partial specializations may not specialize dependent non-type A partial specialization may not use a template parameter in its specialization
parameters ('parameter') (C++) ( see page 269) argument list which is dependent on another type parameter. For example:
E2388: Argument list of specialization cannot be identical to the parameter list of When declaring a partial specialization, its specialization argument list must differ
primary template (C++) ( see page 269) in some way from its basic parameter list. For example:
template<class T>
E2389: Mismatch in kind of substitution argument and template parameter When referencing a template specialization, all type parameters must be satisfied
'parameter' (C++) ( see page 269) using type arguments, all non-type parameters require non-type arguments, and
all template template parameters require either a template name, or another
template template argument. Mismatching these requirements in any way will
trigger the above error. For example:
E2480: Cannot involve template parameters in complex partial specialization A partial specialization cannot reference other template parameters in a nonvalue
arguments (C++) ( see page 269) argument expression, unless it is simply a direct reference to the template
parameter. For example:
E2392: Template instance 'template' is already instantiated (C++) ( see page There are two ways to trigger this error. If –A is enabled (ANSI compliant mode),
270) then attempting to explicitly instantiate a template specialization which has
already been instantiated (either implicitly or explicitly) will cause this error.
Regardless of –A, attempting to explicitly specialize a template specialization
which has already been either implicit or explicitly instantiated will always trigger
this error. For example:
E2393: Cannot take the address of non-type, non-reference template parameter A template parameter has no address, and is not associated with any real
'parameter' (C++) ( see page 270) "object". Therefore, to take its address, or attempt to assign to it, has no
meaning. For example:
E2399: Cannot reference template argument 'arg' in template class 'class' this The compiler no longer generates this error.
way (C++) ( see page 270) 3
E2397: Template argument cannot have static or local linkage (C++) ( see Only integral constant expressions, and the address of global variables with
page 270) external linkage, may be used as template arguments. For example:
E2485: Cannot use address of array element as non-type template argument Non-type template arguments may only be of integral type, or the address of a
(C++) ( see page 271) global variable. They cannot be the address of an array element. For example:
E2402: Illegal base class type: formal type 'type' resolves to 'type' (C++) ( see When instantiating a template class definition, if it is found that a declared base
page 271) class does not resolve to an accessible class type, this error will result. For
example:
E2403: Dependent call specifier yields non-function 'name' (C++) ( see page The compiler no longer generates this error.
271)

219
C++ Compiler Errors And Warnings (C++) RAD Studio 3.1 C++ Reference

E2404: Dependent type qualifier 'qualifier' has no member type named 'name' If a template declaration references a member of a dependent type, it is only
(C++) ( see page 271) possible to alert the user to the non-existence of this member during type
instantiation for a given set of template arguments. For example:
E2405: Dependent template reference 'identifier' yields non-template symbol If a template specialization reference within a template declaration yields a
(C++) ( see page 271) reference to a non-template during type instantiation, the above error will result.
For example:
E2406: Dependent type qualifier 'qualifier' is not a class or struct type (C++) ( If a dependent name reference within a template declaration results in a
see page 272) non-struct member qualification at instantiation time, the above error will result.
For example:
E2407: Dependent type qualifier 'qualifier' has no member symbol named 'name' If a template declaration references a member of a dependent type, it is only
(C++) ( see page 272) possible to alert the user to the non-existence of this member during type
instantiation for a given set of template arguments. For example:
E2408: Default values may be specified only in primary class template Template functions, and class partial specializations, may not use default
declarations (C++) ( see page 272) expressions in their template parameter lists. Only primary template declarations
may do this. For example:
E2409: Cannot find a valid specialization for 'specifier' (C++) ( see page 272) This error is no longer generated by the compiler.
E2410: Missing template parameters for friend template 'template' (C++) ( see If a friend template is declared, but no template parameters are specified, this
page 273) error will result. For example:
E2486: Cannot use address of class member as non-type template argument Non-type template arguments may only be of integral type, or the address of a
(C++) ( see page 273) global variable. They cannot be the address of a class member. For example:
E2411: Declaration of member function default parameters after a specialization If a member function of a class template is declared, and then a specialization of
has already been expanded (C++) ( see page 273) that class implicitly instantiated, and later that member function defined with
default parameters specified, the above error will result. For example:
E2412: Attempting to bind a member reference to a dependent type (C++) ( The compiler no longer generates this error.
see page 273)
E2414: Destructors cannot be declared as template functions (C++) ( see page Destructors cannot be templates. For example:
273)
E2473: Invalid explicit specialization of 'specifier' (C++) ( see page 274) Attempting to explicitly specialize a static data member or any non-template will
cause this error.
E2490: Specialization within template classes not yet implemented (C++) ( see Explicit and partial specialization of member template classes and functions
page 274) within template classes and nested template classes, is not supported.
E2416: Invalid template function declaration (C++) ( see page 274) The compiler no longer generates this error.
E2417: Cannot specify template parameters in explicit specialization of 'specifier' The compiler no longer generates this error.
(C++) ( see page 274)
E2418: Maximum instantiation depth exceeded; check for recursion (C++) ( The compiler only supports 256 levels of instantiation before it will trigger this
see page 274) error. The main problem is in controlling stack depth, because the parser uses
recursive functions to manage type instantiation. Here is an example that would
produce such an error:
E2420: Explicit instantiation can only be used at global scope (C++) ( see page Explicit instantiation cannot be specified at any level other than namespace or
274) global scope. For example:
E2422: Argument kind mismatch in redeclaration of template parameter If a template is declared at one point in the translation unit, and then redeclared
'parameter' (C++) ( see page 275) with template parameters of a different kind at another location, this error will
result. For example:
E2423: Explicit specialization or instantiation of non-existing template 'template' Attempting to explicit specialize or instantiate a template which does not exist is
(C++) ( see page 275) clearly illegal. For example:
E2479: Cannot have both a template class and function named 'name' (C++) ( No other function or type may have the same name as a template class. For
see page 275) example:
E2484: The name of template class 'class' cannot be overloaded (C++) ( see Attempting to declare a function that overrides the name of a template class will
page 275) cause this error. For example:
E2426: Explicit specialization of 'specifier' requires 'template<>' declaration (C++) According to the standard, explicit specialization of any template now always
( see page 275) require the "template<>" declarator syntax. For example:
E2487: Cannot specify default function arguments for explicit specializations An explicit specialization of a function may not declare default function
(C++) ( see page 276) arguments. For example:
E2427: 'main' cannot be a template function (C++) ( see page 276) 'main' cannot be declared as a template function. 'main' is the entry point of a
console application, and it should be declared as a regular __cdecl function.
3 This error message should not occur because it has been replaced with another
one (E2475).
E2429: Not a valid partial specialization of 'specifier' (C++) ( see page 276) Internal compiler error.
E2430: Number of template parameters does not match in redeclaration of If a template is redeclared with a different number of template parameters, this
'specifier' (C++) ( see page 276) error will result. For example:
E2477: Too few template parameters were declared for template 'template' (C++) If a member declaration or definition occurs outside of a template class, and that
( see page 276) outer declaration uses a different number of template parameters than the parent
class, this error will result. For example:
E2478: Too many template parameters were declared for template 'template' If a member declaration or definition occurs outside of a template class, and that
(C++) ( see page 277) outer declaration uses a different number of template parameters than the parent
class, this error will result. For example:

220
3.1 C++ Reference RAD Studio C++ Compiler Errors And Warnings (C++)

E2431: Non-type template parameters cannot be of floating point, class, or void Non-type template parameters are restricted as to what type they may be.
type (C++) ( see page 277) Floating point, class and void types are illegal. For example:
E2434: Template declaration missing template parameters ('template<...>') (C++) In a context where at least one template parameter is clearly required, if none are
( see page 277) found this error will result. For example:
E2435: Too many template parameter sets were specified (C++) ( see page If a member template is being defined outside of its parent class, and too many
277) template parameter sets are declared, this error will result. For example:
E2436: Default type for template template argument 'arg' does not name a If a template template parameter is to have a default type, that type must either
primary template class (C++) ( see page 277) be a generic template class name, or another template template parameter.
E2437: 'typename' should be followed by a qualified, dependent type name (C++) Whenever the "typename" keyword is used in a template declaration or definition,
( see page 278) it should always name a dependent type. For example:
E2438: Template template arguments must name a class (C++) ( see page A template template parameter must always declare a new class name. For
278) example:
E2439: 'typename' is only allowed in template declarations (C++) ( see page The "typename" keyword must only be used within template declarations and
278) definitions.
E2440: Cannot generate specialization from 'specifier' because that type is not The compiler no longer generates this error.
yet defined (C++) ( see page 278)
E2441: Instantiating 'specifier' (C++) ( see page 278) Whenever a compiler error occurs while instantiating a template type, the context
of what was being instantiated at that point in time will be reported to the user, in
order to aid in detection of the problem.
E2503: Missing or incorrect version of TypeLibImport.dll (C++) ( see page 279) This error occurs when the compiler is trying to access TypeLibImport.dll but it
either can't find it, it was corrupted, or you have the wrong version of it installed
on your computer. You can reinstall it from the product CD.
E2470: Need to include header <typeinfo> to use typeid (C++) ( see page 279) When you use the 'typeid' function, you have to include the <typeinfo> header,
otherwise you will get syntax errors.
For example, consider a test case with the following code:
E2514: Cannot (yet) use member overload resolution during template You are trying to overload a member during template instantiation. You cannot
instantiation (C++) ( see page 279) have calls to overloaded constant functions within array bounds initializers, for
example.
E2508: 'using' cannot refer to a template specialization (C++) ( see page 279) The using keyword cannot refer to a template specialization.
E2462: 'virtual' can only be used with non-template member functions (C++) ( The 'virtual' keyword can only be applied to regular member functions, not to
see page 279) member template functions.
Consider a test case with the following code:
W8086: Incorrect use of #pragma alias "aliasName"="substituteName" (C++) ( The directive #pragma alias is used to tell the linker that two identifier names are
see page 280) equivalent. You must put the two names in quotes.
You will receive this warning if you don't use pragma alias correctly. For example,
the following two lines both generate this warning:
W8099: Static main is not treated as an entry point (C++) ( see page 280) The main function has been created as static, and as such cannot be used as a
valid entry point.
Consider:
W8093: Incorrect use of #pragma codeseg [seg_name] ["seg_class"] [group] The #pragma codeseg directive can be used to set or reset the name, class, and
(C++) ( see page 280) group of a segment. You have to follow the exact syntax mentioned in the
warning message, and all names are optional.
So these are all legal:
W8094: Incorrect use of #pragma comment( <type> [,"string"] ) (C++) ( see The directive #pragma comment can be used to emit linker comment records.
page 280) In this message, <type> can be any of the following:

• user
• lib
• exestr
• linker
The type should be there but the string is optional.
W8085: Function 'function' redefined as non-inline (C++) ( see page 281) This warning is used to indicate when a certain function, which has been
declared inline in one location, is redefined in another location to be non-inline. 3
W8105: %s member '%s' in class without constructors (C++) ( see page 281) A class that contains constant or reference members (or both) must have at least
one user-defined constructor.
Otherwise, there would be no way to ever initialize such members.
W8095: Incorrect use of #pragma message( "string" ) (C++) ( see page 281) You can use pragma message to emit a message to the command line or to the
message window. You would get this warning if you use the incorrect syntax, so
W8098: Multi-character character constant (C++) ( see page 281) This warning is issued when the compiler detects a multi-character integer
constant, such as:

221
C++ Compiler Errors And Warnings (C++) RAD Studio 3.1 C++ Reference

W8096: Incorrect use of #pragma code_seg(["seg_name"[,"seg_class"]]) (C++) Pragma code_seg is similar to pragma codeseg, but with this one you can only
( see page 281) modify the name and the class of a code segment. If you use the wrong syntax,
you get this warning.
The following examples show the correct usage:
W8083: Pragma pack pop with no matching pack push (C++) ( see page 282) Each #pragma pack(pop) should have a matching preceding #pragma
pack(push) in the same translation unit. Pairs of 'push' and 'pop' can be nested.
For example:
W8097: Not all options can be restored at this time (C++) ( see page 282) Your program has a #pragma pop at a place where it can't restore options.
For example:
W8084: Suggest parentheses to clarify precedence (C++) ( see page 282) This warning indicates that several operators used in one expression might
cause confusion about the applicable operator precedence rules. The warning
helps create code that is more easy to understand and potentially less
ambiguous.
For example, compile the following code using the –w command line option:
W8092: 'type' argument 'specifier' passed to 'function' is not an iterator: 'type' An argument that is not an iterator is being used with an STL algorithm that
iterator required (C++) ( see page 282) requires an iterator.
W8087: 'operator::operator==' must be publicly visible to be contained by a 'type' A type that is being used with an STL container has a private 'operator=='.
(C++) ( see page 283)
W8090: 'type::operator<' must be publicly visible to be used with 'type' (C++) ( A type that is being used with an STL container has a private 'operator<'. The
see page 283) type you're trying to use must be made public.
W8089: 'type::operator<' must be publicly visible to be contained by a 'type' The type that is being used for an STL container has a private 'operator<'. The
(C++) ( see page 283) type that is being contained (type::operator) must be a public type.
For example, if you were trying to instantiate a class type "vector<blah>", the
error would be:
W8091: 'type' argument 'specifier' passed to 'function' is a 'iterator category' An incorrect iterator category is being used with an STL algorithm.
iterator: 'iterator category' iterator required (C++) ( see page 283)
W8076: Template instance 'specifier' is already instantiated (C++) ( see page You are trying to explicitly instantiate a template that was already implicitly
283) instantiated.
If –A is not enabled and an attempt is made to explicitly instantiate a
specialization which has already been either implicitly or explicitly instantiated,
this error will result.
W8077: Explicitly specializing an explicitly specialized class member makes no Internal error. This warning is no longer generated by the compiler.
sense (C++) ( see page 283) The following code is illegal:
Informational messages (C++) ( see page 284) The compiler displays status information while compiling if you have checked
"Show general messages" on the Compiler page of the Project Options dialog
box. Most of the messages are self-explanatory and state information about
compiling and linking; for example:
E2196: Cannot take address of member function 'function' (C++) ( see page An expression takes the address of a class member function, but this member
284) function was not found in the program being debugged. The evaluator issues this
message.
F1002: Unable to create output file 'filename' (C++) ( see page 284) This error occurs if the work disk is full or write protected.
This error also occurs if the output directory does not exist.
Solutions
If the disk is full, try deleting unneeded files and restarting the compilation.
If the disk is write-protected, move the source files to a writeable disk and restart
the compilation.
F1003: Error directive: 'message' (C++) ( see page 284) This message is issued when an #error directive is processed in the source
file.
'message' is the text of the #error directive.
F1004: Internal compiler error (C++) ( see page 284) An error occurred in the internal logic of the compiler. This error shouldn't occur
in practice, but is generated in the event that a more specific error message is
not available.
F1006: Bad call of intrinsic function (C++) ( see page 284) You have used an intrinsic function without supplying a prototype. You may have
supplied a prototype for an intrinsic function that was not what the compiler
expected.
3 F1007: Irreducible expression tree (C++) ( see page 285) An expression on the indicated line of the source file caused the code generator
to be unable to generate code. Avoid using the expression. Notify CodeGear if an
expression consistently reproduces this error.
F1009: Unable to open input file 'filename' (C++) ( see page 285) This error occurs if the source file can't be found.
Check the spelling of the name. Make sure the file is on the specified disk or
directory.
Verify that the proper directory paths are listed. If multiple paths are required, use
a semicolon to separate them.

222
3.1 C++ Reference RAD Studio C++ Compiler Errors And Warnings (C++)

F1011: Register allocation failure (C++) ( see page 285) Possible Causes
An expression on the indicated line of the source file was so complicated that the
code generator could not generate code for it.
Solutions
Simplify the expression. If this does not solve the problem, avoid the expression.
Notify CodeGear if an expression can consistently reproduce this error.
F1012: Compiler stack overflow (C++) ( see page 285) The compiler's stack has overflowed. This can be caused by a number of things,
among them deeply nested statements in a function body (for example, if/else) or
expressions with a large number of operands. You must simplify your code if this
message occurs. Adding more memory to your system will not help.
F1013: Error writing output file (C++) ( see page 285) A DOS error that prevents the C++ IDE from writing an .OBJ, .EXE, or temporary
file.
Solutions
Make sure that the Output directory in the Directories dialog box is a valid
directory.
Check that there is enough free disk space.
F1000: Compiler table limit exceeded (C++) ( see page 285) One of the compiler's internal tables overflowed.
This usually means that the module being compiled contains too many function
bodies.
This limitation will not be solved by making more memory available to the
compiler. You need to simplify the file being compiled.
F1005: Include files nested too deep (C++) ( see page 286) This message flags (directly or indirectly) recursive #include directives.
F1008: Out of memory (C++) ( see page 286) The total working storage is exhausted.
This error can occur in the following circumstances:

• Not enough virtual memory is available for compiling a


particular file. In this case, shut down any other concurrent
applications. You may also try to reconfigure your
machine for more available virtual memory, or break up
the source file being compiled into smaller separate
components. You can also compile the file on a system
with more available RAM.
• The compiler has encountered an exceedingly complex or
long expression at the line indicated and has insufficient
reserves to parse it. Break the expression down into
separate statements.... more ( see page 286)
F1010: Unable to open 'filename' (C++) ( see page 286) This error occurs if the specified file can't be opened.
Make sure the file is on the specified disk or directory. Verify the proper paths are
listed. If multiple paths are required, use a semicolon to separate them.
E2000: 286/287 instructions not enabled (C++) ( see page 286) Use the -2 command-line compiler option to enable 286/287 opcodes. Be aware
that the resulting code cannot be run on 8086- and 8088-based machines.
Abnormal program termination (C++) ( see page 286) The program called abort because there wasn't enough memory to execute.
This message can be caused by memory overwrites.
E2009: Attempt to grant or reduce access to 'identifier' (C++) ( see page 286) A C++ derived class can modify the access rights of a base class member, but
only by restoring it to the rights in the base class.
It can't add or reduce access rights.
E2011: Illegal to take address of bit field (C++) ( see page 286) It is not legal to take the address of a bit field, although you can take the address
of other kinds of fields.
E2010: Cannot add or subtract relocatable symbols (C++) ( see page 287) The only arithmetic operation that can be performed on a relocatable symbol in
an assembler operand is addition or subtraction of a constant.
Variables, procedures, functions, and labels are relocatable symbols.
E2013: 'function1' cannot be distinguished from 'function2' (C++) ( see page The parameter type lists in the declarations of these two functions do not differ
287) enough to tell them apart.
Try changing the order of parameters or the type of a parameter in one 3
declaration.

223
C++ Compiler Errors And Warnings (C++) RAD Studio 3.1 C++ Reference

E2014: Member is ambiguous: 'member1' and 'member2' (C++) ( see page You must qualify the member reference with the appropriate base class name.
287) In C++ class 'class', member 'member' can be found in more than one base
class, and it was not qualified to indicate which one you meant.
This applies only in multiple inheritance, where the member name in each base
class is not hidden by the same member name in a derived class on the same
path.
The C++ language rules require that this test for ambiguity be made before
checking for access rights (private, protected, public).
It is possible to get this message even though only one (or... more ( see page
287)
E2015: Ambiguity between 'function1' and 'function2' (C++) ( see page 287) Both of the named overloaded functions could be used with the supplied
parameters.
This ambiguity is not allowed.
E2017: Ambiguous member name 'name' (C++) ( see page 287) Whenever a structure member name is used in inline assembly, such a name
must be unique. (If it is defined in more than one structure, all of the definitions
must agree as to its type and offset within the structures). In this case, an
ambiguous member name has been used.
For example:
E2019: 'identifier' cannot be declared in an anonymous union (C++) ( see page The compiler found a declaration for a member function or static member in an
288) anonymous union.
Such unions can only contain data members.
E2020: Global anonymous union not static (C++) ( see page 288) In C++, a global anonymous union at the file level must be static.
E2022: Array size too large (C++) ( see page 288) The declared array is larger than 64K and the 'huge' keyword was not used.
If you need an array of this size, either use the 'huge' modifier, like this:
E2024: Cannot modify a const object (C++) ( see page 288) This indicates an illegal operation on an object declared to be const, such as an
assignment to the object.
E2025: Assignment to 'this' not allowed, use X::operator new instead (C++) ( In early versions of C++, the only way to control allocation of class of objects was
see page 288) by assigning to the 'this' parameter inside a constructor.
This practice is no longer allowed, because a better, safer, and more general
technique is to define a member function operator new instead.
For example:
E2026: Assembler statement too long (C++) ( see page 288) Inline assembly statements can't be longer than 480 bytes.
E2001: Constructors and destructors not allowed in __automated section (C++) Only member function declarations are allowed in __automated sections.
( see page 289)
E2002: Only __fastcall functions allowed in __automated section (C++) ( see The calling convention for functions declared in an __automated section must be
page 289) __fastcall.
E2003: Data member definition not allowed in __automated section (C++) ( see Only member function declarations are allowed in __automated sections.
page 289)
E2004: Only read or write clause allowed in property declaration in __automated Storage specifiers stored, default, and nodefault are not allowed in property
section (C++) ( see page 289) declarations in __automated sections.
E2005: Redeclaration of property not allowed in __automated section (C++) ( If you declare a property in an __automated section it has be a new declaration.
see page 290) Property hoisting is not allowed.
E2027: Must take address of a memory location (C++) ( see page 290) Your source file used the address-of operator (&) with an expression that can't be
used that way; for example, a register variable.
E2028: operator -> must return a pointer or a class (C++) ( see page 290) The C++ operator -> function must be declared to either return a class or a
pointer to a class (or struct or union).
In either case, it must be something to which the -> operator can be applied.
E2029: 'identifier' must be a previously defined class or struct (C++) ( see page You are attempting to declare 'identifier' to be a base class, but either it is not a
290) class or it has not yet been fully defined.
Correct the name or rearrange the declarations.
E2030: Misplaced break (C++) ( see page 290) The compiler encountered a break statement outside a switch or looping
construct.
You can only use break statements inside of switch statements or loops.
E2031: Cannot cast from 'type1' to 'type2' (C++) ( see page 290) A cast from type 'ident1' to type 'ident2' is not allowed.
3 In C++, you cannot cast a member function pointer to a normal function pointer.
For example:
E2033: Misplaced continue (C++) ( see page 291) The compiler encountered a continue statement outside a looping construct.
E2034: Cannot convert 'type1' to 'type2' (C++) ( see page 291) An assignment, initialization, or expression requires the specified type conversion
to be performed, but the conversion is not legal.
In C++, the compiler will convert one function pointer to another only if the
signature for the functions are the same. Signature refers to the arguments and
return type of the function. For example:
E2036: Conversion operator cannot have a return type specification (C++) ( This C++ type conversion member function specifies a return type different from
see page 292) the type itself.
A declaration for conversion function operator can't specify any return type.

224
3.1 C++ Reference RAD Studio C++ Compiler Errors And Warnings (C++)

E2037: The constructor 'constructor' is not allowed (C++) ( see page 292) Constructors of the form
E2039: Misplaced decimal point (C++) ( see page 292) The compiler encountered a decimal point in a floating-point constant as part of
the exponent.
E2041: Incorrect use of default (C++) ( see page 292) The compiler found no colon after the default keyword.
E2042: Declare operator delete (void*) or (void*, size_t) (C++) ( see page 293) E2043 Declare operator delete[] (void*) or (void*, size_t)Compiler error
Declare the operator delete with one of the following:
1.A single void* parameter, or
2.A second parameter of type size_t
If you use the second version, it will be used in preference to the first version.
The global operator delete can only be declared using the single-parameter form.
E2044: operator delete must return void (C++) ( see page 293) E2044 operator delete[] must return voidCompiler error
This C++ overloaded operator delete was declared in some other way.
Declare the operator delete with one of the following:
1.A single void* parameter, or
2.A second parameter of type size_t
If you use the second version, it will be used in preference to the first version.
The global operator delete can only be declared using the single-parameter form.
E2045: Destructor name must match the class name (C++) ( see page 293) In a C++ class, the tilde (~) introduces a declaration for the class destructor.
The name of the destructor must be same as the class name.
In your source file, the ~ preceded some other name.
E2048: Unknown preprocessor directive: 'identifier' (C++) ( see page 293) The compiler encountered a # character at the beginning of a line. The directive
name that followed the # was not one of the following:

• define ( see page 690)


• else ( see page 688)
• endif
• if
• ifdef ( see page 688)
• ifndef ( see page 688)
• include ( see page 692)
• line ( see page 693)
• pragma
• undef ( see page 692)
E2046: Bad file name format in include directive OR Bad file name format in line Include and line directive file names must be surrounded by quotes ("filename.h")
directive (C++) ( see page 294) or angle brackets (<filename.h>).
The file name was missing the opening quote or angle bracket.
If a macro was used, the resulting expansion text is not surrounded by quote
marks.
E2051: Invalid use of dot (C++) ( see page 294) An identifier must immediately follow a period operator (.). This is a rare message
that can only occur in some specialized inline assembly statements.
Example
E2053: Misplaced elif directive (C++) ( see page 294) The compiler encountered an #elif directive without any matching #if,
#ifdef, or #ifndef directive.
E2054: Misplaced else (C++) ( see page 294) The compiler encountered an else statement without a matching if statement.
Possible Causes

• An extra "else" statement


• An extra semicolon 3
• Missing braces
• Some syntax error in a previous "if" statement
E2055: Misplaced else directive (C++) ( see page 294) The compiler encountered an #else directive without any matching #if,
#ifdef, or #ifndef directive.
E2056: Misplaced endif directive (C++) ( see page 295) The compiler encountered an #endif directive without any matching #if,
#ifdef, or #ifndef directive.
E2059: Unknown language, must be C or C++ (C++) ( see page 295) In the C++ construction

225
C++ Compiler Errors And Warnings (C++) RAD Studio 3.1 C++ Reference

E2060: Illegal use of floating point (C++) ( see page 295) Floating-point operands are not allowed in these operators

• shift (SHL, SHR)


• bitwise Boolean (AND, OR, XOR, NOT)
• conditional (? :)
• indirection (*)
• certain others
The compiler found a floating-point operand with one of
these prohibited operators.
E2061: Friends must be functions or classes (C++) ( see page 295) A friend of a C++ class must be a function or another class.
E2062: Invalid indirection (C++) ( see page 295) The indirection operator (*) requires a pointer as the operand.
Example
E2063: Illegal initialization (C++) ( see page 296) Initializations must be one of the following:

• constant expressions
• the address of a global extern or static variable plus or
minus a constant
E2064: Cannot initialize 'type1' with 'type2' (C++) ( see page 296) You are attempting to initialize an object of type 'type1' with a value of type
'type2' which is not allowed.
The rules for initialization are essentially the same as for assignment.
E2068: 'identifier' is not a non-static data member and can't be initialized here Only data members can be initialized in the initializers of a constructor.
(C++) ( see page 296) This message means that the list includes a static member or function member.
Static members must be initialized outside of the class, for example:
E2069: Illegal use of member pointer (C++) ( see page 296) Pointers to class members can only be passed as arguments to functions, or
used with the following operators:

• assignment operators
• comparison operators
• .*
• —>*
• ?: conditional (ternary) operator
• && logical AND ( see page 531) operator
• || logical OR ( see page 559) operator
The compiler has encountered a member pointer being used
with a different operator.
In order to call a member function pointer, one must supply
an instance of the class for it to call upon.
For example:
E2071: operator new must have an initial parameter of type size_t (C++) ( see E2071 Operator new[] must have an initial parameter of type size_tCompiler error
page 297) Operator new can be declared with an arbitrary number of parameters.
It must always have at least one, the amount of space to allocate.
E2072: Operator new[] must return an object of type void (C++) ( see page 297) This C++ overloaded operator new was declared in some other way.

3 E2075: Incorrect 'type' option: option (C++) ( see page 297) An error has occurred in either the configuration file or a command-line option.
The compiler may not have recognized the configuration file parameter as legal;
check for a preceding hyphen (-), or the compiler may not have recognized the
command-line parameter as legal.
This error can also occur if you use a #pragma option in your code with an
invalid option.

226
3.1 C++ Reference RAD Studio C++ Compiler Errors And Warnings (C++)

E2076: Overloadable operator expected (C++) ( see page 297) Almost all C++ operators can be overloaded.
These are the only ones that can't be overloaded:

• the field-selection dot (.)


• dot-star (.*)
• double colon (::)
• conditional expression (?:)
The preprocessor operators (# and ##) are not C or C++
language operators and thus can't be overloaded.
Other non-operator punctuation, such as semicolon (;), can't
be overloaded.
E2080: 'function' must be declared with one parameter (C++) ( see page 298) This C++ operator function was incorrectly declared with more than one
parameter.
E2077: 'operator' must be declared with one or no parameters (C++) ( see When operator ++ or operator -- is declared as a member function, it must be
page 298) declared to take either:

• No parameters (for the prefix version of the operator), or


• One parameter of type int (for the postfix version)
E2079: 'function' must be declared with no parameters (C++) ( see page 298) This C++ operator function was incorrectly declared with parameters.
E2078: 'operator' must be declared with one or two parameters (C++) ( see When operator ++ or operator -- is declared as a non-member function, it must
page 298) be declared to take either:

• one parameter (for the prefix version of the operator), or


• two parameters (for the postfix version)
E2081: 'function' must be declared with two parameters (C++) ( see page 298) This C++ operator function was incorrectly declared with other than two
parameters.
E2082: 'identifier' must be a member function or have a parameter of class type Most C++ operator functions must have an implicit or explicit parameter of class
(C++) ( see page 298) type.
This operator function was declared outside a class and does not have an explicit
parameter of class type.
E2083: Last parameter of 'operator' must have type 'int' (C++) ( see page 299) When a postfix operator ++ or operator -- is overloaded, the last parameter must
be declared with the type int.
E2084: Parameter names are used only with a function body (C++) ( see page When declaring a function (not defining it with a function body), you must use
299) either empty parentheses or a function prototype.
A list of parameter names only is not allowed.
Example declarations
E2085: Invalid pointer addition (C++) ( see page 299) Your source file attempted to add two pointers together.
E2086: Illegal pointer subtraction (C++) ( see page 299) This is caused by attempting to subtract a pointer from a non-pointer.
E2087: Illegal use of pointer (C++) ( see page 299) Pointers can only be used with these operators:

• addition(+)
• subtraction(-)
• assignment(=)
• comparison(==)
• indirection(*)
• arrow(->)
3
Your source file used a pointer with some other operator.
Example
E2088: Bad syntax for pure function definition (C++) ( see page 300) Pure virtual functions are specified by appending "= 0" to the declaration, like
this:

227
C++ Compiler Errors And Warnings (C++) RAD Studio 3.1 C++ Reference

E2089: Identifier 'identifier' cannot have a type qualifier (C++) ( see page 300) A C++ qualifier class::identifier can't be applied here.
A qualifier is not allowed on the following:

• typedef names
• function declarations (except definitions at the file level)
• on local variables or parameters of functions
• on a class member--except to use its own class as a
qualifier (redundant but legal).
E2090: Qualifier 'identifier' is not a class or namespace name (C++) ( see page The C++ qualifier in the construction qual::identifier is not the name of a struct or
300) class.
E2092: Storage class 'storage class' is not allowed here (C++) ( see page 300) The given storage class is not allowed here.
Probably two storage classes were specified, and only one can be given.
E2096: Illegal structure operation (C++) ( see page 300) Structures can only be used with dot (.), address-of (&) or assignment (=)
operators, or be passed to or from a function as parameters.
The compiler encountered a structure being used with some other operator.
E2104: Invalid use of template keyword (C++) ( see page 300) You can only use a template class name without specifying its actual arguments
inside a template definition.
Using a template class name without specifying its actual arguments outside a
template definition is illegal.
E2108: Improper use of typedef 'identifier' (C++) ( see page 301) Your source file used a typedef symbol where a variable should appear in an
expression.
Check for the declaration of the symbol and possible misspellings.
E2109: Not an allowed type (C++) ( see page 301) Your source file declared some sort of forbidden type; for example, a function
returning a function or array.
E2110: Incompatible type conversion (C++) ( see page 301) The cast requested can't be done.
E2113: Virtual function 'function1' conflicts with base class 'base' (C++) ( see A virtual function has the same argument types as one in a base class, but differs
page 301) in one or more of the following:

• Return type
• Calling convention
• Exception specification (throw list)
E2114: Multiple base classes require explicit class names (C++) ( see page In a C++ class constructor, if there is more than one immediate base class, each
301) base class constructor call in the constructor header must include the base class
name.
E2115: Bit field too large (C++) ( see page 301) This error occurs when you supply a bit field with more than 16 bits.
E2116: Bit fields must contain at least one bit (C++) ( see page 301) You can't declare a named bit field to have 0 (or less than 0) bits.
You can declare an unnamed bit field to have 0 bits.
This is a convention used to force alignment of the following bit field to a byte
boundary (or to a word boundary.
W8005: Bit fields must be signed or unsigned int (C++) ( see page 302) In ANSI C, bit fields may only be signed or unsigned int (not char or long, for
example).
E2119: User break (C++) ( see page 302) You typed a Ctrl+Break while compiling in the IDE.
(This is not an error, just a confirmation.)
E2111: Type 'typename' may not be defined here (C++) ( see page 302) Class and enumeration types may not be defined in a function return type, a
function argument type, a conversion operator type, or the type specified in a
cast.
You must define the given type before using it in one of these contexts.
Note:This error message is often the result of a missing semicolon (;) for a
class declaration. You might want to verify that all the class declarations
preceding the line on which the error occurred end with a semicolon.
3 E2121: Function call missing ) (C++) ( see page 302) The function call argument list had some sort of syntax error, such as a missing
or mismatched right parenthesis.
E2123: Class 'class' may not contain pure functions (C++) ( see page 302) The class being declared cannot be abstract, and therefore it cannot contain any
pure functions.
E2126: Case bypasses initialization of a local variable (C++) ( see page 302) In C++ it is illegal to bypass the initialization of a local variable.
This error indicates a case label that can transfer control past this local variable.
E2127: Case statement missing : (C++) ( see page 302) A case statement must have a constant expression followed by a colon.
The expression in the case statement either was missing a colon or had an extra
symbol before the colon.

228
3.1 C++ Reference RAD Studio C++ Compiler Errors And Warnings (C++)

E2128: Case outside of switch (C++) ( see page 302) The compiler encountered a case statement outside a switch statement.
This is often caused by mismatched braces.
E2129: Character constant too long (or empty) (C++) ( see page 303) Character constants can only be one or two characters long.
E2133: Unable to execute command 'command' (C++) ( see page 303) The linker or assembler cannot be found, or possibly the disk is bad.
E2134: Compound statement missing closing brace (C++) ( see page 303) The compiler reached the end of the source file and found no closing brace.
This is most commonly caused by mismatched braces.
E2137: Destructor for 'class' required in conditional expression (C++) ( see If the compiler must create a temporary local variable in a conditional expression,
page 303) it has no good place to call the destructor because the variable might or might
not have been initialized.
The temporary can be explicitly created, as with classname(val, val), or implicitly
created by some other code.
You should recast your code to eliminate this temporary value.
E2135: Constructor/Destructor cannot be declared 'const' or 'volatile' (C++) ( A constructor or destructor has been declared as const or volatile.
see page 303) This is not allowed.
E2138: Conflicting type modifiers (C++) ( see page 303) This occurs when a declaration is given that includes more than one addressing
modifier on a pointer or more than one language modifier for a function.
Only one language modifier (for example, __cdecl, __pascal, or
__fastcall) can be given for a function.
E2136: Constructor cannot have a return type specification (C++) ( see page C++ constructors have an implicit return type used by the compiler, but you can't
303) declare a return type or return a value.
E2038: Cannot declare or define 'identifier' here: wrong namespace (C++) ( You tried to declare a template in an illegal place or a namespace member
see page 304) outside of its namespace.
E2154: Cannot define 'identifier' using a namespace alias (C++) ( see page You cannot use a namespace alias to define a namespace member outside of its
304) namespace.
E2421: Cannot use local type 'identifier' as template argument (C++) ( see A local type was used in an actual template type argument, which is illegal.
page 304)
E2035: Conversions of class to itself or base class not allowed (C++) ( see You tried to define a conversion operator to the same class or a base class.
page 304)
E2139: Declaration missing ; (C++) ( see page 304) Your source file contained a struct or union field declaration that was not followed
by a semicolon.
Check previous lines for a missing semicolon.
E2140: Declaration is not allowed here (C++) ( see page 304) Declarations can't be used as the control statement for while, for, do, if, or switch
statements.
E2141: Declaration syntax error (C++) ( see page 304) Your source file contained a declaration that was missing a symbol or had an
extra symbol added to it.
Check for a missing semicolon or parenthesis on that line or on previous lines.
E2142: Base class 'class' contains dynamically dispatchable functions (C++) ( This error occurs when a class containing a DDVT function attempts to inherit
see page 304) DDVT functions from multiple parent classes.
Currently, dynamically dispatched virtual tables do not support the use of multiple
inheritance.
E2143: Matching base class function 'function' has different dispatch number If a DDVT function is declared in a derived class, the matching base class
(C++) ( see page 305) function must have the same dispatch number as the derived function.
E2144: Matching base class function 'function' is not dynamic (C++) ( see page If a DDVT function is declared in a derived class, the matching base class
305) function must also be dynamic.
E2145: Functions 'function1' and 'function2' both use the same dispatch number This error indicates a dynamically dispatched virtual table (DDVT) problem.
(C++) ( see page 305)
E2146: Need an identifier to declare (C++) ( see page 305) In this context, an identifier was expected to complete the declaration.
This might be a typedef with no name, or an extra semicolon at file level.
In C++, it might be a class name improperly used as another kind of identifier.
E2147: 'identifier' cannot start a parameter declaration (C++) ( see page 305) An undefined 'identifier' was found at the start of an argument in a function
declarator.
Often the type name is misspelled or the type declaration is missing. This is
usually caused by not including the appropriate header file.
E2150: Type mismatch in default argument value (C++) ( see page 305) The default parameter value given could not be converted to the type of the
parameter.
3
The message "Type mismatch in default argument value" is used when the
parameter was not given a name.
When compiling C++ programs, this message is always preceded by another
message that explains the exact reason for the type mismatch.
That other message is most often "Cannot convert 'type1' to 'type2'" but the
mismatch could be due to another reason.
E2152: Default expression may not use local variables (C++) ( see page 306) A default argument expression is not allowed to use any local variables or other
parameters.

229
C++ Compiler Errors And Warnings (C++) RAD Studio 3.1 C++ Reference

E2153: Define directive needs an identifier (C++) ( see page 306) The first non-whitespace character after a #define must be an identifier.
The compiler found some other character.
E2155: Too many default cases (C++) ( see page 306) The compiler encountered more than one default statement in a single switch.
E2156: Default outside of switch (C++) ( see page 306) The compiler encountered a default statement outside a switch statement.
This is most commonly caused by mismatched braces.
E2158: Operand of 'delete' must be non-const pointer (C++) ( see page 306) It is illegal to delete a variable that is not a pointer. It is also illegal to delete a
pointer to a constant.
For example:
E2159: Trying to derive a far class from the huge base 'base' (C++) ( see page This error is no longer generated by the compiler.
306)
E2160: Trying to derive a far class from the near base 'base' (C++) ( see page If a class is declared (or defaults to) near, all derived classes must also be near.
306)
E2161: Trying to derive a huge class from the far base 'base' (C++) ( see page This error is no longer generated by the compiler.
307)
E2162: Trying to derive a huge class from the near base 'base' (C++) ( see This error is no longer generated by the compiler.
page 307)
E2163: Trying to derive a near class from the far base 'base' (C++) ( see page If a class is declared (or defaults to) far, all derived classes must also be far.
307)
E2164: Trying to derive a near class from the huge base 'base' (C++) ( see This error is no longer generated by the compiler.
page 307)
E2165: Destructor cannot have a return type specification (C++) ( see page C++ destructors never return a value, and you can't declare a return type or
307) return a value.
E2166: Destructor for 'class' is not accessible (C++) ( see page 307) The destructor for this C++ class is protected or private, and can't be accessed
here to destroy the class.
If a class destructor is private, the class can't be destroyed, and thus can never
be used. This is probably an error.
A protected destructor can be accessed only from derived classes.
This is a useful way to ensure that no instance of a base class is ever created,
but only classes derived from it.
E2167: 'function' was previously declared with the language 'language' (C++) ( Only one language modifier (cdecl pascal) can be given for a function.
see page 307) This function has been declared with different language modifiers in two locations.
E2168: Division by zero (C++) ( see page 308) Your source file contains a divide or remainder in a constant expression with a
zero divisor.
E2169: 'identifier' specifies multiple or duplicate access (C++) ( see page 308) A base class can be declared public or private, but not both.
This access specifier can appear no more than once for a base class.
E2170: Base class 'class' is included more than once (C++) ( see page 308) A C++ class can be derived from any number of base classes, but can be directly
derived from a given class only once.
E2171: Body has already been defined for function 'function' (C++) ( see page A function with this name and type was previously supplied a function body.
308) A function body can only be supplied once.
One cause of this error is not declaring a default constructor which you
implement. For example:
E2172: Duplicate case (C++) ( see page 308) Each case of a switch statement must have a unique constant expression value.
E2175: Too many storage classes in declaration (C++) ( see page 308) A declaration can never have more than one storage class, either Auto, Register,
Static, or Extern.
E2176: Too many types in declaration (C++) ( see page 309) A declaration can never have more than one basic type. Examples of basic types
are:

• char
• class
• int
• float
3 • double
• struct
• union
• enum
• typedef name
E2179: virtual specified more than once (C++) ( see page 309) The C++ reserved word "virtual" can appear only once in one member function
declaration.

230
3.1 C++ Reference RAD Studio C++ Compiler Errors And Warnings (C++)

E2007: Dispid only allowed in __automated sections (C++) ( see page 309) The definition of dispids is only permitted in __automated sections.
Divide error (C++) ( see page 309) You tried to divide an integer by zero, which is illegal.
E2182: Illegal parameter to __emit__ (C++) ( see page 309) There are some restrictions on inserting literal values directly into your code with
the __emit__ function.
For example, you cannot give a local variable as a parameter to __emit__.
E2183: File must contain at least one external declaration (C++) ( see page This compilation unit was logically empty, containing no external declarations.
309) ANSI C and C++ require that something be declared in the compilation unit.
E2184: Enum syntax error (C++) ( see page 310) An enum declaration did not contain a properly formed list of identifiers.
E2185: The value for 'identifier' is not within the range of 'type-name' (C++) ( You have attempted to assign a value that is out of the range of the specified
see page 310) type.
E2186: Unexpected end of file in comment started on line 'number' (C++) ( see The source file ended in the middle of a comment.
page 310) This is normally caused by a missing close of comment (*/).
E2187: Unexpected end of file in conditional started on line 'number' (C++) ( The source file ended before the compiler (or MAKE) encountered #endif.
see page 310) The #endif either was missing or misspelled.
Every #if statement needs a matching #endif statement.
E2188: Expression syntax (C++) ( see page 310) This is a catch-all error message when the compiler parses an expression and
encounters a serious error.
Possible Causes
This is most commonly caused by one of the following:

• two consecutive operators


• mismatched or missing parentheses
• a missing semicolon on the previous statement.
Solutions
If the line where the error occurred looks syntactically
correct, look at the line directly above for errors.
Try moving the line with the error to a different location in the
file and recompiling.
If the error still occurs at the moved statement, the syntax
error is occurring somewhere in that statement.
If the error occurred... more ( see page 310)
E2190: Unexpected closing brace (C++) ( see page 311) An extra right brace was encountered where none was expected. Check for a
missing closing brace.
Useful Tip:
The IDE has a mechanism for finding a matching curly brace. If you put the
cursor on the '{' or '}' character, hold down Ctrl, hit 'Q' and then '{' or '}', it will
position the cursor on the matching brace.
E2189: extern variable cannot be initialized (C++) ( see page 311) The storage class extern applied to a variable means that the variable is being
declared but not defined here--no storage is being allocated for it.
Therefore, you can't initialize the variable as part of the declaration.
E2344: Earlier declaration of 'identifier' (C++) ( see page 311) This error message only shows up after the messages "Multiple declaration for
'identifier'" and "Type mismatch in redeclaration of 'identifier'". It tells you where
the previous definition of the identifier in question was found by the compiler, so
you don't have to search for it.
E2192: Too few parameters in call (C++) ( see page 311) This error message occurs when a call to a function with a prototype (via a
function pointer) had too few arguments. Prototypes require that all parameters
be given. Make certain that your call to a function has the same parameters as
the function prototype.
E2193: Too few parameters in call to 'function' (C++) ( see page 311) A call to the named function (declared using a prototype) has too few arguments.
Make certain that the parameters in the call to the function match the parameters 3
of the function prototype.
E2194: Could not find file 'filename' (C++) ( see page 311) The compiler is unable to find the file supplied on the command line.
E2197: File name too long (C++) ( see page 311) The file name given in an #include directive was too long for the compiler to
process.
File names in DOS must be no more than 79 characters long.

231
C++ Compiler Errors And Warnings (C++) RAD Studio 3.1 C++ Reference

E2195: Cannot evaluate function call (C++) ( see page 312) The error message is issued if someone tries to explicitly construct an object or
call a virtual function.
In integrated debugger expression evaluation, calls to certain functions (including
implicit conversion functions, constructors, destructors, overloaded operators,
and inline functions) are not supported.
E2198: Not a valid expression format type (C++) ( see page 312) Invalid format specifier following expression in the debug evaluate or watch
window. A valid format specifier is an optional repeat value followed by a format
character (c, d, f[n], h, x, m, p, r, or s).
E2200: Functions may not be part of a struct or union (C++) ( see page 312) This C struct or union field was declared to be of type function rather than pointer
to function.
Functions as fields are allowed only in C++.
Floating point error: Divide by 0 OR Floating point error: Domain OR Floating These fatal errors result from a floating-point operation for which the result is not
point error: Overflow (C++) ( see page 312) finite:

• Divide by 0 means the result is +INF or -INF exactly, such


as 1.0/0.0.
• Domain means the result is NAN (not a number), like
0.0/0.0.
• Overflow means the result is +INF (infinity) or -INF with
complete loss of precision, such as assigning
1e200*1e200 to a double.
Floating point error: Stack fault (C++) ( see page 312) The floating-point stack has been overrun. This error may be due to assembly
code using too many registers or due to a misdeclaration of a floating-point
function.
The program prints the error message and calls abort and _exit.
These floating-point errors can be avoided by masking the exception so that it
doesn't occur, or by catching the exception with signal.
Floating point error: Partial loss of precision OR Floating point error: Underflow These exceptions are masked by default, because underflows are converted to
(C++) ( see page 312) zero and losses of precision are ignored.
E2201: Too much global data defined in file (C++) ( see page 313) The sum of the global data declarations exceeds 64K bytes. This includes any
data stored in the DGROUP (all global variables, literal strings, and static locals).
Solutions
Check the declarations for any array that might be too large. You can also
remove variables from the DGROUP.
Here's how:

• Declare the variables as automatic. This uses stack


space.
• Dynamically allocate memory from the heap using calloc,
malloc, or farmalloc for the variables. This requires the
use of pointers.
Literal strings are also put in the DGROUP. Get the file
farstr.zip from our BBS to extract literal strings into their
own segment.... more ( see page 313)
E2203: Goto bypasses initialization of a local variable (C++) ( see page 313) In C++, it is illegal to bypass the initialization of a local variable.
This error indicates a goto statement that can transfer control past this local
variable.
E2204: Group overflowed maximum size: 'name' (C++) ( see page 313) The total size of the segments in a group (for example, DGROUP) exceeded 64K.
E2206: Illegal character 'character' (0x'value') (C++) ( see page 313) The compiler encountered some invalid character in the input file.
The hexadecimal value of the offending character is printed.
This can also be caused by extra parameters passed to a function macro.
3 E2207: Implicit conversion of 'type1' to 'type2' not allowed (C++) ( see page When a member function of a class is called using a pointer to a derived class,
313) the pointer value must be implicitly converted to point to the appropriate base
class.
In this case, such an implicit conversion is illegal.
E2208: Cannot access an inactive scope (C++) ( see page 313) You have tried to evaluate or inspect a variable local to a function that is currently
not active. (This is an integrated debugger expression evaluation message.)

232
3.1 C++ Reference RAD Studio C++ Compiler Errors And Warnings (C++)

E2209: Unable to open include file 'filename' (C++) ( see page 314) The compiler could not find the named file.
Possible Causes

• The named file does not exist.


• An #include file included itself.
• You do not have FILES set in CONFIG.SYS on your root
directory.
Solutions
• Verify that the named file exists.
• Set FILES = 20 in CONFIG.SYS.
E2210: Reference member 'member' is not initialized (C++) ( see page 314) References must always be initialized, in the constructor for the class.
A class member of reference type must have an initializer provided in all
constructors for that class.
This means you can't depend on the compiler to generate constructors for such a
class, because it has no way of knowing how to initialize the references.
E2212: Function defined inline after use as extern (C++) ( see page 314) Functions can't become inline after they have already been used.
Either move the inline definition forward in the file or delete it entirely.
The compiler encountered something like:
E2211: Inline assembly not allowed in inline and template functions (C++) ( see The compiler can't handle inline assembly statements in a C++ inline or template
page 314) function.
You could eliminate the inline assembly code or, in the case of an inline function,
make this a macro, and remove the inline storage class.
F1001: Internal code generator error (C++) ( see page 315) An error has occurred in the internal logic of the code generator. Contact
CodeGear technical support.
E2413: Invalid template declaration (C++) ( see page 315) After the declarator of a template member, either a semicolon, an initialization, or
a body was expected, but some other, illegal token was found. This message
appears when a template member is declared outside of the template, but the
syntax was wrong.
E2070: Invalid use of namespace 'identifier' (C++) ( see page 315) A namespace identifier was used in an illegal way, for example, in an expression.
E2214: Cannot have a 'non-inline function/static data' in a local class (C++) ( All members of classes declared local to a function must be entirely defined in
see page 315) the class definition.
This means that local classes cannot contain any static data members, and all of
their member functions must have bodies defined within the class definition.
E2215: Linkage specification not allowed (C++) ( see page 315) Linkage specifications such as extern "C" are only allowed at the file level.
Move this function declaration out to the file level.
E2216: Unable to create turboc.$ln (C++) ( see page 315) The compiler cannot create the temporary file TURBOC.$LN because it cannot
access the disk or the disk is full.
E2218: Templates can only be declared at namespace or class scope (C++) ( Templates cannot be declared inside classes or functions. They are only allowed
see page 315) in the global scope, or file level.
For example:
E2217: Local data exceeds segment size limit (C++) ( see page 316) The local variables in the current function take up more than 64K.
E2219: Wrong number of arguments in call of macro 'macro' (C++) ( see page Your source file called the named macro with an incorrect number of arguments.
316)
E2220: Invalid macro argument separator (C++) ( see page 316) In a macro definition, arguments must be separated by commas.
The compiler encountered some other character after an argument name.
This is correct:
E2221: Macro argument syntax error (C++) ( see page 316) An argument in a macro definition must be an identifier.
The compiler encountered some non-identifier character where an argument was
expected.
E2222: Macro expansion too long (C++) ( see page 316) A macro can't expand to more than 4,096 characters.
E2223: Too many decimal points (C++) ( see page 316) The compiler encountered a floating-point constant with more than one decimal 3
point.
E2224: Too many exponents (C++) ( see page 316) The compiler encountered more than one exponent in a floating-point constant.
E2225: Too many initializers (C++) ( see page 316) The compiler encountered more initializers than were allowed by the declaration
being initialized.
E2226: Extra parameter in call (C++) ( see page 317) A call to a function, via a pointer defined with a prototype, had too many
arguments.
E2227: Extra parameter in call to function (C++) ( see page 317) A call to the named function (which was defined with a prototype) had too many
arguments given in the call.
E2228: Too many error or warning messages (C++) ( see page 317) There were more errors or warnings than allowed.

233
C++ Compiler Errors And Warnings (C++) RAD Studio 3.1 C++ Reference

E2233: Cannot initialize a class member here (C++) ( see page 317) Individual members of structs, unions, and C++ classes can't have initializers.
A struct or union can be initialized as a whole using initializers inside braces.
A C++ class can only be initialized by the use of a constructor.
E2232: Constant/Reference member 'member' in class without constructors A class that contains constant or reference members (or both) must have at least
(C++) ( see page 317) one user-defined constructor.
Otherwise, there would be no way to ever initialize such members.
E2229: Member 'member' has the same name as its class (C++) ( see page A static data member, enumerator, member of an anonymous union, or nested
317) type cannot have the same name as its class.
Only a member function or a non-static member can have a name that is identical
to its class.
E2234: Memory reference expected (C++) ( see page 317) The built-in assembler requires a memory reference.
You probably forgot to put square brackets around an index register operand.
E2231: Member 'member' cannot be used without an object (C++) ( see page This means that you have written class::member where 'member' is an ordinary
318) (non-static) member, and there is no class to associate with that member.
For example, it is legal to write this:
E2235: Member function must be called or its address taken (C++) ( see page A reference to a member function must be called, or its address must be taken
318) with & operator.
In this case, a member function has been used in an illegal context.
For example:
O2237: DPMI programs must use the large memory model (C++) ( see page The compiler no longer issues this error.
318)
E2238: Multiple declaration for 'identifier' (C++) ( see page 318) This identifier was improperly declared more than once.
This might be caused by conflicting declarations such as:

• int a; double a;
• a function declared two different ways, or
• a label repeated in the same function, or
• some declaration repeated other than an extern function
or a simple variable
This can also happen by inadvertently including the same
header file twice. For example, given:
E2239: 'identifier' must be a member function (C++) ( see page 319) Most C++ operator functions can be members of classes or ordinary
non-member functions, but these are required to be members of classes:

• operator =
• operator ->
• operator ( )
• type conversions
This operator function is not a member function but should
be.
E2240: Conversion of near pointer not allowed (C++) ( see page 319) A near pointer cannot be converted to a far pointer in the expression evaluation
box when a program is not currently running. This is because the conversion
needs the current value of DS in the user program, which doesn't exist.
E2243: Array allocated using 'new' may not have an initializer (C++) ( see page When initializing a vector (array) of classes, you must use the constructor that
319) has no arguments.
This is called the default constructor, which means that you can't supply
constructor arguments when initializing such a vector.
E2244: 'new' and 'delete' not supported (C++) ( see page 319) The integrated debugger does not support the evaluation of the new and delete
3 operators.
E2245: Cannot allocate a reference (C++) ( see page 319) You have attempted to create a reference using the new operator.
This is illegal, because references are not objects and can't be created through
new.
E2309: Inline assembly not allowed (C++) ( see page 320) Your source file contains inline assembly language statements and you are
compiling it from within the integrated environment.
You must use the BCC command to compile this source file from the DOS
command line.
E2250: No base class to initialize (C++) ( see page 320) This C++ class constructor is trying to implicitly call a base class constructor, but
this class was declared with no base classes.
Check your declarations.

234
3.1 C++ Reference RAD Studio C++ Compiler Errors And Warnings (C++)

E2254: : expected after private/protected/private (C++) ( see page 320) When used to begin a private, protected, or public section of a C++ class, the
reserved words "private," "protected," and "public" must be followed by a colon.
E2255: Use :: to take the address of a member function (C++) ( see page 320) If f is a member function of class c, you take its address with the syntax
E2256: No : following the ? (C++) ( see page 320) The question mark (?) and colon (:) operators do not match in this expression.
The colon might have been omitted, or parentheses might be improperly nested
or missing.
E2257: , expected (C++) ( see page 320) A comma was expected in a list of declarations, initializations, or parameters.
This problem is often caused by a missing syntax element earlier in the file or
one of its included headers.
E2258: Declaration was expected (C++) ( see page 320) A declaration was expected here but not found.
This is usually caused by a missing delimiter such as a comma, semicolon, right
parenthesis, or right brace.
E2259: Default value missing (C++) ( see page 321) When a C++ function declares a parameter with a default value, all of the
following parameters must also have default values.
In this declaration, a parameter with a default value was followed by a parameter
without a default value.
E2260: Default value missing following parameter 'parameter' (C++) ( see page All parameters following the first parameter with a default value must also have
321) defaults specified.
E2263: Exception handling not enabled (C++) ( see page 321) A 'try' block was found with the exception handling disabled.
E2264: Expression expected (C++) ( see page 321) An expression was expected here, but the current symbol can't begin an
expression.
This message might occur where the controlling expression of an if or while
clause is expected or where a variable is being initialized.
This message is often due to a symbol that is missing or has been added.
E2266: No file names given (C++) ( see page 321) The command line contained no file names. You must specify a source file name.
E2265: No file name ending (C++) ( see page 321) The file name in an #include statement was missing the correct closing quote
or angle bracket.
E2271: Goto statement missing label (C++) ( see page 321) The goto keyword must be followed by an identifier.
E2272: Identifier expected (C++) ( see page 321) An identifier was expected here, but not found.
In C, an identifier is expected in the following situations:

• in a list of parameters in an old-style function header


• after the reserved words struct or union when the braces
are not present, and
• as the name of a member in a structure or union (except
for bit fields of width 0).
In C++, an identifier is also expected in these situations:
• in a list of base classes from which another class is
derived, following a double colon (::), and
• after the reserved word "operator" when no operator
symbol is present.
E2275: Opening brace expected (C++) ( see page 322) A left brace was expected at the start of a block or initialization.
E2276: ( expected (C++) ( see page 322) A left parenthesis was expected before a parameter list.
E2274: < expected (C++) ( see page 322) The keyword template was not followed by <.
Every template declaration must include the template formal parameters
enclosed within < >, immediately following the template keyword.
E2277: Lvalue required (C++) ( see page 322) The left side of an assignment operator must be an addressable expression.
Addressable expressions include the following:

• numeric or pointer variables


3
• structure field references or indirection through a pointer
• a subscripted array element
E2278: Multiple base classes not supported for Delphi classes (C++) ( see Delphi style classes cannot have multiple base classes.
page 322)
E2280: Member identifier expected (C++) ( see page 322) The name of a structure or C++ class member was expected here, but not found.
The right side of a dot (.) or arrow (->) operator must be the name of a member in
the structure or class on the left of the operator.

235
C++ Compiler Errors And Warnings (C++) RAD Studio 3.1 C++ Reference

E2279: Cannot find default constructor to initialize member 'identifier' (C++) ( When the following occurs
see page 323) 1.A C++ class 'class1' contains a member of class 'class2,'
and
2.You want to construct an object of type 'class1' (but not from another object of
type 'class1'). There must be a constructor class2::class2() so that the member
can be constructed.
This constructor without parameters is called the default constructor.
The compiler will supply a default constructor automatically unless you have
defined any constructor for class 'class2'.
In that case, the compiler will not supply the default constructor automatically (
you must supply one.
E2310: Only member functions may be 'const' or 'volatile' (C++) ( see page Something other than a class member function has been declared const or
323) volatile.
E2311: Non-virtual function 'function' declared pure (C++) ( see page 323) Only virtual functions can be declared pure, because derived classes must be
able to override them.
E2283: Use . or -> to call 'function' (C++) ( see page 323) You attempted to call a member function without providing an object. This is
required to call a member function.
E2284: Use . or -> to call 'member', or & to take its address (C++) ( see page A reference to a non-static class member without an object was encountered.
323) Such a member can't be used without an object, or its address must be taken
with the & operator.
E2285: Could not find a match for 'argument(s)' (C++) ( see page 323) No C++ function could be found with parameters matching the supplied
arguments. Check parameters passed to function or overload function for
parameters that are being passed.
E2286: Overloaded function resolution not supported (C++) ( see page 324) In integrated debugger expression evaluation, resolution of overloaded functions
or operators is not supported, not even to take an address.
E2287: Parameter 'number' missing name (C++) ( see page 324) In a function definition header, this parameter consisted only of a type specifier
'number' with no parameter name.
This is not legal in C.
(It is allowed in C++, but there's no way to refer to the parameter in the function.)
E2288: Pointer to structure required on left side of -> or ->* (C++) ( see page Nothing but a pointer is allowed on the left side of the arrow (->) in C or C++.
324) In C++ a -> operator is allowed.
E2290: 'code' missing ] (C++) ( see page 324) This error is generated if any of the following occur:

• Your source file declared an array in which the array


bounds were not terminated by a right bracket.
• The array specifier in an operator is missing a right
bracket.
• The operator [ ] was declared as operator [.
• A right bracket is missing from a subscripting expression.
Add the bracket or fix the declaration.
Check for a missing or extra operator or mismatched
parentheses.
E2291: brace expected (C++) ( see page 324) A right brace was expected at the end of a block or initialization.
E2292: Function should return a value (C++) ( see page 324) Your source file declared the current function to return some type other than int
or void, but the compiler encountered a return with no value. This usually
indicates some sort of error.
Functions declared as returning int are exempt because older versions of C did
not support void function return types.
E2293: ) expected (C++) ( see page 325) A right parenthesis was expected at the end of a parameter list.
E2294: Structure required on left side of . or .* (C++) ( see page 325) The left side of a dot (.) operator (or C++ dot-star operator, .*) must evaluate to a
structure type. In this case it did not.
3 This error can occur when you create an instance of a class using empty
parentheses, and then try to access a member of that 'object'.
E2312: 'constructor' is not an unambiguous base class of 'class' (C++) ( see A C++ class constructor is trying to call a base class constructor 'constructor.'
page 325) This error can also occur if you try to change the access rights of
'class::constructor.'
Check your declarations.
E2313: Constant expression required (C++) ( see page 325) Arrays must be declared with constant size.
This error is commonly caused by misspelling a #define constant.
E2296: Templates not supported (C++) ( see page 325) An error has occurred while using the command-line utility H2ASH. See the
online file "tsm_util.txt" for further information about this utility.

236
3.1 C++ Reference RAD Studio C++ Compiler Errors And Warnings (C++)

E2314: Call of nonfunction (C++) ( see page 325) The name being called is not declared as a function.
This is commonly caused by incorrectly declaring the function or misspelling the
function name.
E2321: Declaration does not specify a tag or an identifier (C++) ( see page 325) This declaration doesn't declare anything.
This may be a struct or union without a tag or a variable in the declaration. C++
requires that something be declared.
For example:
E2297: 'this' can only be used within a member function (C++) ( see page 326) In C++, "this" is a reserved word that can be used only within class member
functions.
E2316: 'identifier' is not a member of 'struct' (C++) ( see page 326) You are trying to reference 'identifier' as a member of 'struct', but it is not a
member.
Check your declarations.
E2317: 'identifier' is not a parameter (C++) ( see page 326) In the parameter declaration section of an old-style function definition, 'identifier'
is declared but not listed as a parameter. Either remove the declaration or add
'identifier' as a parameter.
E2319: 'identifier' is not a public base class of 'classtype' (C++) ( see page 326) The right operand of a .*, ->*, or ::operator was not a pointer to a member of a
class that is either identical to (or an unambiguous accessible base class of) the
left operand's class type.
E2320: Expression of scalar type expected (C++) ( see page 326) The !, ++, and -- operators require an expression of scalar type.
Only these types are allowed:

• char
• short
• int
• long
• enum
• float
• double
• long double
• pointer
E2302: No type information (C++) ( see page 327) The integrated debugger has no type information for this variable. Ensure that
you've compiled the module with debug information. If it has, the module may
have been compiled by another compiler or assembler.
E2303: Type name expected (C++) ( see page 327) One of these errors has occurred:

• In declaring a file-level variable or a struct field, neither a


type name nor a storage class was given.
• In declaring a typedef, no type for the name was supplied.
• In declaring a destructor for a C++ class, the destructor
name was not a type name (it must be the same name as
its class).
• In supplying a C++ base class name, the name was not
the name of a class.
E2304: 'Constant/Reference' variable 'variable' must be initialized (C++) ( see This C++ object is declared constant or as a reference, but is not initialized.
page 327) It must be initialized at the point of declaration.
E2305: Cannot find 'class::class' ('class'&) to copy a vector OR Cannot find When a C++ class 'class1' contains a vector (array) of class 'class2', and you
'class'::operator=('class'&) to copy a vector (C++) ( see page 327) want to construct an object of type 'class1' from another object of type 'class 1',
you must use this constructor:
3
E2306: Virtual base classes not supported for Delphi classes (C++) ( see page Delphi style classes cannot be derived virtually, not even from other Delphi style
328) classes.
E2308: do statement must have while (C++) ( see page 328) Your source file contained a do statement that was missing the closing while
keyword.
E2322: Incorrect number format (C++) ( see page 328) The compiler encountered a decimal point in a hexadecimal number.
E2324: Numeric constant too large (C++) ( see page 328) String and character escape sequences larger than hexadecimal or octal 77 can't
be generated.
Two-byte character constants can be specified by using a second backslash. For
example,

237
C++ Compiler Errors And Warnings (C++) RAD Studio 3.1 C++ Reference

E2282: Namespace name expected (C++) ( see page 328) The name of a namespace symbol was expected.
E2334: Namespace member 'identifier' declared outside its namespace (C++) ( Namespace members must be declared inside their namespace. You can only
see page 328) use explicit qualification to define a namespace member (for example, to give a
body for a function declared in a namespace). The declaration itself must be
inside the namespace.
E2325: Illegal octal digit (C++) ( see page 329) The compiler found an octal constant containing a non-octal digit (8 or 9).
E2329: Invalid combination of opcode and operands (C++) ( see page 329) The built-in assembler does not accept this combination of operands.
Possible causes

• There are too many or too few operands for this


assembler opcode.
• The number of operands is correct, but their types or
order do not match the opcode.
E2327: Operators may not have default argument values (C++) ( see page 329) It is illegal for overloaded operators to have default argument values.
E2330: Operator must be declared as function (C++) ( see page 329) An overloaded operator was declared with something other than function type.
For example:
E2333: Class member 'member' declared outside its class (C++) ( see page C++ class member functions can be declared only inside the class declaration.
329) Unlike nonmember functions, they can't be declared multiple times or at other
locations.
E2335: Overloaded 'function name' ambiguous in this context (C++) ( see page The only time an overloaded function name can be used or assigned without
329) actually calling the function is when a variable or parameter of the correct
function pointer type is initialized or assigned the address of the overload
function.
In this case, an overloaded function name has been used in some other context,
for example, the following code will generate this error:
E2339: Cannot overload 'main' (C++) ( see page 330) You cannot overload main.
E2336: Pointer to overloaded function 'function' doesn't match 'type' (C++) ( A variable or parameter is assigned (or initialized with) the address of an
see page 330) overloaded function.
However, the type of the variable or parameter doesn't match any of the
overloaded functions with the specified name.
E2337: Only one of a set of overloaded functions can be "C" (C++) ( see page C++ functions are by default overloaded, and the compiler assigns a new name
330) to each function.
If you wish to override the compiler's assigning a new name by declaring the
function extern "C", you can do this for only one of a set of functions with the
same name.
(Otherwise the linker would find more than one global function with the same
name.)
E2338: Overlays only supported in medium, large, and huge memory models The compiler no longer issues this error.
(C++) ( see page 330)
E2340: Type mismatch in parameter 'number' (C++) ( see page 330) The function called, via a function pointer, was declared with a prototype.
However, the given parameter number (counting left to right from 1) could not be
converted to the declared parameter type.
When compiling C++ programs, this message is always preceded by another
message that explains the exact reason for the type mismatch.
That other message is usually "Cannot convert 'type1' to 'type2'" but the
mismatch might be due to many other reasons.
E2341: Type mismatch in parameter 'number' in call to 'function' (C++) ( see Your source file declared the named function with a prototype, and the given
page 331) parameter number (counting left to right from 1) could not be converted to the
declared parameter type.
When compiling C++ programs, this message is always preceded by another
message that explains the exact reason for the type mismatch.
That other message is usually "Cannot convert 'type1' to 'type2'", but the
mismatch might be due to many other reasons.
E2342: Type mismatch in parameter 'parameter' (C++) ( see page 331) Your source file declared the function called via a function pointer with a
3 prototype.
However, the named parameter could not be converted to the declared
parameter type.
When compiling C++ programs, this message is always preceded by another
message that explains the exact reason for the type mismatch.
That other message is usually "Cannot convert 'type1' to 'type2'" but the
mismatch might be due to many other reasons.

238
3.1 C++ Reference RAD Studio C++ Compiler Errors And Warnings (C++)

E2343: Type mismatch in parameter 'parameter' in call to 'function' (C++) ( see Your source file declared the named function with a prototype, and the named
page 331) parameter could not be converted to the declared parameter type.
When compiling C++ programs, this message is always preceded by another
message that explains the exact reason for the type mismatch.
That other message is usually "Cannot convert 'type1' to 'type2'" but the
mismatch might be due to many other reasons.
E2345: Access can only be changed to public or protected (C++) ( see page A C++ derived class can modify the access rights of a base class member, but
331) only to public or protected.
A base class member can't be made private.
E2349: Nonportable pointer conversion (C++) ( see page 331) An implicit conversion between a pointer and an integral type is required, but the
types are not the same size. You must use an explicit cast.
This conversion might not make any sense, so be sure this is what you want to
do.
E2350: Cannot define a pointer or reference to a reference (C++) ( see page It is illegal to have a pointer to a reference or a reference to a reference.
332)
E2352: Cannot create instance of abstract class 'class' (C++) ( see page 332) Abstract classes (those with pure virtual functions) can't be used directly, only
derived from.
When you derive an abstract base class, with the intention to instantiate
instances of this derived class, you must override each of the pure virtual
functions of the base class exactly as they are declared.
For example:
E2354: Two operands must evaluate to the same type (C++) ( see page 332) The types of the expressions on both sides of the colon in the conditional
expression operator (?:) must be the same, except for the usual conversions.
These are some examples of usual conversions

• char to int
• float to double
• void* to a particular pointer
In this expression, the two sides evaluate to different types
that are not automatically converted.
This might be an error or you might merely need to cast one
side to the type of the other.
When compiling C++ programs, this message is always
preceded by another message that explains the exact
reason for the type mismatch.... more ( see page 332)
E2355: Recursive template function: 'x' instantiated 'y' (C++) ( see page 333) The compiler has detected a recursive template function instance. For example:
E2356: Type mismatch in redeclaration of 'identifier' (C++) ( see page 333) Your source file redeclared a variable with a different type than was originally
declared for the variable.
Possible Causes
This can occur if a function is called and subsequently declared to return
something other than an integer.
Solutions
If this has happened, you must declare the function before the first call to it.
E2357: Reference initialized with 'type1', needs lvalue of type 'type2' (C++) ( A reference variable that is not declared constant must be initialized with an
see page 333) lvalue of the appropriate type.
In this case, the initializer either wasn't an lvalue, or its type didn't match the
reference being initialized.
E2358: Reference member 'member' needs a temporary for initialization (C++) You provided an initial value for a reference type that was not an lvalue of the
( see page 333) referenced type.
This requires the compiler to create a temporary for the initialization.
Because there is no obvious place to store this temporary, the initialization is
illegal.
3

239
C++ Compiler Errors And Warnings (C++) RAD Studio 3.1 C++ Reference

E2360: Invalid register combination (e.g. [BP+BX]) (C++) ( see page 334) The built-in assembler detected an illegal combination of registers in an
instruction.
These are valid index register combinations:

• [BX]
• [BP]
• [SI]
• [DI]
• [BX+SI]
• [BX+DI]
• [BP+SI]
• [BP+DI]
Other index register combinations are not allowed.
E2361: 'specifier' has already been included (C++) ( see page 334) This type specifier occurs more than once in this declaration.
Delete or change one of the occurrences.
E2362: Repeat count needs an lvalue (C++) ( see page 334) The expression before the comma (,) in the Watch or Evaluate window must be
an accessible region of storage. For example, expressions like this one are not
valid:
E2363: Attempting to return a reference to local variable 'identifier' (C++) ( see This C++ function returns a reference type, and you are trying to return a
page 334) reference to a local (auto) variable.
This is illegal, because the variable referred to disappears when the function exits.
You can return a reference to any static or global variable, or you can change the
function to return a value instead.
E2364: Attempting to return a reference to a local object (C++) ( see page 334) You attempted to return a reference to a temporary object in a function that
returns a reference type. This may be the result of a constructor or a function call.
This object will disappear when the function returns, making the reference illegal.
E2365: Member pointer required on right side of .* or ->* (C++) ( see page 335) The right side of a C++ dot-star (.*) or an arrow star (->*) operator must be
declared as a pointer to a member of the class specified by the left side of the
operator.
In this case, the right side is not a member pointer.
E2366: Can't inherit non-RTTI class from RTTI base OR E2367 Can't inherit When virtual functions are present, the RTTI attribute of all base classes must
RTTI class from non-RTTI base (C++) ( see page 335) match that of the derived class.
E2368: RTTI not available for expression evaluation (C++) ( see page 335) Expressions requiring RTTI are not supported by the expression evaluator in the
integrated debugger. This error message is only issued by the expression
evaluator (if you try to Inspect, Watch, or Evaluate), not by the compiler.
E2371: sizeof may not be applied to a bit field (C++) ( see page 335) sizeof returns the size of a data object in bytes, which does not apply to a bit field.
E2372: sizeof may not be applied to a function (C++) ( see page 335) sizeof can be applied only to data objects, not functions.
You can request the size of a pointer to a function.
E2373: Bit field cannot be static (C++) ( see page 335) Only ordinary C++ class data members can be declared static, not bit fields.
E2374: Function 'function' cannot be static (C++) ( see page 335) Only ordinary member functions and the operators new and delete can be
declared static.
Constructors, destructors and other operators must not be static.
Stack overflow (C++) ( see page 335) This error is reported when you compile a function with the Test Stack Overflow
option on, but there is not enough stack space to allocate the function's local
variables.
This error can also be caused by the following:

• infinite recursion, or
• an assembly language procedure that does not maintain
3 the stack project
• a large array in a function
E2376: statement missing (C++) ( see page 336) In a do, for, if, switch, or while statement, the compiler found no left parenthesis
after the while keyword or test expression.
E2377: statement missing ) (C++) ( see page 336) In a do, for, if, switch, or while statement, the compiler found no right parenthesis
after the while keyword or test expression.
E2378: do-while or for statement missing ; (C++) ( see page 336) In a do or for statement, the compiler found no semicolon after the right
parenthesis.

240
3.1 C++ Reference RAD Studio C++ Compiler Errors And Warnings (C++)

E2379: Statement missing ; (C++) ( see page 336) The compiler encountered an expression statement without a semicolon following
it.
E2380: Unterminated string or character constant (C++) ( see page 336) The compiler found no terminating quote after the beginning of a string or
character constant.
E2381: Structure size too large (C++) ( see page 336) Your source file declared a structure larger than 64K.
E2382: Side effects are not allowed (C++) ( see page 336) Side effects such as assignments, ++, or -- are not allowed in the debugger
watch window. A common error is to use x = y (not allowed) instead of x == y to
test the equality of x and y.
E2383: Switch selection expression must be of integral type (C++) ( see page The selection expression in parentheses in a switch statement must evaluate to
336) an integral type (char, short, int, long, enum).
You might be able to use an explicit cast to satisfy this requirement.
E2433: Specialization after first use of template (C++) ( see page 337) An ANSI C++ rule requires that a specialization for a function template be
declared before its first use. This error message is only issued when the ANSI
conformance option (-A) is active.
E2384: Cannot call near class member function with a pointer of type 'type' (C++) Also E2385 Cannot call near class member function 'function' with a pointer of
( see page 337) type 'type'
Member functions of near classes can't be called via a member pointer.
This also applies to calls using pointers to members.
(Remember, classes are near by default in the tiny, small, and medium memory
models.)
Either change the pointer to be near, or declare the class as far.
E2390: Type mismatch in parameter 'number' in template class name 'template' The actual template argument value supplied for the given parameter did not
(C++) ( see page 337) exactly match the formal template parameter type.
When compiling C++ programs, this message is always preceded by another
message that explains the exact reason for the type mismatch.
That other message is usually "Cannot convert 'type1' to 'type2'" but the
mismatch might be due to many other reasons.
E2391: Type mismatch in parameter 'parameter' in template class name The actual template argument value supplied for the given parameter did not
'template' (C++) ( see page 337) exactly match the formal template parameter type.
When compiling C++ programs, this message is always preceded by another
message that explains the exact reason for the type mismatch.
That other message is usually "Cannot convert 'type1' to 'type2'" but the
mismatch might be due to many other reasons.
E2394: Too few arguments passed to template 'template' (C++) ( see page 337) A template class name was missing actual values for some of its formal
parameters.
E2395: Too many arguments passed to template 'template' (C++) ( see page A template class name specified too many actual values for its formal parameters.
338)
E2396: Template argument must be a constant expression (C++) ( see page A non-type template class argument must be a constant expression of the
338) appropriate type.
This includes constant integral expressions and addresses of objects or functions
with external linkage or members.
E2401: Invalid template argument list (C++) ( see page 338) This error indicates that an illegal template argument list was found.
In a template declaration, the keyword template must be followed by a list of
formal arguments enclosed within < and > delimiters.
E2400: Nontype template argument must be of scalar type (C++) ( see page A nontype formal template argument must have scalar type; it can have an
338) integral, enumeration, or pointer type.
E2415: Template functions may only have 'type-arguments' (C++) ( see page A function template was declared with a non-type argument.
338) This is not allowed with a template function, as there is no way to specify the
value when calling it.
E2425: 'member' is not a valid template type member (C++) ( see page 338) A member of a template with some actual arguments that depend on the formal
arguments of an enclosing template was found not to be a member of the
specified template in a particular instance.
E2428: Templates must be classes or functions (C++) ( see page 338) The declaration in a template declaration must specify either a class type or a
function.
E2432: 'template' qualifier must name a template class or function instance' When defining a template class member, the actual arguments in the template
(C++) ( see page 339) class name used as the left operand for the :: operator must match the formal 3
arguments of the template class.
E2442: Two consecutive dots (C++) ( see page 339) Because an ellipsis contains three dots (...), and a decimal point or member
selection operator uses one dot (.), two consecutive dots cannot legally occur in a
C program.
E2443: Base class 'class' is initialized more than once (C++) ( see page 339) In a C++ class constructor, the list of initializations following the constructor
header includes base class 'class' more than once.
E2444: Member 'member' is initialized more than once (C++) ( see page 339) In a C++ class constructor, the list of initializations following the constructor
header includes the same member name more than once.

241
C++ Compiler Errors And Warnings (C++) RAD Studio 3.1 C++ Reference

E2445: Variable 'identifier' is initialized more than once (C++) ( see page 339) This variable has more than one initialization. It is legal to declare a file level
variable more than once, but it can have only one initialization (even if two are
the same).
E2446: Function definition cannot be a typedef'ed declaration (C++) ( see page In ANSI C, a function body cannot be defined using a typedef with a function
339) Type.
Redefine the function body.
E2132: Templates and overloaded operators cannot have C linkage (C++) ( You tried to use a linkage specification with a template or overloaded operator.
see page 339) The most common cause for this error message is having the declaration
wrapped in an extern "C" linkage specification.
E2447: 'identifier' must be a previously defined enumeration tag (C++) ( see This declaration is attempting to reference 'ident' as the tag of an enum type, but
page 340) it has not been so declared.
Correct the name, or rearrange the declarations.
E2448: Undefined label 'identifier' (C++) ( see page 340) The named label has a goto in the function, but no label definition.
E2449: Size of 'identifier' is unknown or zero (C++) ( see page 340) This identifier was used in a context where its size was needed.
A struct tag might only be declared (the struct not defined yet), or an extern array
might be declared without a size.
It's illegal then to have some references to such an item (like sizeof) or to
dereference a pointer to this type.
Rearrange your declaration so that the size of 'identifier' is available.
E2450: Undefined structure 'structure' (C++) ( see page 340) The named structure was used in the source file, probably on a pointer to a
structure, but had no definition in the source file.
This is probably caused by a misspelled structure name or a missing declaration.
E2451: Undefined symbol 'identifier' (C++) ( see page 340) The named identifier has no declaration.
Possible Causes

• Actual declaration of identifier has been commented out.


• Misspelling, either at this point or at the declaration.
• An error in the declaration of the identifier.
• The header file in which the identifier is declared was not
included using #include
Tools to help track down the problem:
GREP ( see page 170)
E2453: Size of the type 'identifier' is unknown or zero (C++) ( see page 340) This type was used in a context where its size was needed.
For example, a struct tag might only be declared (the struct not defined yet).
It's illegal then to have some references to such an item (like sizeof) or to
dereference a pointer to this type.
Rearrange your declarations so that the size of this type is available.
E2452: Size of the type is unknown or zero (C++) ( see page 341) This error message indicates that an array of unspecified dimension nested
within another structure is initialized and the -A (ANSI) switch is on. For example:
E2454: union cannot be a base type (C++) ( see page 341) A union can't be used as a base type for another class type.
E2455: union cannot have a base type (C++) ( see page 341) In general, a C++ class can be of union type, but such a class can't be derived
from any other class.
E2456: Union member 'member' is of type class with 'constructor' (or destructor, A u