Mastering Delphi 3
Updates
Although I've tried to check every single page of the book with
care, there is no way a 1500 pages book can be complete correct.
The book "Mastering Delphi 3" was also released at the
same time of Delphi 3, so I failed to notice few of the final
changes of the software in time for printing. The list of
errors and omissions,
sorted by chapter and page, is followed by a list of
further hints and tips.
Beside the technical errors there are two small problems with
the cover. The text close to the CD icon should read "More
than 300 Delphi Examples" (not "Objects"). The
"Second Edition" tag is a little confusing, because
this is actually the third edition. Seems this has to do with
the fact this is the second edition covering a 32 bit version
of Delphi, or with the fact that the title changed for the second
edition, I'm not really sure...
- Chapter 1, Hello example: The project on the companion CD
has a reference to a wrong package, and shows an error message
on loading. Simply ignore it.
- Chapter 1, XForm example: The source code of this example
as that of all the other examples based on ActiveForms (see Chapter
24) requires a few changes to work with the release version of
Delphi. It won't recompile as is. If you follow the simple steps
mentioned in the text you'll be able to rebuild it properly.
- Chapter 2, page 48, second paragraph: The "Show Last
Compile Error" command is not part of Delphi 3. Actually
it was not even part of Delphi 2...
- Chapter 2, page 50, final tip: The "Open toolbar button"
mentioned is actually the "Open Project" button of the
Delphi toolbar (not to be confused with the "Open File"
button).
- Chapter 4, page 115, note: The caption of the note should
read "New", meaning this is a new feature of Delphi
3.
- Chapter 11, AnimCtrl example: The CommonAVI property of the
Animate component has slightly changed, so the program will not
open in the Delphi environment. You should open the DFM file in
the Delphi editor, go to the line of the Animate control: CommonAVI
= caFindFolder; and change it to CommonAVI = aviFindFolder.
The same problem surfaces also in the WebNav example of Chapter
24 (but in this case you can open the project, then reset the
property). Here is the updated complete code of the example, in the file AnimCtrl.zip.
- Chapter 12, CoolDemo example: Opening the program shows a
couple of hints related to non-existing properties. Simply pressing
the cancel button fixes the problem.
- Chapter 16, page 790, tring to change the value of any population or area, there is an error. This is due to the fact that the EditFormat property of the fields should be set to
######### without the thousand separators.
- Chapter 17, Interbase-related examples (IbEmp, SqlJoin, SqlJoin2):
you might have problems with the default Interbase aliases, which
point to different databases then those in the beta versions.
- Chapter 17, page 836, first paragraph: Delphi's default data
directory is "Delphi 3/Demos/Data", and not "3.0".
- Chapter 17, page 866, the last two sentences before the title
should read: "Defining an association between an attribute
type and one or more fields of the tables of a database forces
Delphi to use the proper attributes every time you use a table
with one of those field inside an application. For example, all
the 'Phone' fields (such as phone number and fax number) of a
table can be associated with a specific attribute set, so that
every time you use that tables in a program Delphi will automatically
set the proper input mask of the field object, as well as other
attributes. This works also if the field is retrieved as part
of a query, but only if you create the field objects at design-time."
- Chapter 18, page 889, first two bullets: The class we inherit
from is TComboBox, and the new class we are building is Tmd3ComboBox,
as Figure 18.1 properly shows.
- Chapter 18, page 917, the paragraph before the title is incorrect.
It should be: "When the bitmap for the component is ready,
you can install the component in Delphi selecting Components >
Install Components, and choosing a package (or creating a new
one), and Delphi should add to the source code of the package
also a resource inclusion statement for the component bitmap.
This doesn't always work, but you can add the {$R arrow3.dcr}
statement in the package source code yourself. Even better, you
can add the generic statement {$R *.dcr} in the source
code of the unit defining the component.
- Chapter 18, page 928, the 9th line of the initial listing
should be: "FTabStops [I] := StrToIntDef (Copy ..."
- Chapter 20, page 969, second last bullet. The text here is
really wrong. Packaged units include version information, so an
updated package will actually crash an existing application based
on it. The text should read: "If you use a package as a DLL,
when you have a new updated version of the package, you'll need
to recompile the program or this will show an odd error message
at start up, and will not run." Keep in mind that, as an
alternative to updating the executable file, you can distribute
each the new version of the package using a different file name.
Of course the older executable files won't take advantage of the
new version, but at least they'll keep running. See also the
Packages are special DLLs section for more information.
- Chapter 23, XArrow program: The program will not compile,
because the RegisterNonActiveX procedure has an extra parameter.
The code should read RegisterNonActiveX([TMd3WArrowX], axrComponentOnly).
- Chapter 24, XFMulti and XForm1 examples: These program will
not compile unless you make a couple of changes in the source
code, following the compiler error messages (or simply rebuilding
them from scratch following the description in the text).
- Chapter 28, page 1282, first paragraph, third sentence: "Again,
I've chosen this tool because it's a former Borland product, which
was included in the Client/Server version of Delphi. Delphi
still includes an interface to this engine, in the form of the
Report component, which is not installed by default." In
any case to compile any of the ReportSmith examples you should
have the engine (maybe the one included in Delphi 2) and you can
refer to the proper unit by adding to the path (in the Libraries
page of the Environment Options) the string: \lib\Delphi2.
- Related to Chapter 21: Pressing Ctrl+G in the editor generates
a new GUID automatically, so you don't need to copy one
from an external program.
- You can use the VER100 define to conditionally compile
for Delphi 3. This can be useful if you want to maintain compatibility
with Delphi 2 or Delphi 1.
- Here are two (unrelated) usefull routines not mentioned in
the text: Swap and ProcessPath.
It seems that many programmers think they can apply their knowledge
about DLLs usage to packages (I did this error myself). Building
a small EXE and several DLLs is a typical way to make a program
more flexible (you fix a bug in small DLL and ship only that to
your clients). You simply CANNOT use packages this way, because
packages include version information! The effect is that
if you recompile the package-DLL, you need to recompile all the
executables files based on the package-DLL. Otherwise starting
the program will produce a Windows error, almost incomprehensible
to users (something like: Cannot find package:unit:method).
Seems there is no obvious way to make the program die gracefully.
This is a problem of the Windows loader, which loads the DLL and
tries to fix the import table of the executable file... but doesn't
find a proper match!
So packages are just for components distribution, and I strongly
advise against using home-built packages at run-time! Of course
the incompatibility takes place only if you do changes in the
interface section of one of the units of the package: If you only
edit code in the implementation section there will be no problem.
However, since packages are meant as component packages, every
time you change the interface or even add something to it without
changing the existing code, all the programs using the previous
version of the package will be broken. A solution is to add the
version number inside the name of the package DLL: If mypack01.dpl
becomes mypack02.dpl the older programs still works. The
drawback is that you might end up with ten versions of a package
on disk, and not be sure which are actually in use. I think the
new CDK (the Component Developer Kit from Eagle Software) uses
this approach.