The Delphi FAQ
Maintainer: Graham Mainwaring <
[email protected]>
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 <
[email protected]> 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 <
[email protected]> 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 <
[email protected]> 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 <
[email protected]>, "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/
[email protected]/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/
[email protected]/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/
[email protected]/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/
[email protected]/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/
[email protected]/Works fine, except that it
isn't data-aware once you load it into Delphi.
VBTools Card Deck/MicroHelp/
[email protected]/Works fine
VBTools Dice/MicroHelp/
[email protected]/Works fine
Data Widgets/Sheridan Software/
[email protected]/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
[email protected] 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 <
[email protected]> 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 <
[email protected]> 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 <
[email protected]> 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 <
[email protected]> 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
<
[email protected]>
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 <
[email protected]> 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 <
[email protected]> 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 <
[email protected]> 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 <
[email protected]> 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.