Pascal Newsletter #24
The full source code examples of this issue are available for download.
![]() |
![]() |
Pascal Newsletter #24 - 11-JUL-2001 INDEX 1. A FEW WORDS FROM THE EDITOR 2. DBISAM - What is DBISAM? - Features - Licensing - Pricing and Ordering - Evaluation - Support - More information 3. CUSTOM CONTAINERS PACK (CCPACK 5) - What is Custom Containers Pack? - Downloads - A sample composite component - More information 4. A SIMPLE DATABASE APPLICATION 5. NEWS - Delphi3000.com announces its new membership system - Kylix Desktop Developer Edition for just $199! - Borland releases educational editions - BORCON 2001 - Borland's new registration policy 6. DECOMPILING DELPHI EXECUTABLES 7. DELPHI ON THE NET ________________________________________________________________________ 1. A FEW WORDS FROM THE EDITOR In this issue I'm glad to introduce DBISAM, one of the best BDE replacements available in the market for Delphi and C++ Builder. If you are interested in component writing, I recommend you to read the article about CCPack5. With this freeware expert you can easily develop composite components. As promised in the last issue, here you'll find an example of a simple database application for beginners in database programming. I hope you enjoy this issue... and don't forget to vote for us! ;) Regards, Ernesto De Spirito eds2004 @ latiumsoftware.com ________________________________________________________________________ JfControls Library. Multi-language. Multi-appearance. Skins. Privileges. More than 40 integrated and customizable components. Impressive GUI. Centralized resources administration. Multiple programming problems solved. For Delphi 3-7 and C++ Builder 3-6. http://www.jfactivesoft.com/ ________________________________________________________________________ 2. DBISAM What is DBISAM? =============== DBISAM is a database management system that is linked into your Delphi and C++ Builder applications, and it solves many problems associated with the BDE and MDAC. DBISAM tables use a proprietary file format, but they can be converted to and from MS Access tables, Paradox and other BDE tables. DBISAM tables can be easily created and restructured by code, and normally they don't need to be packed since DBISAM automatically re-uses all free space in data, index, and blob files (although you can easily pack tables if you deem it necessary). With DBISAM it's easy to encrypt a table protected with a password. Data corruption is a worry with other systems. DBISAM is very stable and minimizes the chance of corruption due to power loss, and it comes with an utility to repair tables if they ever get corrupted. Applications using DBISAM can be run from a CD-ROM and they can access DBISAM databases in a CD-ROM or marked with the Read-Only attribute. DBISAM provides progress events for indexing, repairing, copying, optimizing and restructuring tables, so you can show the user a visual indication of the progress of any of those operations. DBISAM is multi-user. It automatically manages all cache refresh and locking issues transparently. Locking is implemented at record level, not at page level. DBISAM is thread-safe and can be used in multiple threads as long as you use a different, dynamically-created TDBISAMSession component instance per thread. This also means that any TDBISAMDatabase, TDBISAMTable, or TDBISAMQuery components must be created dynamically and attached only to the TDBISAMSession component for the current thread. DBISAM's in-memory tables are also thread-safe, so you can safely share the in-memory tables among multiple threads just like a normal table. Features ======== We can talk a lot about DBISAM, but let's allow the features speak by themselves: * Productivity Features - Compiles directly into your .EXE with no external .DLLs or configuration files needed - Has a very small footprint, only 250-300k (base engine size, does not include data access component layer) - Transparent single-user and multi-user usage with no configuration changes required - Complete source code for all utilities provided, and source code for DBISAM itself is available for an additional charge * Version Support - Available for Delphi 3, 4, 5 and C++Builder 3, 4, 5 - TDBISAMTable, TDBISAMQuery, TDBISAMDatabase, and TDBISAMSession components provided for all versions of Delphi (3, 4, 5) and C++ Builder (3, 4, 5) * International Support - International support for over 100 languages - Language and sorting information is stored in each table, no configuration files or special drivers needed * Database Engine Features - Does not pre-allocate large blocks of memory and uses a very small amount of memory per table - Primary and secondary indexes with support for case-insensitive, descending, and unique attributes - Configurable index key compression - Logical sequence numbers that show exact position of record in relation to total records, even with a range set - Partial index key searches and ranges - Accurate record counts, even with active ranges and/or filters - Complete expression filter support including a filter optimizer, SUBSTRING, TRIM, LOWER, UPPER, POS, OCCURS, REPLACE, EXTRACT, CAST, ABS, ROUND, and IF functions, IN, LIKE, IS NULL, and BETWEEN extended operators. - SQL SELECT, INSERT, UPDATE, DELETE CREATE TABLE, ALTER TABLE, DROP TABLE, CREATE INDEX, and DROP INDEX support, complete with a query optimizer, sub-selects, SUM MIN, MAX, COUNT, and AVG aggregate functions, SUBSTRING, TRIM, LOWER, UPPER, POS, OCCURS, REPLACE, EXTRACT, CAST, ABS, ROUND, and IF functions, IN, LIKE, IS NULL, and BETWEEN extended operators, both live and canned result sets, parameterized queries, queries on queries (INTO clause), in-memory query result sets, query progress events, SQL DDL scripts, and extended SQL syntax for DBISAM-specific features - Shareable in-memory tables that are identical to disk-based tables and include streaming support - All native Delphi field types (including BCD, BLOB, and auto- increment field types) supported - Configurable block sizes for BLOBs - NULL support - Min, Max, and Required constraints and default values and character- case specifiers for fields - Long field names and field and table descriptions for reference purposes - Encryption of tables with passwords - User-defined versioning of tables - User-defined semaphore locking - Automatic record locking and manual table locking - Automatic change detection with configurable change detection policy - lazy or strict - Complete cache management including intelligent read-ahead record buffering, index page buffering, BLOB block buffering, and optimized, serialized writes - Automatic read-only support for CD-ROMs including optimized buffering - Buffered transactions that allow tables to survive unexpected client workstation power-downs with little, or in most cases, no data corruption - Built-in table verification and repair facilities complete with progress and log events - Built-in table restructure facilities complete with progress and data conversion events - Automatic free space recycling for data records, index pages, and BLOB blocks - Built-in table optimization facilities complete with progress events - Multi-threading support - Fast performance. DBISAM outperforms Access, Paradox and many others: http://www.elevatesoft.com/benchmrk.htm * Utilities Provided - DBISAM software utilities are available to anyone and, if needed, may be re-distributed to customers. - BDE Database Transfer Utility for transferring BDE-based tables to DBISAM format - Database System Utility for creating, restructuring, browsing, searching, querying, reverse-engineering, and repairing tables interactively * Features Not Supported - Stored procedures - Batch moves (native import/export). However there's a sample of code meant to perform that task. - Cached updates Licensing ========= DBISAM is licensed for royalty-free use within your compiled Delphi and/or C++Builder applications. You have to purchase one license of DBISAM for each full licensed copy of Delphi and/or C++Builder into which you intend to install the DBISAM components. For example, if you own one licensed copy of Delphi 3, the Delphi 3.01 upgrade, the Delphi 4.0 upgrade, etc., you are only required to purchase only one DBISAM license. However, if for example you own two licensed copies of Delphi 3.0, you are required to purchase two DBISAM licenses to be able to use DBISAM in both. Pricing and Ordering ==================== A license of DBISAM costs U$S 249, plus additional U$S 130 if you want the source code. There is a 10% discount off of the normal price of DBISAM for educational and governmental institutions as well as for full-time students at an educational institution. http://www.elevatesoft.com/ordering.htm Evaluation ========== There's a free trial version available for download. The only difference with the commercial version is that a nag dialog that appears once during the initialization of DBISAM when the application is executed outside the IDE, and the license only allows its use for evaluation purposes only. * DBISAM Trial Version - Version 2.10 http://www.elevatesoft.com/download.htm * Additional Software and Utilities http://www.elevatesoft.com/download.htm Support ======= Elevate Software offers electronic support via email or through their officially-monitored support newsgroups. E-mail and newsgroup support questions are answered within 12 hours of their receipt. Support e-mail and newsgroup posts are reviewed every hour from 8:00 am EST to 8:00 pm EST, so the longest wait for a response should be 24 hours. Elevate Software provides support for those evaluating the trial version of DBISAM. * Email: support@mail.elevatesoft.com * Newsgroups: - Announcements news://news.elevatesoft.com/elevatesoft.public.announcements - Public Beta Tests news://news.elevatesoft.com/elevatesoft.public.beta - DBISAM news://news.elevatesoft.com/elevatesoft.public.dbisam - General Discussion news://news.elevatesoft.com/elevatesoft.public.discussion - Third Party Job Postings news://news.elevatesoft.com/elevatesoft.public.jobs - SQL news://news.elevatesoft.com/elevatesoft.public.sql - Enhancement Suggestions news://news.elevatesoft.com/elevatesoft.public.suggestions - Test Posts news://news.elevatesoft.com/elevatesoft.public.test - Third Party Announcements and Information news://news.elevatesoft.com/elevatesoft.public.thirdparty More information ================ You can find more information about DBISAM, including customer quotes, screen shots, on-line user's manual, technical bulletins, etc. at Elevate Software's web site: http://www.elevatesoft.com/ --------------------- Portions of this article were taken from Elevate Software's web site and are Copyright (c) 2001 Elevate Software - All Rights Reserved. They have been reproduced and modified here with the author's permission. ________________________________________________________________________ 3. CUSTOM CONTAINERS PACK (CCPACK 5) What is Custom Containers Pack? =============================== CCPack 5 is a freeware package that allows you to visually combine, extend and inherit VCL containers. The package was developed by Sergey Orlik, Product Manager of Inprise Moscow office (Russia, C.I.S. and Baltic States). CCPack 5 works with Delphi/C++Builder 5, and is the evolution of two existing Delphi/C++Builder 3,4 add-ins: Custom Forms Pack (CFPack) and Composite Components Pack (CCPack 4). One of the common uses of CCPack 5 is to create components made of various components: * CCPack Introduction movie http://www.geocities.com/sergey_orlik/ccpmovie.zip (~337K) Downloads ========= * Custom Containers Pack (CCPack 5) for Delphi/C++Builder 5 http://www.geocities.com/sergey_orlik/ccpack5.zip (~695K) * CCPack 4.5 for Delphi/C++Builder 3 and 4 http://www.geocities.com/sergey_orlik/ccpack4.zip (~591K) * CFPack 4.3 for Delphi/C++Builder 4 http://www.geocities.com/sergey_orlik/cfpack4.zip (~129K) * CFPack 1.01 for Delphi/C++Builder 3 (old and non-modified version) http://www.geocities.com/sergey_orlik/cfpack.zip (~45K) Full source code is provided and you can modify it without restriction for any non-commercial projects. Let the author know if you want to use this software in your commercial projects by e-mail <sorlik@inprise.ru> stating the tool's name in the subject line. A sample composite component ============================ After you have installed CCPack, you're ready for the first example. Close all Delphi projects. In the "File" menu choose "New...", select "Custom Container" (or "Composite Control" in Delphi 3/4) in the "New items" dialog, and click "OK". In the "New Container" dialog select "TFrame", write "TFileComposite" in the "New class name" field and click "Finish". A form appears. Its surface is the surface of your new Delphi component. Set the following properties in the Object Inspector: Width = 281 Height = 164 This will be the default size of the component. Drop a Panel onto the form, and set its properties: Align = alLeft Width = 130 BevelOuter = bvNone Caption = Constraints.MinWidth = 110 Drop a Splitter to the right to the panel. It will align automatically to the side of the panel. Drop a DriveComboBox and a DirectoryListBox on the panel and set their properties: DriveComboBox: Left = 0 Top = 0 Width = 130 Height = 19 Anchors = [akLeft, akTop, akRight] DirectoryListBox: Left = 0 Top = 19 Width = 130 Height = 145 Anchors = [akLeft, akTop, akRight, akBottom] Click on the right side of the form, and drop a FileListBox: Align = alClient TabOrder = 0 With this we have completed the visual interface of our composite component. Now it's time to add some code to "link" the components. Double click the DriveComboBox and in the Change event handler write: procedure TFileComposite.DriveComboBox1Change(Sender: TObject); begin DirectoryListBox1.Drive := DriveComboBox1.Drive; end; Double click the DirectoryListBox and in the Change event handler write: procedure TFileComposite.DirectoryListBox1Change(Sender: TObject); begin FileListBox1.Directory := DirectoryListBox1.Directory; end; With this we have completed the basic behavior of our composite component, which for the programming interface will inherit the methods and properties from TFrame (the base class we chose when we created the component). Let's add a couple of public properties: FileName and Directory. In the declaration of the class add: type TFileComposite = class(TFrame) : : protected { Protected declarations } function GetFileName: string; procedure SetFileName(FileName: string); function GetDirectory: string; procedure SetDirectory(Directory: string); public { Public declarations } property FileName: string read GetFileName write SetFileName; property Directory: string read GetDirectory write SetDirectory; : : The implementation is quite simple. Basically we get and set the FileName of the FileListBox and the Directory property of the DirectoryListBox: function TFileComposite.GetFileName: string; begin Result := FileListBox1.FileName; end; procedure TFileComposite.SetFileName(FileName: string); begin FileListBox1.FileName := FileName; end; function TFileComposite.GetDirectory: string; begin Result := DirectoryListBox1.Directory; end; procedure TFileComposite.SetDirectory(Directory: string); begin DirectoryListBox1.Directory := Directory; end; Now let's add three events: Change, Click and DblClick. In the declaration of the class add: type TFileComposite = class(TFrame) : : private { Private declarations } FOnChange: TNotifyEvent; FOnClick: TNotifyEvent; FOnDblClick: TNotifyEvent; protected : public : published { Published declarations } property OnChange: TNotifyEvent read FOnChange write FOnChange; property OnClick: TNotifyEvent read FOnClick write FOnClick; property OnDblClick: TNotifyEvent read FOnDblClick write FOnDblClick; end; As you might be guessing, these events will be triggered by the Change, Click and DblClick events of the FileListBox, so generate the corresponding event handlers and write the following: procedure TFileComposite.FileListBox1Change(Sender: TObject); begin if Assigned(FOnChange) then FOnChange(Self); end; procedure TFileComposite.FileListBox1Click(Sender: TObject); begin if Assigned(FOnClick) then FOnClick(Self); end; procedure TFileComposite.FileListBox1DblClick(Sender: TObject); begin if Assigned(FOnDblClick) then FOnDblClick(Self); end; If you wonder about the Assigned function, please allow me to explain. FOnChange is a field of type TNotifyEvent, and this means that it can hold the address of a procedure of object that takes a "Sender: TObject" parameter... or it can be Nil, so we should make sure that FOnChange isn't Nil before making the call "FOnChange(Self)". However, the following won't work: if FOnChange <> nil then ... The reason is that referring FOnChange is taken by the compiler as an invocation of the procedure it points to. Since it's a procedure, it doesn't return a value type-compatible with a pointer (so we can't compare it with Nil), but before realizing this, the compiler will find that we forgot the parameter (Sender) in the call to FOnChange... Our intention is not to call the procedure FOnChange points to, but to know whether the value of FOnChange isn't Nil. This is the purpose of the built-in Assigned function used above. For the purpose of the example, this is it. You can install this unit and then use the component from the Components Palette, or you can include the unit in a test project and create the component by code like we did in the test application to save you from having to install a useless component. As you can see, with CCPack someone with little experience in component writing can build composite components quickly and easily. More information ================ You can find more information about CCPack, and find other components at Sergey Orlik's web site: http://www.geocities.com/sergey_orlik ________________________________________________________________________ 4. A SIMPLE DATABASE APPLICATION From time to time at Latium Software we receive a request like the following: > I'd like to know which is the way to build a database application with > Delphi. I already know how to work with tables, forms, components, > etc. What I want to know is the way to integrate everything... In many ways Delphi is like those construction kits I played with when I was a boy. These kits had many pieces of different shapes, sizes and colors, and with them you could build whatever you wanted, limited only by your imagination... and the available pieces, of course. Delphi has a lot of components and you can use them to build the application you want. Borland does not suggest a way to do things. They just put the bricks there, and it's up to you how you build your house. There are many ways to do things. In the archive attached to this newsletter you'll find one of these ways. It doesn't intend to be the best way to write a database application, or a recommended way to do it. What's more, I don't even claim it's a good way to do it. The intention is simply to serve as an example showing one of the possibilities. You can improve it and use it as a base for your own projects. When you take a look at the example, you'll see that I used a data module with two tables (Customers and Orders, that come as sample tables with the BDE) with a master-detail relationship (you can see it in the Data Diagram). If you double click on the Table components you'll see that I defined some properties of the fields like the display width, display format, edit mask, etc. I placed the DataSource components in the data module, to show that you can place them there and not necessarily place one on each form that access these tables. The application uses a MDI interface. From the menu you can show the Customers form, which displays the content of the Customers table in a DbGrid. In the form there's a button "Orders..." to show the orders placed by the currently selected customer. Notice that you can switch back to the Customers form and if you move to another record, the Orders form gets automatically updated (thanks to the master-detail relationship set between the two tables). In both forms you have buttons to add, edit and delete records from the respective tables. The "Add..." and "Edit..." buttons show a modal form that allows you to add or edit a single record. You'll see that this form is created the first time and then it's hidden when closed, so it's readily available if we need to invoke it again. The form will be released automatically when its parent form is released. In the Order form there's an example of a DbCombo and a DbLookupCombo that lists a calculated field from another table (Employees). We leave the rest of the example for your analysis. If you have doubts or questions about it, I'd like to invite you to join our low-traffic forum for Delphi programmers at Yahoo! Groups, where other members or even ourselves might be able to help. Home: http://groups.yahoo.com/group/delphi-en Join: http://groups.yahoo.com/group/delphi-en/join delphi-en-subscribe@yahoogroups.com ________________________________________________________________________ 5. NEWS Delphi3000.com announces its new membership system ================================================== Delphi3000.com now offers three kinds of membership: * Bronze Membership. Limited access. Free. * Silver Membership. Full access. USD 4.90/mo. Uploaders get a free Silver Membership. * Gold Membership. Full access, plus a message in the newsletter. USD 14.90/mo. Delphi3000.com members now have iTecture CodeFinder, an application to browse the Delphi3000.com database off-line. Why? http://www.delphi3000.com/why.asp Details: http://www.delphi3000.com/whysignup.asp NOTE: If you can't enter the site with www.delphi3000.com try with 213.208.2.22 instead. Kylix Desktop Developer Edition for just $199! ============================================== Exactly as the title reads, Borland is selling the Desktop Developer Edition (DDE) of Kylix for only just $199! Yes! Only just $199! You don't believe it? Well, read it by yourself: http://shop.borland.com/Product/0,1057,3-15-CQ100479,00.html If you bought Kylix DDE before this offer was in effect, you can contact your local Borland Customer Service to get a free upgrade to Kylix Server Development Edition. Borland releases educational editions ===================================== Borland now offers educational editions of Delphi and Kylix: * Delphi 6 Enterprise Educational edition.......................$399 * Delphi 6 Professional Educational edition......................$99 * Kylix Server Developer Educational edition (available soon)...$399 * Kylix Desktop Educational edition (available soon).............$99 BORCON 2001 =========== The 12th Annual Borland Conference (BORCON 2001) will be held from July 21 to 25 in Long Beach, California. There's still time to register. http://www.borland.com/conf2001/ Borland's new registration policy ================================= Starting with JBuilder 5 and Delphi 6, registration of Borland software is no longer optional: * Open letter to the Borland Community regarding registration of Borland products - by David Intersimone http://community.borland.com/article/0,1410,27382,00.html * Delphi 6 Internet registration - by David Intersimone http://community.borland.com/article/0,1410,27385,00.html ________________________________________________________________________ 6. DECOMPILING DELPHI EXECUTABLES It isn't possible to recover completely the original Delphi sources of an application from its executable file, far from that, but something can be done. If you are interested in decompiling or reverse engineering Delphi executables, I suggest you the following pages: * EXE2DPR - Delphi project sources Rescuer Versions supported: Delphi 1.0-4.0 and C++Builder 3.0 http://www.ems.ru/~gold/exe2dpr.html * DeDe Versions supported: Delphi 2,3,4,5 and Builder http://www.balbaro.com/dede/index.html * Revendepro Versions supported: Delphi 4 and Delphi 5 http://www.puthoon.com/Revendepro/index.html * MultiRipper Versions supported: N/A http://www.csee.uq.edu.au/~csmweb/decompilation/application.html * Delphi project sources rescuer - without sources Versions supported: Delphi 3 and Delphi 4 shareit1.element-5.de/programs.html?productid=100815&languageid=1 ________________________________________________________________________ 7. DELPHI ON THE NET * Delphi Database Programming Course - by Zarko Gajic Free online database programming course for beginner Delphi developers focused on ADO techniques. Three new chapters have been added in the last two months (Chapter 9 "Searching for data", Chapter 10 "ADO Cursors" and Chapter 11 "From Paradox to Access with ADO and Delphi"). http://delphi.about.com/compute/delphi/library/weekly/aa010101a.htm * An introduction to hook procedures - by Chris Cummings What Windows hooks are and how to use them in a Delphi application. http://delphi.about.com/compute/delphi/library/bluc/text/uc063001a.htm * Sticky Windows - by Zarko Gajic How to dock your Delphi forms to the edges of your desktop screen. http://delphi.about.com/library/weekly/aa070301a.htm * Automating Internet Explorer to find all links on a web page - By Corbin Dunn - Borland Developer Support Staff You may want to find all links on a given web page. This document has source code and directions on how to do this. http://community.borland.com/article/0,1410,26574,00.html * General Issues in Delphi Client/Server Development - by Bill Wolf This paper will cover some important aspects of client/server development learned the hard way — in real world situations. It will include a brief overview of the client/server methodology and a discussion of why so many projects run in to difficulties as well as ways to avoid them. http://ourworld.compuserve.com/homepages/billw/dl130.htm * Anti Cracking FAQ - by R. Fellner How to make cracking your programs a little harder http://www.inner-smile.com/nocrack.phtml * Kylix & Delphi 6 New Language Features - by Dr. Bob This article shows a few of the Kylix and Delphi 6 changes in the compiler and the RunTime Library (RTL). http://www.drbob42.com/Delphi5/examin19.htm * Cross-platform DrBobCGI (and Cookies) - by Dr. Bob This article presents the cross-platform edition of DrBobCGI (to produce web server applications with Delphi and Kylix without the need for the WebBroker Technology). As one of the examples, Dr.Bob shows how to (set and) get cookie values using DrBobCGI. http://www.drbob42.com/Delphi5/examin18.htm * Shakespeare on the Web - by John Kaster This article shows how to produce a basic web service application that spews Shakespearean insults http://community.borland.com/article/0,1410,27399,00.html * Community TV: RAD Product Group Overview with Simon Thornhill Anders O interviews Simon Thornhill about Delphi 6 and future plans of the RAD product group. Now with MP3 audio and text transcript. http://community.borland.com/article/0,1410,27299,00.html * Community TV: Delphi 6 XML Data Bindings with Mark Edington John K talks with Mark Edington about XML Data Bindings and how support for XML DOM is implemented with Object Pascal language bindings. Includes MP3 audio and text transcript. http://community.borland.com/article/0,1410,27323,00.html * Community TV: Delphi 6 Overview with Michael Swindell Anders O interviews Michael Swindell, Director of Product Management for the RAD Group, who provides an overview of Delphi 6's new features BizSnap, WebSnap and DataSnap. Includes text transcript and audio mp3 http://community.borland.com/article/0,1410,27300,00.html * Getting started with WebSnap in Delphi 6 Enterprise John K explains how to use the WebSnap framework to produce a fully functional browser-based database application, complete with graphic field support http://community.borland.com/article/0,1410,27404,00.html ________________________________________________________________________ YOU CAN HELP US We need your help to keep this newsletter going and growing. The easiest way you can help us is voting for us in any or some of these rankings to help give more visibility to our web site and thus increase the number of subscriptions to this newsletter: http://www.sandbrooksoftware.com/cgi-bin/TopSite2/rankem.cgi?id=latium http://news.optimax.com/delphi/links/links.exe/click?id=70C517ECAE6E http://www.programmingpages.com/?r=latiumsoftwarecomenpascal http://www.top219.org/cgi-bin/vote.cgi?delphi&83 http://top100borland.com/in.php?who=20 http://top200.jazarsoft.com/delphi/rank.php3?id=latium http://213.65.224.200/cgi-bin/toplist.cgi/hits?Id=80 It's just a few seconds for you that REALLY mean much to us. ________________________________________________________________________ If you haven't received the full source code examples for this issue, you can get them from http://www.latiumsoftware.com/download/p0024.zip ________________________________________________________________________ This newsletter is provided "AS IS" without warranty of any kind. Its use implies the acceptance of our licensing terms and disclaimer of warranty you can read at http://www.latiumsoftware.com/en/legal.php where you will also find a note about legal trademarks. Articles are copyright of their respective authors and they are reproduced here with their permission. You can redistribute this newsletter as long as you do it in full (including copyright notices), without changes, and gratis. ________________________________________________________________________ Main page: http://www.latiumsoftware.com/en/pascal/delphi-newsletter.php Group home page: http://groups.yahoo.com/group/pascal-newsletter/ Subscribe/join: pascal-newsletter-subscribe@yahoogroups.com Unsubscribe/leave: pascal-newsletter-unsubscribe@yahoogroups.com Problems with your subscription? eds2004 @ latiumsoftware.com ________________________________________________________________________ Latium Software http://www.latiumsoftware.com/en/index.php Copyright (c) 2001 by Ernesto De Spirito. All rights reserved. ________________________________________________________________________ |
The full source code examples of this issue are available for download.
![]() |
Errors? Omissions? Comments? Please contact us!






