You are on page 1of 576
y ‘i y DELPHI IN A NUTSHELL A Nesktop Quick Reference A Desktop Quick Reference Ray Lischner Beijing + Cumirig Delphi in a Nutshelt by Ray Lisehner Copynght © 2000 OReilly & Associates, Inc. All nghts reserved, ranted in the United States of America Published by O'Reilly & Associates, Inc, 101 Mortis Street, Sebastopol, CA 95472, Editor: simon Hayes Production Editor: siuiclense Newell Cover Designer: ‘lie Volckhausen Printing History: March 2000: First Edition. "Nutshell Handbook, the Nutshell Handbook logo, and the O'Reilly logo are registered trademarks of O'Reilly & Associates, Inc. The assocration between the image of a Ivnx and the topic of Delphi isa trademark of O'Reilly & Asseerates, Tne Many of the designations used by manufacturers and sellers to distinguish their products are clasmed as trademarks. Where those designations appear in this book, and O'Reilly & Associates, Inc. was aware ofa trademark claim, the deagnations have been prnted in caps of initial caps. While every precaution has been taken inthe preparation ofthis book, the publisher assumes no responsibilty in exits or umssions, of for damages resulting from the Use of the information contained heresn, Library of Congress Cataloging-in-Publication Data Lschner, Ray, 1961— Delph un a nutshell / by Ray Lischner ecm ISN 1-56592-059-5 (alk. paper) 1. Delphi (Computer file) 2. Computer software—evelopment I. Title (QA7676.D47 156 2000 005.208-de2 99-086244 ISBN: 1-56592.059.5 (7/001 wm Table of Contents Preface Chapter 1—Delpbi Pascal Units Programs Libraries Packages Data Types Variables and Constants Exception Handling. File YO. Functions and Provedures Chapter 2—The Delphi Object Model Classes and Objects Interfaces, Reference Counting Messages soe Memory Management... Old-Seyle Object Types Chapter 3—Runtime Type Information Virtual Method Table Published Declarations ‘The Typlnfo Unit Virtual and Dynamic Methods Initialization and Finalization Automated Metiuds Interfaces Exploring RTT Chapter 4—Concurrent Programming ‘Thread and Processes The TThread Class ‘The BeginThread and EndThread Functions .. Thread Local Storage Processes Futures Chapter 5—Language Keference Chapter 6—System Constants Variant Type Codes Open Array Types Virtual Method Table Ottsets Runtime Error Codes, Chapter 7—Operators Unary Operators ‘Muldplicaive Operators Additive Operators Comparison Operators Chapter 8—Compiler Directives Appendix A—Command-Line Tools Appendix B—The SysUtils Untt Index 90 n a oo) 35 103 108 109 109 19 127 422 22 23 424 25 428 428 430 81 432 435 473 488 543 Preface Borland’s Delph is a combination of a modem programming language, an inte- trated development environment (IDE), and the visual component library (VCL) Delphi's IDE i readily familiar 19 anyone who has wee smi tools. Ror example, 4 WYSIWYG form editor lets you design a window visually, with drag-and-drop cape, Mute inporany, tie framework 18 objectonented, extensible and custom able, due to the power and flexibly of the Delphi programming language. The hear of Delphi is the Delphi Pascal programming language, which has key features to support the IDE and VCL. It has all the power of a’ modem object nented langsinge, along withthe elegance and simpliciyy of Pascal Debbi in a Nutsbell is a comprehensive reference manual for Delphi Pascal t covers the entice language, and it also highlights ways to use the language efec- tively Eapctieuced Delphi prugraumers cat use dhs book as an alphabeical reference, Newcomers to Delph should spend exta time with the first few chap- ters. [hope that everyone wil find something of value in these pages. Not Your Father's Pascal Delphi Pascal is one of many object-onented variants of Pascal. Over the years Delphi has evolved and is no longer recognizable as the Pascal you used in school all those many years ago. In addition wo unitbused audular programy andl robust class model, Delphi Pascal has a number of other modem language features, including the following: © Intertaces (similar to Java™ and COM sntesfaces) + Unicode stangs + Properties + Exception handling Delphi started as a Windows programming language and envitonment, and many Delphi programmers (myself included) consider Delphi to be the best Windows development tool available. Deiphr includes full support for COM and ActiveX, an, objectonented widget library (called the Visual Component Library, or VCL). and. 4 rapid-application development environment that 1s extensible and customizable, Delphi for Linux AAS Lite this, Borland is hard at work porting Delphi to Linux. Peshaps when you ‘ead this, Delph for Linux will be available, bringing its integrated development enuonmient fo X-Windows, including ts WYSIWYG form edlfor, multtier data base support, and full CORBA suppor. Until Borland finishes this work and releases Delphi for Linux, can only specu- late abour how the final product will look. (No, T don't get any specal msde snformation.) You can rely on the core language heing the same in both Delphs for lunux and Delphi for Windows, including classes, objects, interfaces, strings, dynamic arrays, exception, aut the basic data types. Most of the builtin subrou tines will work the same under Linux as under Windows Some language features described in this book are clearly Windows specific, such as the CéShow and Dl1Proc vanables or the Pindifinstance function. If you Want to write code thar 1s portahle herween Windows and Linux, you must avoid these Windows-specific features, Delphi for Windows 1s the best development environment for writing Windows applications and libraries. To attaun this preaues poston, Delph has incorporated. a number of Windows-specifc features. Borland has a goal of making Delph for Linux the best Liqux development environment. To achieve that goal, we can expect Delphi ta include some Linux-specfic features, ‘Ym just guessing. but I believe ic will he foasihle to write code that 1s portable between Windows and Linux. However, you will have to sacrifice some features that are unique to each envirumuent. Wrtung components that are easily portable, specially interactive controls, will probably be a daunting task. Making an appli- cation that is portable will most likely be easier, About This Book ‘The first four chapters of this book present information om haw effectively, and subsequent chapters form the language reference proper. Chapter 1, Delpbi Pascal, discusses the differences between Delphi Pascal and ‘sandard Pascal. If you have used Tusbo Paceal or other variants of Object Pascal, you should ge Chapter 1 a quick read to lear about the new features that are unique t0 Delphi Pascal. Similarly, if you haven't used Pascal since your college days (all those years ago). you must rearl Chapter 1 to leatn about the new and. nifty features in Delphi Pascal. You mught be surprised at how far the language hhas come over the yeas Chapter 2, The Dolpbr Object Model, discusses classes an Ulyeuts m greater depth. If you have used other vanants of Object Pascal, you must read this chapter ise Delph bill Preface ae —_ a because Delphi's object model 1s quite different. IF you have experience with other ‘object-onented programming languages, read Chapter 2 to learn the differences between Delp sind valet languages, sult a9 Java snd Or Chapter 3, Runtime Type Information, covers the key to Delphits integrated devel ‘opment environment. RTTI 1s not documented in Borland!’ offical help files, but anyone writing or using components (that 1s, every Delphi programmer) should understand the nature of RTTT, including its imitations and proper uses. Chapter 4 tells you everything there is to know about RTTI, and then some. Chapter 4, Concurrent Programming, 36 about using Delphi in a modern, muli- threaded, multiprocessor world. Delphi includes several language fearues to help ‘you write multithreaded applicauons, but these features can be difficult to use if you do not have much expenence with the ticks and traps of multithreaded programming. This chapter gets you started uting Delphi elfectively to write ‘modern applications, Chapter 5, Language Reference, 8 the bull of the book. The alphabetical refer- cence lists every keyword, direcuve, subrouune, type, and vanuble an the Delpla Pascal language and its system units. Full examples show you how to use the language correctly and effectively Chapter 6, System Constants, contains tables of related constants, Chapter 51s large fenonigh without adding these literals Maving them 10 a separate chapter makes the complete reference easier to use. Chapter 7, Operators, describes all the arithmetic and other operators in Delp Pascal. Symbols do not alphabetize wel, so listing the symbol operators in thet con chapxer makes i ease find information about a particular operator. Chapter 8, Compiler Directives, lists all the specal comments that you can melude sn yout source code to control how Delphi compiles and links your program. Appendix A, Command-time Tools dscns the usage and options for the vanious ‘commandline tools that come with Delphi, These tools are not related to the Delpin Pascal language, but they are often overlooked and can be extremely ‘seful for the Delph profesional Append B, Tho Syst: Uni list all the subroutines, ypes, nd varables in the SyaVtils unit. This unit not bul nto the compiler (asthe System uni 1). Its ‘not part of the Delpht Pascal language, but 13 part of Deiphi's euntime lbeary Nonetheless, many Delphi professionals have come to rely on SysUtils as though ic were part of the language, and indeed, many subroutines in SysUeils are supe- tiv dew eyuivaeuts is Use Syste uk (oul ay AusiPus used Uf FOS) Conventions Used in This Book ‘The following typographical conventions are used sn this book Constant width Used for Delph entifcrs sud symbols, uicludling all keywords aud dite tives. In the language seference, constant wicth shows the syntax elements that must be used exactly as Shown. For example, the array declaration Preface requires the square brackets and other symbols. and the tyne, array, and of keywords to be used as shown: type name = array(Index type, ...] of nase type: Constant width italic Used in the language reference for syntax elements that must be replaced by your code. In the previous example, you must supply the type Name, the Index type, and the Rase type. Constant Width Bold Used in longer code examples to highlight the lines that contain the language ‘element being described. alte Used to indicate variables, filenames, directory names, URLs, and glossary Note Icons the ourrounding text. g ‘The owl icon designates a tip, suggestion, or general note related to & ‘The turkey icon designates a warning related to the surrounding tex. For More Information ‘When you have a question about Delph, you should fist consult the Delphi help files. Delphi also comes with numerous examples (in the Dems directory) that are ‘often more helpful than the help files, 1f you still cannot find the answer you seek, try posing your question to one of the many Delphi newsgroups. Several standard newsgioups exist, and Borland mai. tains its own newsgroups on its server, forums.borland com. In panticula, oriand pubic. delphi.objectpascal 1s the appropriate newsgroup for questions related to the Delphi Pascal language If you want to know about Delphi's integrated development environment, about the visual component library, or other topics on Delphi programming, the two ‘most popular books are Mastering Delphi 5, by Marco Cann (Sybex, 1999) and Delph 5 Developer's Guide, by Steve Terxesra and Xavier Pacheco (Sams, 1999), If you find errors or omissions an this book, please bring them to my attention by sending email to nussbell@iempest-sw:com. I receive t00 much email to answer © Preface ‘every message indivdually, but be assured that I tad everything (everything that makes it past my anti-spam fiers, anyway). How to Contact Us “The information in this book has bon tested and verified to the best of our ability, Dut mustakes and oversights do occur. Please let us know about ettors you may find, as well as your suggestions for future editions, by writing to: Oxeilly & Associates, Inc 101 Morns Street Sebastopol, CA 95472 (800) 998-9938 Gin the U.S. ot Canada) (707) 820-0515 (international or local) (707) 829.0104 (fax) ‘You can also send us email messages. To be put on our muzling list or to request a catalog, send mail to: ‘mfo@oreilly.com To ask technical questions or to comment on the book, send email to: bookquestionstorelly com To find out about errata and any plans for fuure editions, you can access the ook’s web site at eww oreily.comieatalog/delphs For more information about ths book and others, see the O'Reilly web site sun oreilly.com Acknowledgments I thank Tim O'Reilly for taking a chance with his fist Delphi tile. I look forwaed to reading and writing other Delphi boolis published by O*Relly “The technical editors—Allen Raner and Hallvard Vasshotn—did an excellent ob of spotting my mistakes. Hallvard's copious and detailed comments were snvahuable. Any remaming mistakes are ones that Cade afl Une ediors finshed thes ao cough work. 1 thank my editor, Simon Hayes, and the entice team at 'Reily—Bob Herbstman, ‘Troy Mot, and the design and production staff—for turning my humble manu- scp soto this polished book you tee now None of my books would be possible without the suppor of family 1 thank my wife, Cheryl, and the once-and-future programmer, Anus, who makes it all wworthtie Preface CHAPTER 1 Delphi Pascal Delph Pascal 1 an objectonented extension of wadtionl Pascal. It is not quite a proper superset of ISO standard Pascal, but if you remember Pascal from your School days. you will easy pick up Delphi's extensions. Delph not ps a fancy Pascal, though. Delphi adds powerful object-oriented feaures, without making the lungusge woo complicated. Delph tas asses and objects, exception handling, multithreaded programming, modular programming, dynamic and static linking, OLE automaton, and much, much more ‘Thus chapter describes Delphi's extensions to Pascal, You should already be familar woth tridtional Pascal or one of the other poplar extensions to Pascal, such as Object Pascal. If you already know Borland's Object Pascal from the Turbo Fascalproduets, yOu Will need to leam a new object model (detailed in Chapter 2, ‘The Delpbs Obyct Model), plus other new Features, Bottand uses the name “Object Pascal” to refer to Delphi's programming language, Dut many other languages use the same name, which resuls in confusion. This book uses the name "Delphi Pascal” to refer to the Delph programuning language, leaving Object Pascal forthe many other obyct-orented variations of Pascal Units Delphi Pascal is a modular programming language, and the basic module is called ‘unit To compile and link a Delphi program, you need a program source file and any number of additional units sn sousce or abject form. The program source fle w usually called a project source file because the project can be a program or a library—that is, a dynamucally linked library (DLL). When Delphi links a program or library, it can statically like all the units into a Single exe ur all Ble, or Gu dymaanically link wo unis dhat ure an packages. package 1s a special kind of DLL that contains one or more units and some extra logic that enables Delplu to hude the differences between a statically linked unit and a dynamically linked unit in a package See the section “Packages,” later in thus chapter, for more information about packages, Forms and Files Some units represent forms. A form is Delphi's term for a window you can edit with Delphi's GUL builder. A form descnption is stored in a .dfm file, which contains the Forme layout, contents, aad prupeties Every fm file has an associated pas file, which contains the coe fur dia form, Forms and .dfm files are part of Delphi's integrated development environment ADE), but are not part of the tormal Delphi Pascal language, Nonetheless. the language sncludes several features that exist solely to support Delphi's IDE and form descriptions. Read about these features sn depth in Chapter 3, Runtime Type Information. ‘which maintains compatibility with the fist version of Delph, Ver. sons 2 and later produce only 32-bit programs, so Delphi's linker convers the df resource to a 32-bit resewece automatically Th binary .dfm files are usually compatible with all versions of Delphi Delphi 5 also suppunes extual .dfn files, Ihese files are plain text and. are not compatible with por versions of Delphi, at least not without conversion back to the binary format. The only way to tell whether a dfn file ie binary of text ia to ope te file and check the contents. An easy way to do this programmatically 1s to test the frst {tee bytes, which are always SFF SOA $00 sn a bunary .djin file, g A binary fm file w actually a 16 bit eo (Windows resuuiee) fe, Table 1-1 beefy describes the fles you are likely to tind in Delphi and what they: are used for. Files marked with “(IDE)" are not part of Delphi Pascal, hur ane used by the IDE, Table 1-1: Delp Files: Extension | Description pg) Proc group TD tet | Compiled package (Opec! hand uf DED ft | Options forthe command line compiler dep | Compiled package efomation, needed lnk with a package der | Component bmap resource (DE) dou | Cale yet code jm | Porn descnption ADE) dof | Project options fle (DED dpe} source te tor bulding a package dpe | Main source file fora program o rary dire | Resource snpt for resourcestring decantions Chapter 1 Delbbs Pascal Table 1-1. Delphs Files (continued) Extension sk Desktop layout UDB) ‘pas Unit source code Windows resource (every dpirhas an associated rms file) Separating Interface from Implementation ‘A unit has two pans: interface and implementation. The interface part declares the types, vanables, constants, and routines that are visible to other unite. The imple ‘mentation section provides the guts of the routines declared in the interface section. the implementation section can have additonal declarations that are private 10 the unit's implementation. Thus, units are Delphi's primary means of information hiding, (One unit can tse another unit, that is, import the declarations from that other unit A change to a unit interface requires a recompilation of all unite that woe the changed declaration in the modified unit. Delphi’s compiler manages this automat- scally, o you don’t need to use makeliles to compile Delphi project. ‘You can use a unit in the interface or implementation section, and the choice 1s important when building a project If unit A uses unit B sn its interface section, changes to unit B's interface are propagated as changes to unit A's interface. Delpht must recompile all the unite that use unit A. ‘+ Ifunit A uses unit B in its implementation section, only unit A must be recom- piled to use the new declarations in unit By Units cannot have circular references in thes interface sections. Sometimes, you will run into wo clase declarations that contain mutually dependent declarations. ‘The sumplest solution is to use a single unit, but if you have reasons to declare the classes in separate units, you can use an abstract base class in one or both units to climinate the circular dependency (See Chapter 2 for more information.) Inittalizing and Finalizing Every unit can have an sniualzation and a finalization section. Code an every initialization section runs before the program or library's main begin-end block. Code in the finalization section runs after the program terminates or when the brary is unluaded. Delphi runs the inialization sections using « deptifist traversal of the unit dependency tree, In other words, before a units snitiaization ‘code runs, Delpht runs the initialization section of every unit it uses, A unit 1s initialized only once, Example 1-1 demonstrates how Delphi initializes and final- Example 1-1. Showing the Order of Unis Initialtzation program Bamplel_t; ‘ses unitay (Steptype Console) mis 3 Example 1-1. Showing the Order of Unit intalization (continued) agin Weltetas("Reawpie LoL main program) end. interface inplenantation inieializatioas Weiteln ‘unica initialization’); tanalization Weitetan(unita finalization’): en. unit units; sntertave inplesentaticn anitialization Weitain("mniep initializati finalization lwrfretn( ‘inst finalisation’) ena. When you compile and run Example 1-1, be sure to nin it from a command [promps, not the IDE, of else the console will appear and disappear before you can see the output. which is shown ax Fxampte 1-2 Example 1 2- The Output from Running Example 1-1 We \nsshet Sema units initialisation sunita iniesalization Banple 1-1 main progran units finalization The System and Systnit Units ‘The System und Sysmnit units are automatically included in every unit, o all of the declarations in these units are effectively part of the Delphi Paseal language, and the compiler has special knowiedge about many of the functions and proce. dures in the Syotem and Oystnit units Chapter 5, Language Reference, 1s a complete reference to the system routines and declarations meant for your use Programs ‘A Delphi progiau looks sunllar to a traditional Pascal program, stating with the rogram keyword and using a beginend block for the main program Delphi programs are usually short, though, because the real work takes place in one or ‘more separate unite, In a GUL application, for example, die una program usually 7 Chapter 1~ Delphi Pascal calls an initialization procedure, ereates one or more forms (windows), and calls a procedure for the Windows event loop. or compatibility with standard Fascal, Delphi allows a parameter list after the program name, but—like most modern Pascal compilers—it notes the identifiers listed there, In a GUT application, you cannot use the standard Pascal /O procedures because there ie no input device to read from and no output device to write to. Instead, ‘you can compile a console application, which can read and wete using standard Pascal VO routines. (See Chapter 8, Compiler Directives, to leam about the ‘Shox/Type directive, which tells Delph to build a console or a GUI application.) |A program's uses declaration lists the units that make up the program. Each unit rname can be followed by an in directive that specifies a filename. The IDE and ‘compiler use the filename to locate the units that malee up the project. Unit ‘without an in directive are usually library units, and are not part of the projects source code. If 2 unit has an associated form, the IDE also stores the form name in ‘3 comment, Example 1-3 shows a typical program source fle Example 1-5: Typical Program Pile progean Typical) Fors, Main in ‘Vain.pas' ainForm), Movestusé in ‘MoreStuff.oae' (Forn2}. els in “Ueits.pas (gr +885) begin ‘Aophication Initialize; ‘oplication,CreateForm(MainForm, Mainform) ‘pplication. CreateForm(1Form2, Forn2); deplicaticn. amy end. The Forms unit part of the standard Delphi library, so it does not have an in. directive and source file, The other units have source filenames, so Delphis IDE manages thoce files ao part of the project. To learn about the $R compiler direc- tive, see Chapter 8, The Application object 1s part of Delphi's visual component library and is not covered in this book. Consult Delph’s online help tor informa: tion about the Application object and the rest of the VCI Librartes ‘A Delphi library compiles to a standard Windows DLL. A library source file looks the same ae a program source file, except that it uses the Libvary keyword instead of progran A Lbrary yprcally has an exports declaration, which lists the roulines that the DLL exports. Ihe exports declaration 1s optional, and if you intend to use @ unit in a library. is usually best to put the exports declaration in Libraries 3 the unit, close to the subroutine you are exporting. If you don't use the unit in a Iibrary, the exports declaration has no impact. ‘The min body of the brary—its begin-end block—executes each time the library is loaded into an application. Thus, you don't need to write a DLL proce dure to handle the DLL_PROCESS_ATTACH event, For process detach and thread ‘events, though, you must write hauler. Assign the handler to the DLIProe var- able. Delphi takes care of registering the procedure with Windows, and Windews calls the procedure when a process detaches or when a thread attaches or detaches. Feample 1-4 shows a simple DLL procedure. Esample If DIL Auach and Derach viewer we none rocedure Log const Mog: string); begin MessageBox(0, Phar (tog), ‘Attacher', tb toontnformation + Hb.OK); euvedure actachuetacnroc|Reagon: Integer) ; begin ase Reason of DiL_Process Detach: Log(‘nararh Procees!) DiLtread Attach: tog(‘Attach Thread’); Di_stread Detach: tog( ‘Detach Tawa") else og (nim resent"); ena; begin 11 This code runs each tine the DU, ie Loaded into a new process. Lagl'Retach Proceea') DiiPrec += GhteachDetachProc: Using Dynamic Memory ‘When using a DLL, you must be careful about dynamic memory. Any memory allocated by a DLL fs freed when the DLL 1s unloaded. Your application might fetain pointers to that memory, though, which can cause acess violations of ‘worse problems if you aren't careful. The simplest solution is to use the ShareMen unit as the fst unit in your application and it every Mbrary the application loads, ‘The ShareMe unit redirects all memory requests to a single DL (BorlndM Mtl, ‘which is loaded as long as the application is running, You can load and unload DLLs without worrying ahout dangling pointers Sharing Objects ‘Sharettem solves one kind of memory problem, but not another: class identity If lass A is used in the application and in a DIL, Delphi cannot tell that both © Chapter 1 Delph Pascal smodles nse the same class. Although hath modiles use the same class name, this doesn't mean the classes are identical, Delphi takes the safest course and assumes the classes are different, f you know better, you have no easy way 10 form Delph Sometimes, having separate class sdentites does not cause any problems, but if ‘your program ines to use an object reference across a DLL boundary, the is and fas operators will not work the way you expect them to, Recause the DLL thinks class A is different from the application's class A, the is operator always returns alse. ‘One way wo crcurvert das problemas uw pass obyecisweruss DLL boundaries, IF you have a graphic object, for example, don't pass a TBitmap object, but pass a ‘Windows handle (XBTTMRP) instead. Another solution 1s to use packages. Delphi 3c entities in packages to avoid thie problem. automatically manages the c Setting the Image Base When you create a library, be sure to set the Image Base option, Windows must load every module (DLL and application) at a unique image base address. Delphi's default is $00400000, but Windows uses that address for the application, so it ‘cannot load a DUL at the same address, When Windows must move @ DLL. to a different address. you mcur a performance penalty. because Windows must rewrite a relocation table to reflect the new addresses. You cannot guarantee that every DLL will Lave « uunque addiess because you Cannot cool the audesses Uther DLL authors use, but you can do better than the default. You should at least make sure your DLLs use a different umage base than any of the standard Delph pack- ages and Windows DLLs. Use Windows Quick View to check a fle’ image base, Packages Delphi can link a unit statically with a program or library, of it can link units dynamically To link dynamucally to one of more units, You must put those units sn a package, which is a special kind of DLL. When you write a program or library, you don't need to worry about how the units will be linked. IF you decide to use & package, the unit in the package are not linked into your .exe or ll, but snstead, Delphi compiles a reference to the package’s DLL (which has the extension bp! for Borland Package Library) Packages wvold dhe problems of DLLs, namely, mimagmy memory and class alent: ties. Delplu keeps track ofthe classes defined in each unit and makes sure that the application and all associated packages use the same class identity for the same clace, 20 the 49 and aa operators work correctly Design-Time Versus Runtime Delphi's IDE uses packages to load components, custom forms, and other design- time units, cuch as propery editors, When you write components, keep thet designstime code in a design-ime package, and put the actual component class ia 4 runtime package. Applications that use your component can link statically with the component’s dew file or link dynamically with the runtime package that Packages 7 Contains your component. By keeping the design-time envle in a separate package, you avoxd linking any extraneous code sto an application, Note that the designstime package requires the muntime package because you ‘cannot link one unit sto multiple packages. Think of an application ut library a5 4 collection of units, You cannot include a unit more than once ina single rogram—at doesnt matter whether the units ae linked statically or dynamically ‘Thus, if an application uses two packages, the same unit cannot be contained in both packages. That would be the equivalent of linking the unit rwice, Building a Package To build a package, you need to create 2 dl file, or package source file, The

You might also like