The Delphi FAQ
                 Maintainer: Graham Mainwaring <graham@mhn.org>
                           Last Updated: May 22, 1995



   Questions discussed in this FAQ:

   0. Introduction.
     0.1 What is the purpose of this FAQ?
     0.2 How can I get the latest version of this FAQ?
     0.3 Is this FAQ copyrighted?
   1. General Questions.
     1.1 What is Delphi?
     1.2 What versions of Delphi are there?
     1.3 How much disk space, memory, etc., do I need to run Delphi?
     1.4 How tough is it to learn Delphi?
     1.5 What's the difference between Delphi Desktop and Delphi
        Client/Server?
     1.6 Can you write multi-user database applications in Delphi Desktop?
     1.7 What is the history of Delphi?
     1.8 Where can I get a copy of Delphi?
     1.9 What if I don't have a CD-ROM drive?
     1.10 How can I contact Borland?
     1.11 What technical support do I get with Delphi?
     1.12 What known bugs exist in Delphi?
     1.13 I just bought Delphi.  Where are the language and library reference
        manuals?
   2. Delphi Resources.
     2.1 What are some good books about Delphi?
     2.2 Does anyone publish a Delphi magazine or journal?
     2.3 Where can I find sample source code and utilities for Delphi?
   3. Compatibility.
     3.1 What operating systems does Delphi support?
     3.2 What source management tools are compatible with Delphi?
     3.3 Can I use DLLs developed in C or C++ from Delphi?
     3.4 Can I make calls to Delphi code from C or C++?
     3.5 What third-party packages are specifically known to work (or not
        work) with Delphi?
   4. Database Questions.
     4.1 How do I get access to a database from Delphi?
     4.2 Does Delphi support the <mumble> back-end?
     4.3 What data-aware controls come with Delphi?
     4.4 Can I use the ODBC drivers that I got with <mumble>?
     4.5 What about data-aware VBXes?
     4.6 How do I write a "change password" function for a Paradox table?
     4.7 Why do I get errors when I call the Add method for a TFieldDefs?
     4.8 What is the procedure for connecting Delphi to an MS Access database?
     4.9 How can I manipulate data programmatically?
   5. Programming Questions.
     5.1 What target formats can I create using Delphi?
     5.2 I built a small test project. What are all these files?
     5.3 How can I yield the CPU to other tasks, like "DoEvents" in VB?
     5.4 Why do I get compile errors accessing the Sender object in events?
     5.5 Are there any tools to help me migrate my applications to Delphi?
     5.6 What's the Delphi equivalent of Visual Basic control arrays?
     5.7 How do I close a modal form? For that matter, what's the best way to
        close any form?
     5.8 Are there commercial applications developed in Delphi?
     5.9 Do I have to know a lot about the Windows API to use Delphi?
     5.10 Do I have to understand object oriented programming to use Delphi?
     5.11 How does Delphi's exception handling work?
     5.12 Does Delphi use Pascal or C style strings?
     5.13 How does Delphi handle Windows callbacks?
     5.14 How does Run-Time Type Information (RTTI) work?
     5.15 I'm creating a toolbar, but I have icons, not bitmaps. Help!
     5.16 When I use the Glyph property, how do I know which color is
        transparent?
     5.17 How can I make my Delphi application respond to Windows messages?
     5.18 How can I allocate blocks of memory larger than 64k?
     5.19 Is it possible to write a Windows screen saver in Delphi?
     5.20 I'm trying to call <mumble> from Delphi and it GPFs.  What's up?
     5.21 How can I add pages to a TTabbedNotebook at run-time?
     5.22 I'm painting complex graphics.  How can I speed up redrawing?
     5.23 How can I hade MDI child windows?
     5.24 How do I write a global error handler?
     5.25 Why do I get exception messages even though I'm in protected code?
     5.26 I've added code to my OnKeyPress event that traps Enter keys, but it
        keeps beeping at me and/or activating the default button. How do I
        make it stop?
     5.27 I want to modify a component's properties at run-time, but it isn't
        convenient to store a pointer to the component. Is there an easy way
        to get access to it?
   6. Questions about distributing Delphi applications.
     6.1 Is there anything in Delphi similar to the VB "setup wizard?"
     6.2 What files am I allowed to redistribute with my applications?
     6.3 If I want to send out a Delphi-compiled EXE file, what other files do
        I need to send with it?
     6.4 I want to distribute a database application, but I don't want to
        force all my users to create BDE aliases. What do I do?

   ------------------------------
   0. Introduction.

   0.1 What is the purpose of this FAQ?

   This FAQ is intended to answer some questions about the new development
   environment from Borland International called Delphi. Information in this
   document is not guaranteed to be correct. Use it at your own risk.

   This is not really a FAQ in the purist sense of the term, because some of
   the questions answered here are not really very frequently asked at all.

   0.2 How can I get the latest version of this FAQ?

   This FAQ is posted to comp.lang.pascal approximately monthly. If it's
   expired on your news server, you can get it via anonymous ftp to
   ftp.mhn.org as /pub/delphi.faq; or you can get it from WWW as
   <http://www.mhn.org/delphi.faq>.

   0.3 Is this FAQ copyrighted?

   Yes. A work is copyrighted by the act of publication. But you are hereby
   authorized to do whatever you want, however you want. I request that if you
   distribute all or part of this FAQ, you also distribute the 0 section.
   Also, this authorization applies to *this version* only. I reserve the
   right to apply whatever copyright restrictions I see fit to future
   versions.

   ------------------------------
   1. General Questions.

   1.1 What is Delphi?

   Delphi is a product of Borland International. It is a native code compiler
   that runs under Windows 3.1 and provides visual programming tools somewhat
   similar to those found in Microsoft Visual Basic 3.0. The underlying
   language is Object Pascal, which is an extension of the object-oriented
   Pascal found in Turbo/Borland Pascal starting with version 5.5.

   1.2 What versions of Delphi are there?

   Delphi has been available in beta-test for many months now, and Borland has
   also given away a large number of "prerelease" copies. As far as the
   official release is concerned, though, there are two packages: Delphi
   (sometimes referred to as Delphi Desktop) and Delphi Client/Server. Both
   are version 1.0.

   1.3 How much disk space, memory, etc., do I need to run Delphi?

   The minimum installation of Delphi takes about 30Mb, and the full install
   takes 80Mb. In order to run it well, you'll need a 486 with a minimum of
   8Mb of RAM, though I personally wouldn't try to run it in less than about
   12Mb. I use a 486DX2/66 at home and a Pentium-90 at work, and to be honest,
   there's not much difference between them--Delphi's compiles are so fast
   that the CPU is really not a bottleneck.

   1.4 How tough is it to learn Delphi?

   If you're lucky, you already have lots of experience with both Object
   Pascal (or, as it used to be called, Borland Pascal With Objects--
   essentially, Turbo Pascal v5.5 or later) and with Visual Basic. If you fit
   this description, then Delphi will be a breeze for you.

   Okay, now for everyone else. In order to make full use of the Delphi
   environment, you have to know Pascal, you have to have some grasp of object
   orientation, and you have to understand event-driven programming. Once
   you're over those three hurdles, you've pretty much got it. See section 5
   for more information.

   On the other hand, most people don't need to make "full" use of the
   environment. If you just want to pull a simple application together that
   doesn't do anything too fancy, Delphi shouldn't be any harder to learn than
   VB--it's just that there's a whole lot more you *can* do in Delphi, which
   will make you feel more lost than you really are.

   1.5 What's the difference between Delphi Desktop and Delphi Client/Server?

   Delphi Client/Server includes everything from Delphi Desktop, plus the
   following:

      - SQL-Links 2.5, which includes native client drivers for Oracle,
   Sybase, Informix, and InterBase, and includes full royalty-free
   redistribution rights to those drivers, and which costs $995 if bought
   separately;
      - The Local InterBase Deployment Kit, $495 (*);
      - ReportSmith/SQL, $300 (**);
      - "Team development support" -- interoperation with PVCS (obviously,
   this is no use to you if you don't own PVCS), not available separately;
      - The visual query builder, which creates SQL statements for you, also
   not available separately;
      - The VCL source code, which is available separately for $100.

   (*) Local InterBase is a single-user SQL database engine. The version
   included in Delphi Desktop is intended to be used by developers who want to
   write SQL applications that can be seamlessly migrated to client/server
   environments, but without buying their own (expensive) server platform.
   However, Delphi Desktop does not include redistribution rights. If you want
   to distribute a single-user application that uses Local InterBase, you have
   to pay extra for the deployment kit.

   (**) The version of ReportSmith bundled with Delphi Desktop specifically
   detects and excludes any server-based ODBC drivers from its list of
   acceptable connections. Yes, you heard that right. Even though you've got
   third-party ODBC drivers, and even though you can talk to these drivers
   just fine from the Delphi environment, ReportSmith still won't work. If you
   want to do this without buying Delphi Client/Server, you can buy
   ReportSmith/SQL separately for $300. As an alternative, if you happen to
   already own a copy of Visual Basic, you can use the Crystal Reports VBX
   just fine from within Delphi.

   1.6 Can you write multi-user database applications in Delphi Desktop?

   Using regular, non-client/server Delphi, I have developed an application
   that talks to a Sybase server using ODBC drivers. I didn't have to go to
   any serious trouble getting it to work, and data access speed is quite
   acceptable, better than it was under Visual Basic.

   Steven Lamotte <slamotte@jenex.mb.ca> says: "I think the benefits of the
   native SQL drivers relate mostly to speed. It may be true that ODBC allows
   you to do most everything a server permits, but your SQL commands still
   have to be processed by ODBC. I once wrote a program to compare Sybase SQL
   Server access with C++ using ODBC and using OpenClient (the native SQL
   interface for SQL Server) and the results were that the native interface
   version performed several times better than ODBC."

   1.7 What is the history of Delphi?

   Delphi is the descendant of Turbo Pascal, which was first released in 1983
   for the CP/M operating system. Turbo Pascal was ported to MS-DOS in early
   1984. During the early history of the IBM PC, Turbo Pascal was arguably the
   most popular language for serious development work--mostly because it was a
   real compiler, including the program editor and everything, that cost
   $19.95 and would run on a 128k machine. Borland introduced Turbo Pascal for
   Windows in 1990. The latest release of Borland Pascal (as it is now
   called), not including Delphi, was version 7.0 in late 1992.

   Delphi had an unusually long deveopment cycle--somewhere between 18 months
   and two years, depending on who you talk to. Various beta-test and
   prerelease copies have been circulated, including several hundred "early
   experience" copies which were given away at the trade show Software
   Development '95. Delphi was officially announced in the US on Feb. 14,
   1995, and the first release-level copies were shipped on Feb. 28.

   1.8 Where can I get a copy of Delphi?

   If you are in the US, You can order Delphi Desktop on CD-ROM for an
   introductory price of $199 by calling Borland's credit card order desk at
   1-800-331-0877. If you are a registered user of any version of Turbo Pascal
   or Borland Pascal, you qualify for an upgrade price of $149, and you can
   also buy the Visual Component Library Source Code for $49. The introductory
   pricing is good through approximately May 15, 1995; after that, the price
   will be raised to $495. Delphi Client/Server is $1999.

   Of course, if you buy through a reseller, you will probably pay less.
   According to Borland, "Delphi is available through the following US
   resellers: CompUSA, Best Buy, Elek-Tek, Computer City, Babbages, Software
   Etc., Fry's, Electronics Boutique, Corporate Software, ASAP Software
   Express, Egghead Software, Softmart, Software Spectrum, CDW, PC Connection,
   Programmer's Paradise, Programmer's Warehouse, ProVantage Shop, and Micro
   Warehouse."

   Note that you do NOT have to go through Borland directly to get the upgrade
   price. When you buy a copy of Delphi at the discounted retail price (US
   street prices are $179-$189), the box contains a coupon for the $50
   discount if you mail in a serial number for Turbo or Borland Pascal. You
   have to send in a photocopy of your install disk, or the original first
   page of your manual.

   Borland also maintains list prices in several other currencies through
   their various international offices. In addition, distributors sell Borland
   products across the globe. I do not currently have any verified information
   about non-U.S. pricing for Delphi; check with the closest Borland office or
   with your distributor or reseller.

     9 What if I don't have a CD-ROM drive?

   Borland will ship Delphi on 3.5" floppy diskettes, but they charge extra
   for them. The resellers I have spoken to only carry the CD-ROM version
   because they don't want to have to stock two different items. I got my copy
   on CD, but the CD has directories on it called DISK1 through DISK15, so I
   assume it would be 15 diskettes if you got it that way. If you don't get
   the CD, you won't get the stuff they use to fill up space on the CD, like
   an AVI file of an animated spinning Delphi logo.

   1.10 How can I contact Borland?

   If you have the necessary access, you can get information directly from
   Borland at their web site, <http://www.borland.com>, or at their anonymous
   ftp site, ftp.borland.com. If this doesn't work for you, here is a list of
   their (voice) telephone numbers:

   Australia                                       (61) 2 911 1000
   Belgium/Luxembourg                              (32) 2 4610 448
   Brazil                                          (55) 11 851 5326
   Canada                                          (416) 229 6000
   Chile                                           (56) 2 233 7113
   Denmark, Norway                                 (45) 22 62 89 00
   Eastern Europe, Mediterranean, Russia, Middle   (33) 1 41 23 11 00
   East
   France                                          (33) 1 41 23 11 00
   Germany, Austria, Switzerland                   (49) 61 03 9790
   Asian Headquarters/Hong Kong                    (852) 540 4380
   Italy                                           (39) 2 26 91 51
   Japan                                           (81) 3 5350 9370
   Korea                                           (82) 2 551 2795
   Latin America Headquarters                      (408) 431 1074
   Malaysia                                        (60) 3 230 2618
   Netherlands                                     (31) 020 540 5400
   Singapore                                       (65) 339 8122
   Spain                                           (34) 1 650 7250
   Sweden, Finland                                 (46) 8 799 20 00
   Taiwan                                          (886) 2 718 66 27
   United Kingdom                                  (44) 734 320 022
   USA                                             (408) 431 1000

     11 What technical support do I get with Delphi?

   You get access to the "up and running" line, which will only answer
   questions related to installing Delphi and getting it to run on your
   machine. Also, it is worth noting that the hold times on this line are very
   long indeed--don't expect to talk to anyone without waiting 20 to 30
   minutes.

   In order to get what borland calls "consultative" tech support (I.E.
   someone with whom you can discuss reasons why a program is not working),
   you have to pay $2/minute. You can call (900) 555-1015 and have the charges
   put on your phone bill, or else (800) 330-3372 and use a credit card. I
   have called twice, and they couldn't answer my question either time;
   however, they didn't charge me for the calls.

   1.12 What known bugs exist in Delphi?

   A complete listing is beyond the scope of this FAQ; however, if you have
   WWW access, you can look at:
   <http://www.cybernetics.net/users/bstowers/delphi-bugs.html>.

   1.   I just bought Delphi.  Where are the language and library reference
   manuals?

   They don't ship those manuals with Delphi because of their size.  The
   component library reference is over 1000 pages.  You can get all this
   information from the on-line help, or you can ftp the manuals from Borland
   in Acrobat format, or you can order the actual books for an additional
   charge.

   ------------------------------
   2. Delphi Resources.

   2.1 What are some good books about Delphi?

   Delphi for Dummies, by Neil Rubenking, is the only one that has been widely
   circulated to general bookstores, and as usual with a For Dummies books,
   contains quite a bit of good information among the silly chapter headings
   and excitable prose. Other books that are either in print or on their way
   to print are:

   The Delphi Programmer Explorer, Duntemann/Mischel/Taylor
   Teach Yourself Delphi, Devra Hall
   Delphi by Example, Blake Watson
   Using Delphi, Special Edition, Namir Shammas
   Delphi Developer's Guide, XavierPacheco/Steve Teixeira
   Mastering Delphi, Charlie Calvert
   Teach Yourself Delphi in 21-Days, Andrew Wozniewicz
   Delphi How-To, Gary Frerking
   Developing Windows Applications Using Delphi, Paul Penrod
   Instant Delphi, Dave Jewell
   Delphi Nuts and Bolts, Gary Cornell and Troy Strain
   Software Engineering with Delphi, Edward C. Webber, J. Neal Ford,
   Special Edition Using Delphi, John Matcho, Mark Andrew, et al
   Developing Client/Server Applications with Delphi, Killen/Todd
   Delphi Programming Unleashed, Charlie Calvert
   Mastering Delphi, Tom Swan
   Mastering Delphi, Marco Cantu

   2.2 Does anyone publish a Delphi magazine or journal?

   The following magazines are listed on the Borland WWW server:

   Delphi Developer, 12 issues/$99, Pinnacle Publishing (206) 251-1900
   Delphi Informant, 12 issues/$49, Delphi Informant (916) 686-6610
   Inside Delphi, 12 issues/$79, Cobb Group (502) 493-3200
   The Delphi Magazine, 6 issues/???, The Delphi Magazine +44 0 181 460 0650

   2.3 Where can I find sample source code and utilities for Delphi?

   Borland seems to use CompuServe as their primary on-line service.  There
   are quite a lot of Delphi files in Borland's forum there.  Borland also
   maintains ftp and www sites, but they don't include nearly as many files as
   the CompuServe forum.  Various other web sites have sprung up with Delphi
   files here and there; try <http://vislab-www.nps.navy.mil/~jnhodges/> or
   <http://www.cybernetics.net/users/bstowers>.

   ------------------------------
   3. Compatibility.

   3.1 What operating systems does Delphi support?

   The only version of Delphi that has been released is for Windows 3.1. There
   is no reason why it should not run correctly under systems that provide
   Windows 3.1 emulation, like OS/2 Warp, Windows NT, etc. Borland has
   announced plans for a 32-bit version to coincide with Windows 95. It is
   rumored that this might be a free upgrade to users of Delphi 1.0, but I
   wouldn't count on it. It is also known that Delphi 1.0 does not run
   correctly on the prerelease version of Windows 95.

   Applications built in Delphi are Windows 3.1, 16-bit applications. However,
   Borland has stated that existing Delphi applications will compile
   unmodified in 32-bit Delphi.

   Francis Whiteley <whiteley@croughton.win-uk.net> points out that the
   readme.txt file for Delphi says: "Delphi has been tested under Windows 3.1,
   Windows for Workgroups 3.11, Windows NT 3.5, OS/2 Warp, and the latest pre-
   release version of Windows 95. Note that we do not recommend large-scale
   deployment of database applications running under Windows 95 until
   Microsoft certifies a release for commercial use."

   3.2 What source management tools are compatible with Delphi?

   Delphi Client/Server is said to include built-in connectivity to PVCS. In
   addition, it should be possible to connect to most non-language-specific
   source control systems. However, Delphi forms are stored in non-text
   format, so a source control package must support binary data if it is to
   work with Delphi.

   If your have a source manager that simply cannot deal with binary files,
   Rick Thompson <rat@ab00.larc.nasa.gov> points out: "According to the docs
   (User Guide, pp. 94-95) you can save forms as ASCII text for editing or
   version control purposes.  ASCII forms can also be loaded and resaved in
   binary *.DFM format."

   According to Chuck Lownie <chuck@mks.com>, "MKS Source Integrity (MKS SI is
   2nd in PC/PCLAN source management market next to PVCS with over 35,000
   developers using SI) also offers integration into Delphi.  Our integration
   into Delphi is currently being shipped along with MKS Source Integrity,
   however, in a future maintenance release of Delphi, our integration will
   also be shipped in the Delphi box, similar to PVCS."

   3.3 Can I use DLLs developed in C or C++ from Delphi?

   Delphi is capable of making calls to and receiving callbacks from any
   standard Windows DLL. In addition, it is said to be possible (though rather
   tricky) to get Delphi to access classes within C++ DLLs. Borland's WWW
   server has instructions on how to do this. I wasn't able to get it to work,
   but I think that's because I have weird DLLs.

   3.4 Can I make calls to Delphi code from C or C++?

   Delphi can generate DLLs, which can be called from C, C++, Visual Basic,
   Powerbuilder, or anything else that understands standard Windows DLLs.
   There is an example of a database-capable DLL in the DEMOS\DB\DLL
   directory.

   As is the case in all Windows programming languages that I know of, DLLs
   are difficult to debug and will crash your system if they aren't quite
   right. Save your source code frequently.

   3.5 What third-party packages are specifically known to work (or not work)
   with Delphi?

   Package/Manufacturer/Tested By/Comments
   Orpheus/TurboPower Software/graham@mhn.org/Orpheus is a package of native
        VBX controls (I.E. true Delphi objects, not VBXes), including full
        source code. It's in beta test, and expected to be in full production
        by May. It has a text editor that works with up to 16Mb files, a
        virtual list box, smart data entry fields, a timer pool that allows
        multiple timers without consuming as any Windows resources, spinners,
        better tabbed notebooks, and various other things.
   Crystal Reports VBX/Crystal Services/graham@mhn.org/The version of Crystal
        Reports that is included with Visual Basic works fine. I haven't tried
        other versions. The default class name, TReport, conflicts with the
        ReportSmith class built into Delphi, so I renamed it to
        TCrystalReport.
   Spread-VBX 2.0/FarPoint Systems/graham@mhn.org/When I tried to load Spread-
        VBX, Delphi immediately crashed, and shortly thereafter my entire
        system locked up. I guess that means it isn't compatible...
   Visual Basic's Grid/Microsoft/graham@mhn.org/This loads and runs fine,
        although once again Tgrid conflicts with stuff built into Delphi, so I
        renamed it to TVBGrid. I only installed this to see if it would work;
        Delphi's built-in grids are better.
   VBTools 3D Calendar/MicroHelp/graham@mhn.org/Works fine, except that it
        isn't data-aware once you load it into Delphi.
   VBTools Card Deck/MicroHelp/graham@mhn.org/Works fine
   VBTools Dice/MicroHelp/graham@.mhn.org/Works fine
   Data Widgets/Sheridan Software/graham@mhn.org/Can be made to work, sort of;
        but no data connectivity, so what's the point?

   Hey, you! I know you've used some VBXes (or whatever) with Delphi. Please
   e-mail graham@mhn.org with your findings so that this list can become more
   complete.

   4. Database Questions.

   4.1 How do I get access to a database from Delphi?

   In general, you have to go to "BDE Config" and define an alias for the
   database you want to connect to. This allows you to avoid hard-coding a
   directory path into your application; you just refer to the alias. Then,
   you create a minimum of three objects on the desktop: A Query or Table
   object that actually talks to the alias and gets some data; a Data Source
   object that links between the data and the controls, and at least one data-
   aware control.

   If you've been trying for hours to get this to work, and no matter what you
   do you just don't see anything happening, try setting the "active" property
   on the Table or Query to "True." This will open the database. I have seen
   many people get caught out by this the first time they try it.

   4.2 Does Delphi support the <mumble> back-end?

   Delphi Desktop does not directly support any back-ends except for Local
   InterBase, and of course the BDE (Borland Database Engine) itself. Delphi
   Client/Server directly supports Oracle, Sybase, Informix, and InterBase. In
   both cases, you can use third-party ODBC drivers to connect to any system
   you want.

   4.3 What data-aware controls come with Delphi?

   Steve Teixeira <steixeir@borland.com> says:

        Both versions contain the same data-aware components:

        TDBGrid (a data grid)
        TDBEdit (an edit control)
        TDBNavigator (a navigator with buttons to move around in a table)
        TDBLabel (a label control)
        TDBMemo (a multiline edit control useful for text blobs)
        TDBImage (a component that displays graphic fields)
        TDBRadioButton and TDBCheckBox (self-explanatory)
        TDBListBox, TDBComboBox, TDBLookupListBox, TDBLookupComboBox

   4.4 Can I use the ODBC drivers that I got with <mumble>?

   Yes, generally. I have not encountered any ODBC drivers that don't work
   with Delphi, but on the other hand, I haven't tried any really exotic ones.

   4.5 What about data-aware VBXes?

   Delphi only supports Level 1 VBX controls. This means that data-aware VBX
   controls *do not work* with Delphi. In general, anything that works with
   Microsoft Visual C++ should be okay in Delphi. Also, some data-aware VBX
   controls are sufficiently well-written that Delphi can make use of them and
   simply not access the data properties. See the compatibility list in
   section 3.5.

   4.6 How do I write a "change password" function for a Paradox table?

   There is no way to do this within the Delphi VCL. Seems like a pretty
   serious omission to me. However, it is possible to do it by talking
   directly to the Borland Database Engine through the interface provided by
   the DBIPROCS and DBITYPES units. You call DbiDoRestructure, but set all the
   "number of" variables to zero, which makes it leave the existing values
   intact. I have code to do this, but it's a bit too long to included here.
   E-mail <graham@mhn.org> if you want it.

   4.7 Why do I get errors when I call the Add method for a TFieldDefs?

   Because the documentation is wrong. There is an additional boolean flag
   that defines whether the field is required or not. The correct declaration
   for TFieldDefs.Add is as follows:

   procedure Add(const Name: string; DataType: TFieldType; Size: Word;
   Required: Boolean);

   4.8 What is the procedure for connecting Delphi to an MS Access database?

   David Zaret <zaretd@il.us.swissbank.com> posted:

        Here is the step-by-step process that I took to connect my Delphi app.
        to an Access database:

          Open up the Windows Control Panel.
          Open up the ODBC "Data Sources" icon.
          ADD a new Data Source of Type ACCESS DATA.
          Provide a unique "Data Source Name" (it doesn't really matter what
          you call it - description is optional).
          Choose the Database File by clicking the "Select Database" button.
          Close the "Data Source" window.
          Open up the "Database Engine Configuration" to get to the "BDE
          Configuration Utility" screen.
          Click on the "NEW ODBC Driver" button.
          Provide a "SQL Link Driver" - once again, it doesn't really matter
          what you call it.
           Select a Default ADBC Driver of type ACCESS DATA.
           Under "Default Data Source Name" choose the name of the ADBC driver
          that you provided from the Control Panel.
           Create a new alias by clicking on the "Alis" page tab.
           Click on the "New Alias" button.
           Give the alias a name.
           Select an Alias Type of ODBC_[WHATEVER YOU CALLED IT IN STEP 11].
           Save your settings with File/Save.
           You can now close the BDE Config. Utility.
           IN YOUR PROJECT --- (I am sure that there are many ways to approach
          the next steps, but here's what I did)
             a)   Add a Tdatabase component
                  1)   Set the AliasName to the new alias that you just
                       defined.
                  2)   Provide a dummy DatabaseName.
                  3)   Set the LoginPrompt to FALSE (if you don't want
                       permission checking).
             b)   Add a TQuery component.
                  1)   Set the DatabaseName to the dummy name you provided in
                       a.2)
             c)   Add a TDataSource component.
                  1)   Set the DataSet to the name of the TQuery comp.

        And you are done!  You now have a SQL-ready, data-aware fomr that y ou
        can plop SQL into and data-aware components on to!

   4.9 How can I manipulate data programmatically?

   It is sometimes desirable to write code that deals with databases but is
   not associated with any particular form or user-interface details.  To do
   this, you declare variables of type TDatabase, TTable and/or TQuery, and
   set their properties in code just as you would in the design environment.
   Make sure that you include the DB and DBTables units in your uses
   statement, or you will get "unknown identifier" errors during compilation.

   ------------------------------
   5. Programming Questions.

   5.1 What target formats can I create using Delphi?

   Delphi can create Windows 3.1 EXE files and DLL files. I am told that you
   can also create VBXes, but I have yet to figure out how you would go about
   it. Delphi does NOT create DOS EXE files.

   5.2 I built a small test project. What are all these files?

   Here is a list of the file extensions created by Delphi and what they all
   mean:

   DPR - Delphi Project File. This is actually a Pascal source file; it just
        happens to be the main program for the application.
   ~DP - A backup file of the DPR file before the last save operation.
   PAS - In Delphi, PAS files are always the source code to either a unit or a
        form. The main program of an application is in the DPR file.
   ~PA - A backup of a .PAS file.
   DFM - These files are always paired with PAS files. The DFM file is the
        binary data used to set up initial data for components (IE, the
        properties you set in design mode rather than in code). You can't edit
        a DFM file with a text editor, but if you open it in Delphi, you will
        see a textual version of the contents.
   ~DF - A backup of a .DFM file.
   DCU - A compiled unit, similar in concept to an OBJ file.
   OPT - Project Options; i.e. compiler and linker settings, which form is the
        main form, what icon to use for the application, etc. Generally, the
        stuff you edit under Options/Project.
   RES - A Windows resource file; generated automatically by Delphi and
        required by the compilation process. You don't need to worry about
        this file, but don't delete it either.
   EXE - All of the above linked together into runnable format.

   5.3 How can I yield the CPU to other tasks, like "DoEvents" in VB?

   The Delphi equivalent is Application.ProcessMessages. There is also an API
   function called Yield that seems to do the same thing, but it isn't safe to
   use from most Delphi applications.

   Steve Teixeira <steixeir@borland.com> explains:

        You should not use Yield() unless your application is *guaranteed* not
        to receive any messages (ie, your application contains no windows).

        Instead, the way to do this in Delphi is to call
        Application.ProcessMessages. ProcessMessage encapsulates a
        PeekMessage() loop, which is the correct "API-way" to do this.

   5.4 Why do I get compile errors accessing the Sender object in events?

   If you look at the declaration, the Sender object is of type TObject, which
   is the class from which (almost) all other objects are derived. You're
   probably trying to access a property that isn't defined in TObject, like
   Text or Caption or something. For this reason, "Sender.Text" will fail, but
   if (for example) you know that the sender is of type TEdit, then you could
   use "(Sender As TEdit).Text". If you aren't certain that the Sender object
   will always be the same type, you can check it with "if (Sender is TEdit)
   then <blah>;". See section 5.14.

   5.5 Are there any tools to help me migrate my applications to Delphi?

   There is an automated translator that converts Visual Basic projects to
   Delphi. I have heard from a couple people who have tried using it, and the
   results seem to be pretty mixed. It's very useful for some people, but not
   useful at all for others. It is made by:

      EarthTrek
      7 Mountain Rd.
      Burlington, MA  01803
      (617) 273-0308

   5.6 What's the Delphi equivalent of Visual Basic control arrays?

   There isn't one. Delphi components do not have an Index property like VB
   controls, so you can't declare an array of them. However, there are three
   main reasons why you might want to, and each of them can be done in Delphi.
   Here's how:

   Reason 1. You want to share event handlers between different controls on a
   form.

   This is really easy. All you have to do is select the same event handler
   procedure in each of the controls' events. This is better than control
   arrays because you can even have the same event handler function across
   different kinds of control; for example, a toolbar button and a menu item
   can call the same function directly in each of their Click events.

   Reason 2. You want to be able to dynamically allocate and deallocate
   controls at run-time.

   This is also pretty easy in Delphi. Suppose you have a button on a form,
   and each time it is clicked, you want to create another, different button.
   The following sample code shows how to do this:

   procedure TForm1.Button1Click(Sender: TObject);

   var
     NewButton: TButton;

   begin
     NewButton := TButton.Create(Self);
     NewButton.Parent := Self;
   end;

   It is important to note that once this event finishes, the NewButton
   variable goes out of scope and we no longer have a pointer to the newly-
   created control. You can't deallocate a control within its own event
   handlers, so if at some point you want to remove one or more dynamically-
   created controls, you have to search for them in the Form.Controls array
   and/or maintain your own list of pointers to the controls you create.
   Assuming that there are no control event handlers running, it is safe to
   deallocate a control by just calling its Free method.

   Reason 3. You really want to access controls by number.

   I ran across this when I decided to write a board game similar to Reversi
   as a Delphi learning project. I had 100 TShape controls on a form, in a
   10x10 grid. So, I painted all the shapes in the form designer and allowed
   it to give them names like "ShapeNN", but then I also declared an array of
   pointers to controls: "Board: array[1..10, 1..10] of ^TShape;" and
   populated it in the form's Create event. This is a hundred lines of code
   that really shouldn't be necessary, but from then on I could access
   controls in a two-dimensional array, like this: "Board[3,5]^.Brush.Color :=
   clRed;" -- which is more than I could have done with VB.

   5.7 How do I close a modal form? For that matter, what's the best way to
   close any form?

   Generally speaking, you call the form's Close method. This runs the OnClose
   event, which may decide it doesn't want to close, for example if there is
   unsaved data in the form. Close doesn't free the memory associated with the
   form, unless of course you put a call to Release in the form's OnClose
   event.

   If you want to close a form without giving it a chance to argue, call the
   form's Release method. This is similar to Free, but it allows event
   handlers (e.g. OnDestroy) to finish running before the memory goes away.

   Modal forms "end their modal state" when you set the form's ModalResult
   property to anything greater than zero. If you put a button on a modal form
   and set the button's ModalResult property to some value, then when the user
   clicks on that button the form will close with the result you specified.
   You can find out what the result was by calling ShowModal as a function;
   i.e. result := Form.ShowModal.

   5.8 Are there commercial applications developed in Delphi?

   Not as far as I know. Delphi hasn't been released that long--give it time.
   If you can write a commercial application in VB, then you can definitely
   write one in Delphi. Of course, Delphi itself is written in a combination
   of Delphi and assembler (or so it is said), and it's certainly a commercial
   product.

   5.9 Do I have to know a lot about the Windows API to use Delphi?

   There seems to be a feeling that you need to know more about Windows to use
   Delphi than you do to use Visual Basic. This isn't really true; you can get
   by in both environments with a very minimal understanding of Windows
   internals. However, in both environments, you have to know at least a
   little about the Windows API in order to really make the most of what you
   have. The difference is that Delphi gives you a lot more power to do all
   these interesting things, so you feel more limited if you don't know how.

   5.10 Do I have to understand object oriented programming to use Delphi?

   Well, yes, to a point. Delphi's user interface design tools produce object-
   oriented code. However, if you're familiar with either Visual Basic or
   Powerbuilder, you probably have enough understanding of OOP to get by. You
   can do a great deal in Delphi without having to create your own objects,
   which is the point at which it becomes important to really understand
   something about them.

   5.11 How does Delphi's exception handling work?

   The basic structure goes something like this:

      p := new(big_thing);
      try
        blah(p);
        foo(p);
      finally
        dispose(p);
      end;

   The first line allocates a big block of memory. Then, in the "try" block,
   we execute several statements, each of which might produce an error--or, in
   other words, "raise an event."  If an error does occur, the rest of the
   "try" block will be skipped, "finally" blocks will be executed. If there
   are no errors, then the "finally" block will be entered when the last
   statement in the "try" block completes. So, either way, the big block of
   memory gets freed. These "try/finally" blocks will trap anything up to and
   including a Windows GPF.

   In addition, you can construct "except" blocks which can provide local
   error handling either for all errors or for particular types of error; and
   you can also create your own global error handler to trap exceptions that
   aren't otherwise handled by try blocks. See Chapter 7 in the Delphi User's
   Guide for more details.

   5.12 Does Delphi use Pascal or C style strings?

   Both. Delphi has two different sets of string manipulation functions, one
   for null-terminated strings, and one for Pascal-type (I.E. length byte)
   strings. You will find yourself stumbling across this distinction from time
   to time. Mostly, there are Delphi functions that wrap around the most
   common Windows API functions; for example, MessageBox, which is a Windows
   API call, requires a PChar; but Delphi also has MessageDlg, which accepts
   Pascal-type strings.

   If you have text in a Pascal string and you want to pass it to a function
   that expects a PChar, the following code is a "quick and dirty" way of
   doing it, assuming that s is of type string and that the string has room
   for one more character:

        s[length(s)+1] := #0;     { Appends a null to the end of the string }
        C_Style_Function(@s[1]);  { @s[1] is a PChar to the beginning of s }

   5.13 How does Delphi handle Windows callbacks?

   Just like C: You can get a far pointer to your callback procedure (you have
   to remember to declare it with the "far" qualifier, unless you have {F$+}
   in effect to force all calls to be far), pass the pointer to the Windows
   callback function, and there it is.

   5.14 How does Run-Time Type Information (RTTI) work?

   There are two new operators: "as" and "is."  The "as" operator is a
   protected typecast. You can use it to force the compiler to treat an object
   of one type as another type, but if at run-time the typecast is not
   properly compatible, then you will get an error. For example, if you have a
   class called TSport, with descendants TBasketball and TFootball, you might
   want a variable of type TSport--but you might also happen to know at a
   certain point in the program that this variable actually contains an
   instance of a TFootball. So, you can refer to it as (MySport as TFootball)
   in order to get access to its football-specific properties. However, if you
   are wrong and somehow a TBasketball gets passed in, instead of just looking
   at the data in some oddball way like a regular typecast, this will generate
   an error.

   The "is" operator is used to compare an instance of an object to a class of
   objects, to see if a typecast using "as" will work. If you have a variable
   MySport of type TSport, and it currently contains an instance of a
   TBasketball, then the following statements are true:

      (MySport is TSport)
      (MySport is TBasketball)
      not (MySport is TFootball)

   The combination of these two operators might lead to code such as the
   following:

      function player_goodness(var MySport: TSport): integer;

      begin
        if (MySport is TBasketball) then
          player_goodness := (MySport as TBasketball).rebound_shots
        else if (MySport is TFootball) then
          player_goodness := (MySport as TFootball).total_yardage;
      end;

   It has been pointed out that this would be better implemented as a method
   which TSport defines and TBasketball and TFootball override, but then it
   wouldn't illustrate how RTTI works, would it? :-)

   5.15 I'm creating a toolbar, but I have icons, not bitmaps. Help!

   Your best bet is to own something like HiJaak which can do the conversion
   directly. However, assuming that you have nothing but Windows and Delphi,
   the following procedure can be used to convert an icon to a bitmap:

     Display the icon somehow. Doesn't matter how you do it.
     Press Alt-PrintScreen to copy the current window to the clipboard.
     Load Paintbrush and do an Edit/Paste.
     Highlight the icon using the square selection tool and do an Edit/Copy.
     Go to Options/Image Attributes and set the working area to 32x32 pixels.
     Do an Edit/Paste again.
     Save the result as a BMP file.

   5.16 When I use the Glyph property, how do I know which color is
   transparent?

   Delphi always assumes that the color of the bottom left-hand corner pixel
   is the background color and should be displayed as transparent. Yes, it
   took me a while to figure this out. It's not documented anywhere, but if
   you have the VCL source, you can look at the code in BUTTONS.PAS.

   5.17 How can I make my Delphi application respond to Windows messages?

   Using WM_WININICHANGED as an example, Chuck Jazdzewski
<cjaz@borland.com>
   says:

        Declaring a method in a TForm will allow you to handle
        WM_WININICHANGED messages:

            procedure WMWinIniChange(var Message: TMessage);
              message WM_WININICHANGE;

        The body of the implementation could look like:

        procedure TForm1.WMWinIniChange(var Message: TMessage);
        begin
          inherited;

          {.. react to someone mucking with control panel ..}
        end;

        The call to "inherited" is important.  Note also that message
        handlers are special when calling their inherited since you
        don't refer to the name of the inherited.  This is because
        the inherited is referring to the inherited message handler for
        this message number, which might not have a visible name or
        or even the same name as you have given it, or in some cases,
        might not even exist (in which case you are really calling
        DefaultHandler).

   5.18 How can I allocate blocks of memory larger than 64k?

   Reinier Sterkenburg <sterkenb@pml.tno.nl> says:
        The answer is: use GlobalAlloc and GlobalLock from the WinProcs unit.
        New question is then: why can't we use GlobalAllocPtr anymore?
        Answer: I don't know.

   5.19 Is it possible to write a Windows screen saver in Delphi?

   Thomas W Wolf <twwolf@cacd.rockwell.com> says:

        Someone posted a message requesting information on how to use Delphi
        for a screen saver.

        a) In the project file (*.dpr) add '{$D SCRNSAVE <saver name>} after
        the uses clause.

        b) On the main form, turn off the border and icon controls. In the
        activate method set the form left and top to 0, and set the
        Windowstate to wsMaximize.

        c) In the form create method, set the application.OnMessage to a
        method that controls the deactivation of the screen saver. Set the
        application.OnIdle method to whatever display method for the saver.

        d) In the form create method the command line should be tested for /c
        and /s. These are the command line parameters windows uses to define
        whether the screensaver should run or configure. (/c is for
        configuration)

        e) Compile the program, and rename the .exe to .scr. Move it to the
        windows directory, and it should show up in the control panel.

   5.20 I'm trying to call <mumble> from Delphi and it GPFs.  What's up?

   Based on the number of postings to comp.lang.pascal, it would seem that by
   far the largest number of problems calling Windows API functions or non-
   Delphi DLLs are caused by passing Pascal-style strings to functions that
   expect null-terminated (PChar) strings.  This is the first thing you should
   check if you get a GPF or other strange results when calling an external
   function.  See section 5.12 for more information on which type of strings
   go where.

   5.21 How can I add pages to a TTabbedNotebook at run-time?

   The following source code, which assumes that you have a tabbed notebook
   called TabbedNotebook1, will add a new page that contains an "OK" button:

   procedure whatever_whenever;

   var
        NewPage: TTabPage;
        NewPageNumber: word;
        NewButton: TButton;

   begin

        {Create the new TTabPage object}
        NewPage := TTabPage.Create(Application);

        {The page must be a child of the notebook}
        TabbedNotebook1.InsertControl(NewPage);

        {Add text to the notebook's Pages property; this will cause the new
        page to be added as the last tab on the notebook}
        NewPageNumber := TabbedNotebook1.Pages.Add(`New Page');
        TabbedNotebook1.PagesObjects[NewPageNumber] := NewPage;

        {The page needs controls on it; here's how to add one}
        NewButton := TButton.Create(Self);
        (TabbedNotebook1.Pages.Objects[NewPageNumber] as TWinControl)
           .InsertControl(NewButton);
        NewButton.Top := 10;
        NewButton.Height := 30;
        NewButton.Width := 100;
        NewButton.Caption := `OK';

   end;

   5.22 I'm painting complex graphics.  How can I speed up redrawing?

   Steve Teixeira <steixeir@borland.com> says:

        Use a TBitmap component as a memory DC.  You can then copy from
        Bitmap.Canvas to your form's Canvas.

   5.23 How can I hade MDI child windows?

   Steve Teixeira <steixeir@borland.com> says:

        You can't hide MDI children.  Windows does weird things when you try
        to hide MDI children, so VCL doesn't permit it.

   5.24 How do I write a global error handler?

   Use the Application.OnException event.  Look in the help under "application
   events" for details of how to create and attach an event handler to the
   application variable.

   5.25 Why do I get exception messages even though I'm in protected code?

   By default, the internal debugger will halt any time there is an exception,
   even if the exception is trapped by code.  This can often be useful for
   debugging purposes.  If it offends you, turn it off.  You control it from
   the Options/Environment menu.

   5.26 I've added code to my OnKeyPress event that traps Enter keys, but it
   keeps beeping at me and/or activating the default button. How do I make it
   stop?

   The problem is that even though you're running your own handler code, you
   are also allowing the Enter key to pass through and activate the default
   behavior for an Enter key. In order to prevent this, set key := 0, which
   will send a null keystroke through to the default handler.

   5.27 I want to modify a component's properties at run-time, but it isn't
   convenient to store a pointer to the component. Is there an easy way to get
   access to it?

   Use the library function FindComponent to search by name. If you need to
   search by properties other than name, iterate through the form's Components
   array.

   ------------------------------
   6. Questions about distributing Delphi applications.

   6.1 Is there anything in Delphi similar to the VB "setup wizard?"

   No. There are some third-party tools available, but out of the box Delphi
   does not have anything to automate the creation of setup disks. You can of
   course write your setup program in Delphi, but you have to write it
   yourself. If you do decide to use a third-party installation tool, check
   out Chief's Installer Pro. You can get it via anonymous ftp to
   ftp.demon.co.uk as /pub/ibmpc/windows/chief/pro/cinstp17.zip.

   6.2 What files am I allowed to redistribute with my applications?

   If you have Delphi Desktop, you are allowed to redistribute run-time
   versions of the Borland Database Engine and of ReportSmith. Of course, you
   can also distribute the EXE or DLL files you create yourself. Borland has
   some rather odd and overly restrictive licensing terms; for example, your
   programs are required to bear a valid copyright notice (if not yours, then
   Borland's)--which seems to mean that you can't create public domain
   applications using Delphi. Also, if you distribute the Borland Database
   Engine, you are required to send out the whole thing with all relevant
   drivers. This is because other, previously-installed applications may also
   use BDE functions, and if you take away their drivers, well, that's a bad
   thing.

   6.3 If I want to send out a Delphi-compiled EXE file, what other files do I
   need to send with it?

   None. Everything is compiled into the .EXE file. Of course, if you've
   developed other files (like a HLP file, data files, etc.), or if you're
   using VBX files, then you have to send them as well. If you use VBX files,
   you must also include BIVBX11.DLL.

   If the application uses database functions, you also have to include the
   Borland Database Engine. You can just distribute the two pre-packaged disks
   on the Delphi CD (they don't get installed to your hard drive). And if the
   application uses ReportSmith, you have to distribute the ReportSmith run-
   time. These are big; the BDE is two disks and ReportSmith is five.

   6.4 I want to distribute a database application, but I don't want to force
   all my users to create BDE aliases. What do I do?

   The simplest answer is to avoid using aliases in your application.
   Everyting you can set in an alias, you can also set as properties or in the
   Params section of a TDatabase object. For example, if you are accessing
   Paradox files, you can add a "PATH=d:\dir\path" line to the Params
   collection, avoiding the need to use a BDE alias to specify the directory
   where the files reside.