Marco's Web Center

Menu for Books
Delphi 2007 Handbook
Mastering Delphi 2005
Essential Delphi 8 for .NET
Mastering Delphi 7
Essential Pascal
Essential Delphi
Buy Books Online
Marco's TechBookStore

Site Menu
Object Pascal Handbook
Delphi Handbooks Collection
Mastering Borland Delphi 2005
(Old) White Papers
(Old) Conferences

My Other Sites
Italian Site (
the delphi search

Spirit of delphi

Home My Blog Books Object Pascal Marco

Home: Books: Mastering Delphi 3

Mastering Delphi 3


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...

Errors and Omissions (Errata)

  • 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
  • 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.

Further Hints and Tips (Addendum)

  • 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.

Packages are special DLLs

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.