Data Link Files
So a TADOConnection allows us to centralize the definition of a connection string within a form or data module. However, even though this is a worthwhile step forward from scattering the same connection string throughout all ADO datasets, it still suffers from a fundamental flaw If you use a database engine that defines the database in terms of a filename, then the path to the database file s is hard-coded in the EXE. This makes for a very fragile application. The BDE uses aliases to overcome...
Form Constraints
When you choose a resizable border for a form, users can generally resize the form as they like and also maximize it to full screen. Windows informs you that the form's size has changed with the wm_Size message, which generates the OnResize event. OnResize takes place after the size of the form has already been changed. Modifying the size again in this event if the user has reduced or enlarged the form too much would be silly. A preventive approach is better suited to this problem. Delphi...
A Delphi Form in a DLL
Besides writing simple DLLs with functions and procedures, you can place a complete form built with Delphi into a DLL. This can be a dialog box or any other kind of form, and it can be used not only by other Delphi programs, but also by other development environments or macro languages. To build the FormDLL example, I've built a simple form with three scroll bars you can use to select a color and two preview areas for the resulting pen and brush colors. The form also contains two bitmap buttons...
Moving Control Grid Panels
To improve the last example, we might resize the grid using the FormResize method. We could simply write the following code in the Multi2 example procedure TForm1.FormResize Sender TObject begin DBCtrlGrid1.Height ClientHeight - Panel1.Height DBCtrlGrid1.Width ClientWidth end This works, but it is not what I want. I'd like to increase the number of panels, not enlarge them. To accomplish this, we can define a minimum height for the panels and compute how many panels can fit in the available...
MasterDetail Structures
Often you need to relate tables, which have a one-to-many relationship. This means that for a single record of the master table, there are many detailed records in a secondary table. A classic example is that of an invoice and the items of the invoice another is a list of customers and the orders each customer has made. This is very common situation in database programming, and Delphi provides explicit support for it with the master detail structure. We'll see this structure for BDE Table and...
What Is Dynamic Linking
First of all, you need to understand the difference between static and dynamic linking of functions or procedures. When a subroutine is not directly available in a source file, the compiler adds the subroutine to an internal table, which includes all external symbols. Of course, the compiler must have seen the declaration of the subroutine and know about its parameters and type, or it will issue an error. After compilation of a normal static subroutine, the linker fetches the subroutine's...
Pessimistic Locking
The words pessimistic and optimistic in this context refer to the developer's expectations of conflict between user updates. Pessimistic locking assumes that there is a high probability that users will attempt to update the same records at the same time and that a conflict is likely. In order to prevent such a conflict, the record is locked when the edit begins. The record lock is maintained until the update is completed or cancelled. A second user who attempts to edit the same record at the...
Persistent Recordsets
One of the very useful features that contributes to the briefcase model is persistent recordsets. These allow you to save the contents of any recordset to a local file, which can be loaded later. Apart from aiding with the briefcase model, this feature allows developers to create true single-tier applications. It means that you can deploy a database application without having to deploy a database. This makes for a very small footprint on your client's machine. You can persist your datasets...
XSLT with WebSnap
Within the code of a program, you can execute the TransformNode method of a DOM node, passing to it another DOM hosting the XSL document. Instead of using this low-level approach, however, we can let WebSnap help us to create an XSL-based example. In fact, you can create a new WebSnap application I've built a CGI program called XslCust in this case and choose an XSLPageProducer component for its main page, to let Delphi help you start with the application code. Actually, Delphi also includes a...
Configuring a Local Network IP Addresses
If you have a local network available, you'll be able to test the following programs on it otherwise, you can simply use the same computer as client and server. In this case, as I've Foundations of Socket Programming 913 done in the examples, use the address 127.0.0.1 or localhost , which is invariably the address of the current computer. If your network is complex, ask your network administrator to set up proper IP addresses for you. If you want to set up a simple network with a couple of...
A Complex Graphical Component
The graphical component I want to build is an arrow component. You can use such a component to indicate a flow of information, or an action, for example. This component is quite complex, so I'll show you the various steps instead of looking directly at the complete source code. The component I've added to the MdPack package on the CD is only the final version of this process, which will demonstrate several important concepts The definition of new enumerated properties, based on custom...
Figure 27
The Add To Interface dialog box, with the syntax helper in action In the edit box, you can then type the declaration of this new interface element. If the Syntax Helper check box is activated, you'll get hints describing what you should type next and highlighting any errors. You can see the syntax helper in action in Figure 20.17. When you define a new ActiveX interface element, keep in mind that you are restricted to OLE data types. In the XArrow example, I've added two properties to the...
The Form Style
The FormStyle property allows you to choose between a normal form fsNormal and the windows that make up a Multiple Document Interface MDI application. In this case, you'll use the fsMDIForm style for the MDI parent window that is, the frame window of the MDI application and the fsMDIChild style for the MDI child window. To know more about the development of an MDI application, look at Chapter 10. A fourth option is the fsStayOnTop style, which determines whether the form has to always remain on...
An Overview of CGI
CGI is a standard protocol for communication between the client browser and the Web server. It's not a particularly efficient protocol, but it is widely used and is not platform specific. This protocol allows the browser both to ask for and to send data, and it is based on the standard command-line input and output of an application usually a console application . When the server detects a page request for the CGI application, it launches the application, passes command-line data from the page...
The First Thin Client
Now that we have a working server, we can build a client that will connect to it. We'll again start with a standard Delphi application and add a DCOMConnection component to it or the proper component for the specific type of connection you want to test . This component defines a ComputerName property that you'll use to specify the computer that hosts the application server. If you want to test the client and application server from the same computer, you can leave this blank. Once you've...
Working with Unidirectional Cursors
The motto of dbExpress could be fetch but don't cache. The key difference between this library and BDE or ADO is that dbExpress can only execute SQL queries and fetch the results in a unidirectional cursor. In unidirectional database access, you can move from one record to the next, but you cannot get back to a previous record of the dataset. This is because the library doesn't store the data is has retrieved in a local cache, but only passes it from the database server to the calling...
Late Binding and Polymorphism
Pascal functions and procedures are usually based on static or early binding. This means that a method call is resolved by the compiler and linker, which replace the request with a call to the specific memory location where the function or procedure resides. This is known as the address of the function. OOP languages allow the use of another form of binding, known as dynamic or late binding. In this case, the actual address of the method to be called is determined at run time based on the type...
Overloaded Constructors
Overloading is particularly relevant for constructors, because we can add to a class multiple constructors and call them all Create, which makes them easy to remember. Historically, overloading was added to C to allow the use of multiple constructors that have the same name the name of the class . In Object Pascal, this feature was considered unnecessary because multiple constructors can have different specific names. The increased integration of Delphi with C Builder has motivated Borland to...
ListBased DataAware Controls
For letting a user choose a value in a predefined list which reduces input errors , you can use many different components. DBListBox, DBComboBox, and DBRadioGroup are similar, providing a list of strings in the Items property, but they do have some differences The DBListBox component allows selection of predefined items closed selection , but not text input, and can be used to list many elements. Generally it's best to show only about six or seven items, to avoid using up too much space on the...
Mapping XML with Transformations
There is one more technique you can use in Delphi 6 to handle at least some XML documents. You can create a transformation to translate the XML of a generic document into the format used natively by the ClientDataSet component when saving data to a MyBase XML file. In the reverse direction, another transformation can turn a dataset available within a ClientDataSet through a DataSetProvider component into a XML file of a required format or schema . Delphi 6 includes a wizard to generate such...
Data in a Grid
The DBGrid is a grid capable of displaying a whole table at once. It allows scrolling and navigation, and you can edit the grid's contents. It is an extension of the other Delphi grid controls. You can customize the DBGrid by setting the various flags of its Options property and modifying its Columns collection. The grid allows a user to navigate the data, using the scrollbars, and perform all the mayor actions. A user can edit the data directly, insert a new record in a given position by...
Figure 32
The form of the Client2 program after the server has returned the list of the files of a directory The core of the program is in the ClientSocketiRead method, triggered by the socket when there is data to read. The method is first used to get the header indicating which type of data is reaching the program and to set the client program to the proper status case CliStatus of look for data to receive csIdle begin Socket.ReceiveBuf Buffer, 5 strIn Copy Buffer, 1, 5 if strIn 'TEXT ' then CliStatus...
Component Packages
Components are added to component packages. Each component package is basically a DLL a dynamic link library with a BPL extension which stands for Borland Package Library . Packages come in two flavors design-time packages used by the Delphi IDE and run-time packages optionally used by applications. The design-only or run-only package option determines the package's type. When you attempt to install a package, the IDE checks whether it has the design-only or run-only flags, and decides whether...
MasterDetail in WebSnap
The DataSetAdapter component has specific support for master detail relationships between datasets. After you've created the relationship among the datasets, as usual, define an adapter for each dataset and then connect the MasterAdapter property of the adapter of the detail dataset. Setting up the master detail relationship between the adapters makes them work in a more seamless way. For example, when you change the work mode of the master, or enter new records, the detail automatically enters...
Monitoring the Connection
Another feature, which I've added only to the DbxSingle example, is the monitoring capability offered by the SQLMonitor component. In the example, the component is activated as the program starts. Every time there is a tracing string available, the component fires the OnTrace event to let you choose whether to include the string in the log. If the LogTrace parameter of this event is True the default value , the component logs the message in the TraceList string list and fires the OnLogTrace...
The TComponent Class
If the TPersistent class is really more important than it seems at first sight, the key class at the heart of Delphi's component-based class library is TComponent, which inherits from TPersistent and from TObject . The TComponent class defines many core elements of components, but it is not as complex as you might think, as the base classes and the language already provide most of what's actually needed. I won't explore all of the details of the TComponent class, some of which are more...
Assigning Objects
If a variable holding an object only contains a reference to the object in memory, what happens if you copy the value of that variable Suppose we write the BtnTodayClick method of the ViewDate example in the following way procedure TDateForm.BtnTodayClick Sender TObject var LabelDate.Caption TheDay.GetText end This code copies the memory address of the NewDay object to the TheDay variable as shown in Figure 2.6 it doesn't copy the data of an object into the other. In this particular...
Microsoft Data Access Components MDAC
ADO is part of a bigger picture called Microsoft Data Access Components MDAC . MDAC is an umbrella for Microsoft's database technologies and includes ADO, OLE DB, ODBC, and RDS Remote Data Services . Often you will hear people use the terms MDAC and ADO interchangeably but incorrectly because their version numbers and releases are now aligned. As ADO is only distributed as part of MDAC, we talk in terms of MDAC releases. The major releases of MDAC have been versions 1.5, 2.0, 2.1, 2.5, and 2.6....
The XMLBroker Component
Internet Express uses multiple technologies to accomplish this. The DataSnap data packets are converted into the XML format, to let the program embed this data right into the HTML page for Web client-side manipulation. Actually, the Delta data packet is also represented in XML. These operations are performed by the XMLBroker component, which can handle XML and provide data to the new JavaScript components. Like the ClientDataSet, the XMLBroker has A MaxRecords property indicating the number of...
Registering Property Categories
We've added to this component some custom properties and a new event. If you arrange the properties in the Object Inspector by category a feature available since Delphi 5 , all the new elements will show up in the generic Miscellaneous category. Of course, this is far from ideal, but we can easily register the new properties in one of the available categories. We can register a property or an event in a category by calling one of the four overloaded versions of the RegisterPropertylnCategory...
Live Queries and Cached Updates
When working with local data, it is very common to use grids and other visual controls, edit the data, and send it back to the database. We've already seen that using a DBGrid might cause problems when working with an RDBMS, as moving on the grid might send numerous data requests to the server, creating a huge amount of network traffic. When you use the Query component to connect to some data, you cannot edit the data unless its RequestLive property is set to True. If you are working with local...
Unusual Techniques Alpha Blending Color Key and the Animate API
One of the few new features of Delphi 6 related to forms is support for some new Windows APIs regarding the way forms are displayed not available under Qt CLX . For a form, alpha blending allows you to merge the content of a form with what's behind it on the screen, something you'll rarely need, at least in a business application. The technique is certainly more interesting when applied to bitmap with the new AlphaBlend and AlphaDIBBlend API functions than to a form itself. In any case, by...
The Fields of a Dataset
I mentioned earlier that a dataset has only one record that is the current, or active, one. The record is stored in a buffer, and you can operate on it with some generic methods, but to access the data of the record you need to use the field objects of the dataset. This explains why field components technically instances of class derived from the TField class play a fundamental role in every Delphi database application. Data-aware controls are directly connected to these field objects, which...
Custom Method Calls
Since the server has a normal COM interface, we can add more methods or properties to it and call them from the client. Simply open the type library editor of the server and use it as with any other COM server. In the AppSPlus example, I've added a custom Login method with the following implementation procedure TAppServerPlus.Login const Name, Password WideString begin TODO add actual login code if Password lt gt Name then raise Exception.Create 'Wrong name password combination received' else...
Section III Record Buffers and Field Management
Now that we've covered all the support methods, we can examine the core of a custom dataset. Besides opening and creating records and moving around between them, the component really needs to move the data from the stream the persistent file to the record buffers, and from the record buffers to the TField objects that are connected to the data-aware controls. The management of record buffers is quite complex, because each dataset also needs to allocate, empty, and free the memory it requires...
Dragging and Drawing with the Mouse
To demonstrate a few of the mouse techniques discussed so far, I've built a simple example based on a form without any component and called MouseOne in the VCL version and QMouseOne in the CLX version. The first feature of this program is that it displays in the Caption of the form the current position of the mouse procedure TMouseForm.FormMouseMove Sender TObject Shift TShiftState display the position of the mouse in the caption Caption Format 'Mouse in x d, y d', X, Y You can use this simple...
The Packets and the Cache
The ClientDataSet component reads data in packets made of the number of records indicated by the PacketRecords property. The default value of this property is -1, which means that the provider will pull all the records at once this is reasonable only for a small dataset . Alternatively, you can set this value to zero to ask the server for only the field descriptors and no actual data or use any positive value to specify an actual number. If you retrieve only a partial dataset, as you browse...
Handling Database Errors
Another important element of database programming is handling database errors in custom ways. Of course, you can let Delphi show an exception message each time a database error occurs, but you might want to try to correct the errors or simply show more details. There are basically three approaches you can use to handle database-related errors You can wrap a try except block around risky database operations, such as a call to the Open method of a Query or to the Post method of a dataset. This is...
Looking at Source Code Files
I've just listed some files related to the development of a Delphi application, but I want to spend a little time covering their actual format. The fundamental Delphi files are Pascal source code files, which are plain ASCII text files. The bold, italic, and colored text you see in the editor depends on syntax highlighting, but it isn't saved with the file. It is worth noting that there is one single file for the whole code of the form, not just small code fragments. In the listings in this...
Dynamic Web Pages
When you browse a Web site, you generally download static pages HTML-format text files from the Web server to your client computer. As a Web developer, you can create these pages manually, but for most businesses, it makes more sense to build the static pages from information in a database of some type a SQL server, a series of files, and so on . Using this approach, you're basically generating a snapshot of the data in HTML format, which is quite reasonable if the data isn't subject to...
Overriding Message Handlers The Numeric Edit Box
To customize an edit box component to restrict the input it will accept, all you need to do is handle the wm_Char Windows messages that occur when the user presses any but a few specific keys namely, the numeric characters . One way to respond to a message for a given window whether it's a form or a component is to create a new message-response method that you declare using the message keyword. Delphi's message-handling system makes sure that your message-response method has a chance to The...
The ToDo List
Another feature added in Delphi 5 was the to-do list. This is a list of tasks you still have to do to complete a project, a collection of notes for the programmer or programmers, as this tool can be very handy in a team . While the idea is not new, the key concept of the to-do list in Delphi is that it works as a two-way tool. In fact, you can add or modify to-do items by adding special TODO comments to the source code of any file of a project you'll then see the corresponding entries in the...
Protected Fields and Encapsulation
The code of the GetText method of the TNewDate class compiles only if it is written in the same unit as the TDate class. In fact, it accesses the fDate private field of the ancestor class. If we want to place the descendant class in a new unit, we must either declare the fDate field as protected or add a protected access method in the ancestor class to read the value of the private field. Many developers believe that the first solution is always the best, because declaring most of the fields as...
The Structure of CLX
This is the traditional subdivision of VCL, which is very common for Delphi programmers. Even with the introduction of CLX and some new naming schemes, the traditional names will probably survive and merge into Delphi programmers' jargon. Borland now refers to different portions of the CLX library using one terminology under Linux and a slightly different and less clear naming structure in Delphi. This is the subdivision of the Linux-compatible library BaseCLX forms the core of the class...
Additional and External Delphi Tools
Besides the IDE, when you install Delphi you get other, external tools. Some of them, such as the Database Desktop, the Package Collection Editor PCE.exe , and the Image Editor ImagEdit.exe , are available from Tools menu of the IDE. In addition, the Enterprise edition has a link to the SQL Monitor SqlMon.exe . Other tools that are not directly accessible from the IDE include many command-line tools you can find in the bin directory of Delphi. For example, there is a command-line Delphi...
Section I Initialization Opening and Closing
The first methods I'll examine are responsible for initializing the dataset, and for opening and closing the file stream we'll use to store the data. In addition to initializing the component's internal data, these methods are responsible for initializing and connecting the proper TFields objects to the dataset component. To make this work, all we need to do is to initialize the FieldsDef property with the definitions of the fields for our dataset, then call a few standard methods to generate...
OLE DB Providers
OLE DB providers enable access to a source of data. They are ADO's equivalent to the BDE's drivers. However, although the BDE's Driver SDK has been available for many years, there are no third-party BDE drivers. This is not the case for OLE DB providers. MDAC includes many providers that I'll discuss, but many more are available from Microsoft and, more prolifically, the third-party market. It is no longer possible to reliably list all available OLE DB providers, because the list is so large...
Using Sessions
To underline the importance of this type of support, I've built a WebSnap application with a single page showing both the total number of hits and the total number of hits for each session. The program has a SessionService component with default values for its MaxSessions and DefaultTimeout properties. For every new request, the program increases both an nHits private field of the page module and the SessionHits value of the current session procedure TObject const PageName String var Handled...
InterBase Express IBX
Delphi includes components for native access to Borland's own open-source and free InterBase server. Unlike BDE, ADO, and dbExpress, this is not a server-independent database engine, but a technology for accessing a specific database server. If you plan using only InterBase as your back-end RDBMS, using a specific set of components can give you more control of the server, provide the best performance, and allow you also to configure and maintain the server from within a custom client...
The Status of a Dataset
When you operate on a dataset in Delphi, you can work in different states, indicated by a specific State property, which can assume several different values dsBrowse indicates that the dataset is in normal browse mode, used to look at the data and scan the records. dsEdit indicates that the dataset is in edit mode. A dataset enters this state when the program calls the Edit method or the DataSource has the AutoEdit property set to True, and the user starts editing a data-aware control, such as...












