Using a picture graphic or canvas

There are three kinds of classes in Delphi that deal with graphics A canvas represents a bitmapped drawing surface on a form, graphic control, printer, or bitmap. A canvas is always a property of something else, never a standalone class. A graphic represents a graphic image of the sort usually found in a file or resource, such as a bitmap, icon, or metafile. Delphi defines classes TBitmap, TIcon, and TMetafile, all descended from a generic TGraphic. You can also define your own graphic classes....

Design time

This chapter describes the steps for making the components you create available in the IDE. Making your components available at design time requires several steps Providing Help for your component Compiling components into packages Not all these steps apply to every component. For example, if you don't define any new properties or events, you don't need to provide Help for them. The only steps that are always necessary are registration and compilation. Once your components have been registered...

Example of adding silent video clips

Suppose you want to display an animated logo as the first screen that appears when your application starts. After the logo finishes playing the screen disappears. To run this example, create a new project and save the Unit1.pas file as Frmlogo.pas and save the Project1.dpr file as Logo.dpr. Then 1 Double-click the animate icon from the Win32 page of the Component palette. 2 Using the Object Inspector, set its Name property to Logo1. 3 Select its FileName property, click the ellipsis ( ) button,...

Operating systems versions

When using operating system APIs or accessing areas of the operating system from an application, there is the possibility that the function, operation, or area may not be available on computers with different operating system versions. To account for this possibility, you have a few options Specify in the application's system requirements the versions of the operating system on which the application can run. It is the user's responsibility to install and use the application only under...

Starting a transaction

When you start a transaction, all subsequent statements that read from or write to the database occur in the context of that transaction, until the transaction is explicitly terminated or (in the case of overlapping transactions) until another transaction is started. Each statement is considered part of a group. Changes must be successfully committed to the database, or every change made in the group must be undone. While the transaction is in process, your view of the data in database tables...

Applying cached updates using a database

To apply cached updates to one or more datasets in the context of a database connection, call the database component's ApplyUpdates method. The following code applies updates to the CustomersQuery dataset in response to a button click event procedure TForm1.ApplyButtonClick(Sender TObject) begin for local databases such as Paradox, dBASE, and FoxPro set Translsolation to DirtyRead if not (Databasel.IsSQLBased) and not (Databasel.Translsolation tiDirtyRead) then Databasel.Translsolation...

Adding component editors

Component editors determine what happens when the component is double-clicked in the designer and add commands to the context menu that appears when the component is right-clicked. They can also copy your component to the Windows clipboard in custom formats. If you do not give your components a component editor, Delphi uses the default component editor. The default component editor is implemented by the class TDefaultEditor. TDefaultEditor does not add any new items to a component's context...

Dispatching messages

Note This information is applicable when writing VCL components only. When an application creates a window, it registers a window procedure with the Windows kernel. The window procedure is the routine that handles messages for the window. Traditionally, the window procedure contains a huge case statement with entries for each message the window has to handle. Keep in mind that window in this sense means just about anything on the screen each window, each control, and so on. Every time you...

Waiting for a task to be completed

Sometimes, you need to wait for a thread to finish some operation rather than waiting for a particular thread to complete execution. To do this, use an event object. Event objects (TEvent) should be created with global scope so that they can act like signals that are visible to all threads. When a thread completes an operation that other threads depend on, it calls TEvent.SetEvent. SetEvent turns on the signal, so any other thread that checks will know that the operation has completed. To turn...

Working with XML nodes

Once an XML document has been parsed by a DOM implementation, the data it represents is available as a hierarchy of nodes. Each node corresponds to a tagged element in the document. For example, given the following XML Component palette< xml version 1.0 standalone 'yes' > < DOCTYPE stockholdings SYSTEM sth.dtd> < StockList> < name> Inprise (Borland)< name> < price> 15.375< price> < symbol> INPR< symbol> < shares> 100< shares> < Stock> < Stock...

Directory structure on Linux

Any file or device can be mounted anywhere on the file system. Note Linux pathnames use forward slashes as opposed to Windows use of backslashes. The initial slash stands for the root directory. Following are some commonly used directories in Linux. Table 10.8 Common Linux directories The root or top directory of the entire Linux file system root The root file system the Superuser's home directory home username Files owned by the user where username is the...

Overview of ActiveX control creation

Creating ActiveX controls using Delphi is very similar to creating ordinary controls or forms. This differs markedly from creating other COM objects, where you first define the object's interface and then complete the implementation. To create ActiveX controls (other than Active Forms), you reverse this process, starting with the implementation of a VCL control, and then generating the interface and type library once the control is written. When creating Active Forms, the interface and type...

Using TSQLMonitor to monitor SQL commands

TSQLConnection uses a companion component, TSQLMonitor, to intercept these messages and save them in a string list. TSQLMonitor works much like the SQL monitor utility that you can use with the BDE, except that it monitors only those commands involving a single TSQLConnection component rather than all commands managed by dbExpress. 1 Add a TSQLMonitor component to the form or data module containing the TSQLConnection component whose SQL commands you want to monitor. 2 Set its SQLConnection...

Limiting records with ranges

You can temporarily view and edit a subset of data for any dataset by using filters (see Displaying and editing a subset of data using filters on page 18-12). Some table-type datasets support an additional way to access a subset of available records, called ranges. Ranges only apply to TTable and to client datasets. Despite their similarities, ranges and filters have different uses. The following topics discuss the differences between ranges and filters and how to use ranges. Understanding the...

Defining a COM objects interface

When you use a wizard to create a COM object, the wizard automatically generates a type library (unless you specify otherwise in the COM object wizard). The type library provides a way for host applications to find out what the object can do. It also lets you define your object's interface using the Type Library editor. The interfaces you define in the Type Library editor define what properties, methods, and events your object exposes to clients. Note If you selected an existing interface in...

Writing portable code

If you are writing cross-platform applications that are meant to run on Windows and Linux, you can write code that compiles under different conditions. Using conditional compilation, you can maintain your Windows coding, yet also make allowances for Linux operating system differences. To create applications that are easily portable between Windows and Linux, remember to reduce or isolate calls to platform-specific (Win32 or Linux) APIs use CLX methods instead. eliminate Windows messaging...

Calling invokable interfaces

To call an invokable interface, your client application must include any units that define the invokable interfaces and any remotable classes that implement complex types. If the server is written in Delphi, these should be the same units that the server application uses to define and register these interfaces and classes. It is best to use the same unit, because when you register an invokable interface or remotable class, it is given a uniform resource identifier (URI) that uniquely identifies...

Implementing COM objects with wizards

Delphi makes it easier to write COM server applications by providing wizards that handle many of the details involved. Delphi provides separate wizards to create the following An Active Server Object (for embedding in an Active Server page) The wizards handle many of the tasks involved in creating each type of COM object. They provide the required COM interfaces for each type of object. As shown in Figure 33.6, with a simple COM object, the wizard implements the one required COM interface,...

Generating WSDL documents for a Web Service application

If you include the same units that define and register your invokable interfaces, the classes that represent complex type information, and your remotable exceptions in a Delphi client application, it can generate calls to use your Web Service. All you need to do is supply the URL where you install your Web Service application. However, you may want to make your Web Service available to a wider range of clients. For example, you may have clients that are not written in Delphi. If you are...

HTTP server activity

The client server nature of Web browsers is deceptively simple. To most users, retrieving information on the World Wide Web is a simple procedure click on a link, and the information appears on the screen. More knowledgeable users have some understanding of the nature of HTML syntax and the client server nature of the protocols used. This is usually sufficient for the production of simple, page-oriented Web site content. Authors of more complex Web pages have a wide variety of options to...

Using a single navigator for multiple datasets

As with other data-aware controls, a navigator's DataSource property specifies the data source that links the control to a dataset. By changing a navigator's DataSource property at runtime, a single navigator can provide record navigation and manipulation for multiple datasets. Suppose a form contains two edit controls linked to the CustomersTable and OrdersTable datasets through the CustomersSource and OrdersSource data sources respectively. When a user enters the edit control connected to...

Creating masterdetail relationships

Table-type datasets can be linked into master detail relationships. When you set up a master detail relationship, you link two datasets so that all the records of one (the detail) always correspond to the single current record in the other (the master). Table-type datasets support master detail relationships in two very distinct ways All table-type datasets can act as the detail of another dataset by linking cursors. This process is described in Making the table a detail of another dataset...

Environmental differences between Windows and Linux

Currently, cross-platform means an application that can run virtually unchanged on both the Windows and Linux operating systems. The following table lists some of the differences between Linux and the Windows operating environments. Table 10.7 Differences in the Linux and Windows operating environments File name case sensitivity Line ending characters In Linux, a capital letter is not the same as a lowercase letter. The file Test.txt is not the same file as test.txt. You need to pay close...

Keeping track of which drawing tool to use

A graphics program needs to keep track of what kind of drawing tool (such as a line, rectangle, ellipse, or rounded rectangle) a user might want to use at any given time. You could assign numbers to each kind of tool, but then you would have to remember what each number stands for. You can do that more easily by assigning mnemonic constant names to each number, but your code won't be able to distinguish which numbers are in the proper range and of the right type. Fortunately, Object Pascal...

Communicating with the Help Manager

ICustomHelpViewer provides four functions that can be used to communicate system The Help Manager calls through these functions in the following circumstances String is called when the Help Manager wants to know the name of the viewer (for example, if the application is asked to display a list of all registered viewers). This information is returned via a string, and is required to be logically static (that is, it cannot change during the operation of the application). Multibyte character sets...

Making a control a dockable child

Note Drag and dock properties are available in the VCL but not CLX. 1 Set its DragKind property to dkDock. When DragKind is dkDock, dragging the control moves the control to a new docking site or undocks the control so that it becomes a floating window. When DragKind is dkDrag (the default), dragging the control starts a drag-and-drop operation which must be implemented using the OnDragOver, OnEndDrag, and OnDragDrop events. 2 Set its DragMode to dmAutomatic. When DragMode is dmAutomatic,...

Using default formatting for numeric date and time fields

Delphi provides built-in display and edit format routines and intelligent default formatting for TFloatField, TCurrencyField, TBCDField, TFMTBCDField, TIntegerField, TSmallIntField, TWordField, TDateField, TDateTimeField, and TTimeField, and TSQLTimeStampField components. To use these routines, you need do nothing. Persistent field components Default formatting is performed by the following routines Table 19.4 Field component formatting routines FormatFloat TFloatField, TCurrencyField...

Implementing interfaces across the hierarchy

Using interfaces offers a design approach to separating the way a class is used from the way it is implemented. Two classes can implement the same interface without requiring that they descend from the same base class. This polymorphic invocation of the same methods on unrelated objects is possible as long as the objects implement the same interface. For example, consider the interface, IPaint interface procedure Paint-end TSquare class(TPolygonObject, IPaint) TCircle class(TCustomShape,...

Designing database applications

Using databases 14-1 Types of databases 14-2 Database security 14-3 Referential integrity, stored procedures, and triggers 14-5 Database architecture 14-5 General structure 14-6 The user interface form 14-6 Using a dedicated file on disk 14-9 Connecting to another dataset 14-10 Connecting a client dataset to another dataset in the same application 14-11 Using a multi-tiered architecture. . . . 14-12 Combining approaches 14-14 Designing the user interface 14-15 Analyzing data 14-15 Writing...

Creating Internet applications

About Web Broker and WebSnap 27-1 Terminology and standards 27-2 Parts of a Uniform Resource Locator 27-3 HTTP request header information 27-4 HTTP server activity 27-4 Composing client requests 27-4 Serving client requests 27-5 Responding to client requests 27-5 Types of Web server applications 27-6 Debugging server applications 27-7 Using the Web Application Debugger . . . . 27-7 Launching your application with the Web Application Debugger 27-7 Converting your application to another type of...

Integrated development environment

When you start Delphi, you are immediately placed within the integrated development environment, also called the IDE. This environment provides all the tools you need to design, develop, test, debug, and deploy applications. Delphi's development environment includes a visual form designer, Object Inspector, Object TreeView, Component palette, Project Manager, source code editor, and debugger among other tools. Some tools may not be included in all versions of the product. You can move freely...

Creating projects

All of Delphi's application development revolves around projects. When you create an application in Delphi you are creating a project. A project is a collection of files that make up an application. Some of these files are created at design time. Others are generated automatically when you compile the project source code. You can view the contents of a project in a project management tool called the Project Manager. The Project Manager lists, in a hierarchical view, the unit names, the forms...

Creating SQL statements for update components

To update a record in an associated dataset, an update object uses one of three SQL statements. Each update object can only update a single table, so the object's update statements must each reference the same base table. The three SQL statements delete, insert, and modify records cached for update. You must provide these statements as update object's DeleteSQL, InsertSQL, and ModifySQL properties. You can provide these values at design time or at runtime. For example, the following code...

Handling exceptions in the thread function

The Execute method must catch all exceptions that occur in the thread. If you fail to catch an exception in your thread function, your application can cause access violations. This may not be obvious when you are developing your application, because the IDE catches the exception, but when you run your application outside of the debugger, the exception will cause a runtime error and the application will stop running. To catch the exceptions that occur inside your thread function, add a try...

Retrieving information about a session

You can retrieve information about a session and its database components by using a session's informational methods. For example, one method retrieves the names of all aliases known to the session, and another method retrieves the names of tables associated with a specific database component used by the session. Table 20.4 summarizes the informational methods to a session component Table 20.4 Database-related informational methods for session components GetDriverNames GetDriverParams...

Working with multimedia

Delphi allows you to add multimedia components to your applications. To do this, you can use either the TAnimate component on the Win32 page or the TMediaPlayer component on the System page of the Component palette. Use the animate component when you want to add silent video clips to your application. Use the media player component when you want to add audio and or video clips to an application. For more information on the TAnimate and TMediaPlayer components, see the VCL on-line help. The...

Creating a property page for an ActiveX control

A property page is a dialog box similar to the Delphi Object Inspector in which users can change the properties of an ActiveX control. A property page dialog allows you to group many properties for a control together to be edited at once. Or, you can provide a dialog box for more complex properties. Typically, users access the property page by right-clicking the ActiveX control and choosing Properties. The process of creating a property page is similar to creating a form, you 2 Add controls to...

Setting up a transaction object on the client side

A client-based application can control transaction context through the ITransactionContextEx interface. The following code example shows how a client application uses CreateTransactionContextEx to create the transaction context. This method returns an interface to this object. This example wraps the call to the transaction context in a call to OleCheck which is necessary because the methods of IObjectContext are exposed by Windows directly and are therefore not declared as safecall. procedure...

Customizing the ActiveX controls interface

The ActiveX Control and ActiveForm wizards generate a default interface for the ActiveX wrapper class. This default interface simply exposes the properties, methods, and events of the original VCL control or form, with the following exceptions Data-aware properties do not appear. Because ActiveX controls have a different mechanism for making controls data-aware than VCL controls, the wizards do not convert properties related to data. See Enabling simple data binding with the type library on...

Managing database connections

You can use a session component to manage the database connections within it. The session component includes properties and methods you can use to Close database connections. Close and free all inactive temporary database connections. Locate specific database connections. Iterate through all open database connections. To open a database connection within a session, call the OpenDatabase method. OpenDatabase takes one parameter, the name of the database to open. This name is a bDe alias or the...

Writing Webbased client applications

If you want to create Web-based clients for your multi-tiered database application, you must replace the client tier with a special Web application that acts simultaneously as a client to an application server and as a Web server application that is installed with a Web server on the same machine. This architecture is illustrated in Figure 25.1. Figure 25.1 Web-based multi-tiered database application Figure 25.1 Web-based multi-tiered database application There are two approaches that you can...

Deploying database applications

Applications that access databases involve special installation considerations beyond copying the application's executable file onto the host computer. Database access is most often handled by a separate database engine, the files of which cannot be linked into the application's executable file. The data files, when not created beforehand, must be made available to the application. Multi-tier database applications require even more specialized handling on installation, because the files that...

Using Indexes to search for records

You can search against any dataset using the Locate and Lookup methods of TDataSet. However, by explicitly using indexes, some table-type datasets can improve over the searching performance provided by the Locate and Lookup methods. ADO datasets all support the Seek method, which moves to a record based on a set of field values for fields in the current index. Seek lets you specify where to move the cursor relative to the first or last matching record. TTable and all types of client dataset...

Creating and managing offscreen bitmaps

When creating complex graphic images, you should avoid drawing them directly on a canvas that appears onscreen. Instead of drawing on the canvas for a form or control, you can construct a bitmap object, draw on its canvas, and then copy its completed image to the onscreen canvas. The most common use of an off-screen bitmap is in the Paint method of a graphic control. As with any temporary object, the bitmap should be protected with a try finally block TFancyControl class(TGraphicControl)...

Accessing data in a reference field

You can access the data in a reference field in the same way you access a nested dataset 1 Create a persistent TDataSetField object by invoking the Fields editor for the parent dataset. 2 Create a dataset to represent the value of that dataset field. 3 Set that DataSetField property of the dataset created in step 2 to the persistent dataset field you created in step 1. If the reference is assigned, the reference dataset will contain a single record with the referenced data. If the reference is...

Associating a data control with a dataset

Data controls connect to datasets by using a data source. A data source component (TDataSource) acts as a conduit between the control and a dataset containing data. Each data-aware control must be associated with a data source component to have data to display and manipulate. Similarly, all datasets must be associated with a data source component in order for their data to be displayed and manipulated in data-aware controls on a form. Note Data source components are also required for linking...

Dynamically loading packages

To load a package at runtime, call the LoadPackage function. LoadPackage loads the package, checks for duplicate units, and calls the initialization blocks of all units contained in the package. For example, the following code could be executed when a file is chosen in a file-selection dialog. with OpenDialogl do if Execute then with PackageList.Items do AddObject(FileName, Pointer(LoadPackage(FileName))) To unload a package dynamically, call UnloadPackage. Be careful to destroy any instances...

Overview of component creation

VCL and CLX 40-1 Components and classes 40-2 How do you create components 40-2 Modifying existing controls 40-3 Creating windowed controls 40-3 Creating graphic controls 40-4 Subclassing Windows controls 40-4 Creating nonvisual components 40-5 What goes into a component 40-5 Removing dependencies 40-5 Properties, methods, and events 40-6 Graphics encapsulation 40-7 Registration 40-8 Creating a new component 40-8 Using the Component wizard 40-9 Creating a component manually 40-11 Creating a unit...

Using object fields

Object fields are fields that represent a composite of other, simpler data types. These include ADT (Abstract Data Type) fields, Array fields, DataSet fields, and Reference fields. All of these field types either contain or reference child fields or other data sets. ADT fields and array fields are fields that contain child fields. The child fields of an ADT field can be any scalar or object type (that is, any other field type). These child fields may differ in type from each other. An array...

Using nested detail tables

A nested table is a detail dataset that is the value of a single dataset field in another (master) dataset. For datasets that represent server data, a nested detail dataset can only be used for a dataset field on the server. TClientDataSet components do not represent server data, but they can also contain dataset fields if you create a dataset for them that contains nested details, or if they receive data from a provider that is linked to the master table of a master detail relationship. Note...

Working with frames

A frame (TFrame), like a form, is a container for other components. It uses the same ownership mechanism as forms for automatic instantiation and destruction of the components on it, and the same parent-child relationships for synchronization of component properties. In some ways, however, a frame is more like a customized component than a form. Frames can be saved on the component palette for easy reuse, and they can be nested within forms, other frames, or other container objects. After a...

Working with BDE aliases

Each database component associated with a session has a BDE alias (although optionally a fully-qualified path name may be substituted for an alias when accessing Paradox and dBASE tables). A session can create, modify, and delete aliases during its lifetime. The AddAlias method creates a new BDE alias for an SQL database server. AddAlias takes three parameters a string containing a name for the alias, a string that specifies the SQL Links driver to use, and a string list populated with...

Canceling changes

An application can undo changes made to the current record at any time, if it has not yet directly or indirectly called Post. For example, if a dataset is in dsEdit mode, and a user has changed the data in one or more fields, the application can return the record back to its original values by calling the Cancel method for the dataset. A call to Cancel always returns a dataset to dsBrowse state. If the dataset was in dsEdit or dsInsert mode when your application called Cancel, it receives...

Defining your own messages

A number of the standard components define messages for internal use. The most common reasons for defining messages are broadcasting information not covered by standard messages and notification of state changes. You can define your own messages in both VCL and CLX. Defining a message is a two-step process. The steps are 1 Declaring a message identifier. 2 Declaring a message-record type. A message identifier is an integer-sized constant. Windows reserves the messages below 1,024 for its own...

Using the Safe Ref method

An object can use the SafeRef function to obtain a reference to itself that is safe to pass outside its context. The unit that defines the SafeRef function is Mtx. A reference to the interface ID (RIID) of the interface that the current object wants to pass to another object or client. A reference to the current object's IUnknown interface. SafeRef returns a pointer to the interface specified in the RIID parameter that is safe to pass outside the current object's context. It returns nil if the...

Using TIni File VCL only

The INI file format is still popular, many of the Delphi configuration files (such as the DSK Desktop settings file) are in this format. Because this file format was and is prevalent, VCL provides a class to make reading and writing these files very easy. TIniFile is not available for cross-platform programming. When you instantiate the TIniFile object, you pass as a parameter to the constructor the name of the INI file. If the file does not exist, it is automatically created. You are then free...

Specifying the table type for local tables

If an application accesses Paradox, dBASE, FoxPro, or comma-delimited ASCII text tables, then the BDE uses the TableType property to determine the table's type (its expected structure). TableType is not used when TTable represents an SQL-based table on a database server. By default TableType is set to ttDefault. When TableType is ttDefault, the BDE determines a table's type from its filename extension. Table 20.1 summarizes the file extensions recognized by the BDE and the assumptions it makes...

TInterfaced Object

Delphi defines a simple class, TInterfacedObject, that serves as a convenient base because it implements the methods of IInterface. TInterfacedObject class is declared in the System unit as follows TInterfacedObject class (TObject, IInterface) protected function QueryInterface(const IID TGUID out Obj) HResult stdcall function _AddRef Integer stdcall function _Release Integer stdcall public procedure AfterConstruction override procedure BeforeDestruction override class function NewInstance...

Resizing the cells

VCL When a user or application changes the size of a window or control, Windows sends a message called WM_SIZE to the affected window or control so it can adjust any settings needed to later paint its image in the new size. Your VCL component can respond to that message by altering the size of the cells so they all fit inside the boundaries of the control. To respond to the WM_SIZE message, you will add a message-handling method to the component. Creating a message-handling method is described...

Renaming a file

To change a filename, simply use the RenameFile function function RenameFile(const OldFileName, NewFileName string) Boolean which changes a filename, identified by OldFileName, to the name specified by NewFileName. If the operation succeeds, RenameFile returns True. If it cannot rename the file, for example, if a file called NewFileName already exists, it returns False. For example if not RenameFile('OLDNAME.TXT','NEWNAME.TXT') then ErrorMsg('Error renaming file ') You cannot rename (move) a...

Handling the OnPopup event

You may want to adjust pop-up menu items before displaying the menu, just as you may want to enable or disable items on a regular menu. With a regular menu, you can handle the OnClick event for the item at the top of the menu, as described in Disabling menu items on page 7-10. With a pop-up menu, however, there is no top-level menu bar, so to prepare the popup menu commands, you handle the event in the menu component itself. The pop-up menu component provides an event just for this purpose,...

Creating an ActiveX control

An ActiveX control is a software component that integrates into and extends the functionality of any host application that supports ActiveX controls, such as C++Builder, Delphi, Visual Basic, Internet Explorer, and (given a plug-in) Netscape Navigator. ActiveX controls implement a particular set of interfaces that allow this integration. For example, Delphi comes with several ActiveX controls, including charting, spreadsheet, and graphics controls. You can add these controls to the component...

Deploying CLX applications

If you are writing cross-platform applications that will be deployed on both Windows and Linux, you need to compile and deploy the applications on both platforms. The steps for deploying CLX applications are the same as those for general applications. For information on deploying general applications, see Deploying general applications on page 13-1. For information on installing database CLX applications, see Deploying database applications on page 13-6. Note When deploying CLX applications on...

Adding a new index

There are three ways to add indexes to a client dataset To create a temporary index at runtime that sorts the records in the client dataset, you can use the IndexFieldNames property. Specify field names, separated by semicolons. Ordering of field names in the list determines their order in the index. This is the least powerful method of adding indexes. You can't specify a descending or case-insensitive index, and the resulting indexes do not support grouping. These indexes do not persist when...

Creating persistent fields

Persistent field components created with the Fields editor provide efficient, readable, and type-safe programmatic access to underlying data. Using persistent field components guarantees that each time your application runs, it always uses and displays the same columns, in the same order even if the physical structure of the underlying database has changed. Data-aware components and program code that rely on specific fields always work as expected. If a column on which a persistent field...

Adding actions to the dispatcher

Open the action editor from the Object Inspector by clicking the ellipsis on the Actions property of the dispatcher. Action items can be added to the dispatcher by clicking the Add button in the action editor. Add actions to the dispatcher to respond to different request methods or target URIs. You can set up your action items in a variety of ways. You can start with action items that preprocess requests, and end with a default action that checks whether the response is complete and either...

Disconnecting from a database server

There are two ways to disconnect a server using a connection component Set the Connected property to False. Call the Close method. Calling Close sets Connected to False. When Connected is set to False, the connection component generates a BeforeDisconnect event, where you can perform any cleanup before the connection closes. For example, you can use this event to cache information about all open datasets before they are closed. After the BeforeConnect event, the connection component closes all...

Creating multitiered applications

This chapter describes how to create a multi-tiered, client server database application. A multi-tiered client server application is partitioned into logical units, called tiers, which run in conjunction on separate machines. Multi-tiered applications share data and communicate with one another over a local-area network or even over the Internet. They provide many benefits, such as centralized business logic and thin client applications. In its simplest form, sometimes called the three-tiered...

Using a client dataset to cache updates

By default, when you edit data in most datasets, every time you delete or post a record, the dataset generates a transaction, deletes or writes that record to the database server, and commits the transaction. If there is a problem writing changes to the database, your application is notified immediately the dataset raises an exception when you post the record. If your dataset uses a remote database server, this approach can degrade performance due to network traffic between your application and...

Reraising the exception

Sometimes when you handle an exception locally, you actually want to augment the handling in the enclosing block, rather than replacing it. Of course, when your local handler finishes its handling, it destroys the exception instance, so the enclosing block's handler never gets to act. You can, however, prevent the handler from destroying the exception, giving the enclosing handler a chance to respond. Example When an exception occurs, you might want to display a message to the user or record...

Programming a calculated field

After you define a calculated field, you must write code to calculate its value. Otherwise, it always has a null value. Code for a calculated field is placed in the OnCalcFields event for its dataset. To program a value for a calculated field 1 Select the dataset component from the Object Inspector drop-down list. 2 Choose the Object Inspector Events page. 3 Double-click the OnCalcFields property to bring up or create a CalcFields procedure for the dataset component. 4 Write the code that sets...

Specifying a batch move mode

The Mode property specifies the operation a batch move component performs batAppend Append records to the destination table. batUpdate Update records in the destination table with matching records from the source table. Updating is based on the current index of the destination table. batAppendUpdate If a matching record exists in the destination table, update it. Otherwise, append records to the destination table. batCopy Create the destination table based on the structure of the source table....

Enabling Help in applications

Both the VCL and CLX support displaying Help from applications using an object-based mechanism that allows Help requests to be passed on to one of multiple external Help viewers. To support this, an application must include a class that implements the ICustomHelpViewer interface and, optionally, one of several interfaces descended from it , and registers itself with the global Help Manager. The VCL provides to all applications an instance of TWinHelpViewer, which implements all of these...

Creating resource DLLs

Isolating resources simplifies the translation process. The next level of resource separation is the creation of a resource DLL. A resource DLL contains all the resources and only the resources for a program. Resource DLLs allow you to create a program that supports many translations simply by swapping the resource DLL. Use the Resource DLL wizard to create a resource DLL for your program. The Resource DLL wizard requires an open, saved, compiled project. It will create an RC file that contains...

Implementing unary operations

To allow the custom variant type to work with standard unary operators -, not , you must override the UnaryOp method. UnaryOp has two parameters the value of the operand and the operator. Implement this method to perform the operation and return the result using the same variable that contained the operand. For example, the following UnaryOp method comes from the TComplexVariantType defined in the VarCmplx unit procedure TComplexVariantType.UnaryOp var Right TVarData const Operator TVarOp begin...

What CLX does differently

All of the variant safe array code that was in System is in two new units The operating system dependent code is now isolated in VarUtils.pas, and it also contains generic versions of everything needed by Variants.pas. If you are converting a VCL application that included Windows calls to a CLX application, you need to replace these calls to calls into VarUtils.pas. If you want to use variants, you must include the Variants unit to your uses clause. VarIsEmpty does a simple test against...

Loading and saving custom variant values

By default, when the custom variant is assigned as the value of a published property, it is typecast to a string when that property is saved to a form file, and converted back from a string when the property is read from a form file. You can, however, provide your own mechanism for loading and saving custom variant values in a more natural representation. To do so, the TCustomVariantType descendant must implement the IVarStreamable interface from Classes.pas. IVarStreamable defines two methods,...

Customizing decision graphs

The decision graph component, TDecisionGraph, displays fields from the decision source TDecisionSource as a dynamic graph that changes when data dimensions are opened, closed, dragged and dropped, or rearranged with the decision pivot TDecisionPivot . You can change the type, colors, marker types for line graphs, and many other properties of decision graphs. 1 Right-click it and choose Edit Chart. The Chart Editing dialog box appears. 2 Use the Chart page of the Chart Editing dialog box to view...

Controlling readwrite access to local tables

Like any table-type dataset, TTable lets you control read and write access by your application using the ReadOnly property. In addition, for Paradox, dBASE, and FoxPro tables, TTable can let you control read and write access to tables by other applications. The Exclusive property controls whether your application gains sole read write access to a Paradox, dBASE, or FoxPro table. To gain sole read write access for these table types, set the table component's Exclusive property to True before...

Drawing lines and polylines

A canvas can draw straight lines and polylines. A straight line is just a line of pixels connecting two points. A polyline is a series of straight lines, connected end-to-end. The canvas draws all lines using its pen. To draw a straight line on a canvas, use the LineTo method of the canvas. LineTo draws a line from the current pen position to the point you specify and makes the endpoint of the line the current position. The canvas draws the line using its pen. For example, the following method...

Adding new records

A dataset must be in dsInsert mode before an application can add new records. In code, you can use the Insert or Append methods to put a dataset into dsInsert mode if the read-only CanModify property for the dataset is True. When a dataset transitions to dsInsert mode, it first receives a BeforeInsert event. After the transition to insert mode is successfully completed, the dataset receives first an OnNewRecord event hand then an AfterInsert event. You can use these events, for example, to...

Editing records

A dataset must be in dsEdit mode before an application can modify records. In your code you can use the Edit method to put a dataset into dsEdit mode if the read-only CanModify property for the dataset is True. When a dataset transitions to dsEdit mode, it first receives a BeforeEdit event. After the transition to edit mode is successfully completed, the dataset receives an AfterEdit event. Typically, these events are used for updating the user interface to indicate the current state of the...

Porting your application

If you are porting an application that you want to run on both Windows and Linux, you need to modify your code or use IFDEFs to indicate sections of the code that apply specifically to Windows or Linux. Follow these general steps to port your VCL application to CLX 1 Open the project containing the application you want to change in Delphi. 2 Copy .dfm files to .xfm files of the same name for example, rename unitl.dfm to unitl.xfm . Rename or IFDEF the reference to the .dfm file in the unit file...

Displaying ADT and array fields

Sometimes the fields of the grid's dataset do not represent simple values such as text, graphics, numerical values, and so on. Some database servers allow fields that are a composite of simpler data types, such as ADT fields or array fields. There are two ways a grid can display composite fields It can flatten out the field so that each of the simpler types that make up the field appears as a separate field in the dataset. When a composite field is flattened out, its constituents appear as...

Using Object Pascal or IDL syntax

The Text page of the Type Library editor displays your type information in one of two ways Using an extension of Object Pascal syntax. Note When working on a CORBA object, you use neither of these on the text page. Instead, you must use the CORBA IDL. You can select which language you want to use by changing the setting in the Environment Options dialog. Choose Tools Environment Options, and specify either Pascal or IDL as the Language on the Type Library page of the dialog. Note The choice of...

Specifying aggregates

To specify that you want to calculate summaries over the records in a client dataset, use the Aggregates property. Aggregates is a collection of aggregate specifications TAggregate . You can add aggregate specifications to your client dataset using the Collection Editor at design time, or using the Add method of Aggregates at runtime. If you want to create field components for the aggregates, create persistent fields for the aggregated values in the Fields Editor. Note When you create...

Storing and loading unpublished properties

By default, only published properties are loaded and saved with a component. However, it is possible to load and save unpublished properties. This allows you to have persistent properties that do not appear in the Object Inspector. It also allows components to store and load property values that Delphi does not know how to read or write because the value of the property is too complex. For example, the TStrings object can't rely on Delphi's automatic behavior to store and load the strings it...

Deploying type libraries

By default, when you have a type library that was created as part of an ActiveX or Automation server project, the type library is automatically linked into the .DLL, .OCX, or EXE as a resource. You can, however, deploy your application with the type library as a separate .TLB, as Delphi maintains the type library, if you prefer. Historically, type libraries for Automation applications were stored as a separate file with the .TLB extension. Now, typical Automation applications compile the type...

Displaying and editing a subset of data using filters

An application is frequently interested in only a subset of records from a dataset. For example, you may be interested in retrieving or viewing only those records for companies based in California in your customer database, or you may want to find a record that contains a particular set of field values. In each case, you can use filters to restrict an application's access to a subset of all records in the dataset. With unidirectional datasets, you can only limit the records in the dataset by...

Finding a file

There are three routines used for finding a file FindFirst, FindNext, and FindClose. FindFirst searches for the first instance of a filename with a given set of attributes in a specified directory. FindNext returns the next entry matching the name and attributes specified in a previous call to FindFirst. FindClose releases memory allocated by FindFirst. You should always use FindClose to terminates a FindFirst FindNext sequence. If you want to know if a file exists, a FileExists function...

Wide String

The WideChar type allows wide character strings to be represented as arrays of WideChars. Wide strings are strings composed of 16-bit Unicode characters. As with long strings, wide strings are dynamically allocated with a maximum length of two Gigabytes, but the practical limit is usually dependent on the amount of available memory. In Delphi, wide strings are not reference-counted. Every assignment of a wide string to a wide string var creates a copy of the string data. In Kylix, WideStrings...

Responding to mousedown messages

A MouseDown method is a protected method for a control's OnMouseDown event. The control itself calls MouseDown in response to a Windows mouse-down message. When you override the inherited MouseDown method, you can include code that provides other responses in addition to calling the OnMouseDown event. To override MouseDown, add the MouseDown method to the TDBCalendar class TDBCalendar class TSampleCalendar protected procedure MouseDown Button TButton, Shift TShiftState, X Integer, Y Integer...

Using component properties and events in a data module

Placing components in a data module centralizes their behavior for your entire application. For example, you can use the properties of dataset components, such as TClientDataSet, to control the data available to the data source components that use those datasets. Setting the ReadOnly property to True for a dataset prevents users from editing the data they see in a data-aware visual control on a form. You can also invoke the Fields editor for a dataset, by double-clicking on ClientDataSetl, to...

Events when establishing a connection

In addition to the BeforeConnect and AfterConnect events that are common to all database connection components, TADOConnection also generates an OnWillConnect and OnConnectComplete event when establishing a connection. These events occur after the BeforeConnect event. OnWillConnect occurs before the ADO provider establishes a connection. It lets you make last minute changes to the connection string, provide a user name and password if you are handling your own login support, force an...

Incremental fetching

By changing the PacketRecords property, you can specify that the client dataset fetches data in smaller chunks. PacketRecords specifies either how many records to fetch at a time, or the type of records to return. By default, PacketRecords is set to -1, which means that all available records are fetched at once, either when the client dataset is first opened, or when the application explicitly calls GetNextPacket. When PacketRecords is -1, then after the client dataset first fetches data, it...

Deploying an ActiveX control on the

Before the ActiveX controls that you create can be used by Web clients, they must be deployed on your Web server. Every time you make a change to the ActiveX control, you must recompile and redeploy it so that client applications can see the changes. Before you can deploy your ActiveX control, you must have a Web Server that will respond to client messages. To deploy your ActiveX control, use the following steps 1 Select Project I Web Deployment Options. 2 On the Project page, set the Target...

Editing package source files manually

Package source files, like project files, are generated by Delphi from information you supply. Like project files, they can also be edited manually. A package source file should be saved with the .dpk Delphi package extension to avoid confusion with other files containing Object Pascal source code. To open a package source file in the Code editor, 1 Open the package in the Package editor. 2 Right-click in the Package editor and select View Source. The package heading specifies the name for the...

Decision cube properties and events

The DimensionMap properties of TDecisionCube not only control which dimensions and summaries appear but also let you set date ranges and specify the maximum number of dimensions the decision cube may support. You can also indicate whether or not to display data during design. You can display names, categories values, subtotals, or data. Display of data at design time can be time consuming, depending on the data source. When you click the ellipsis next to DimensionMap in the Object Inspector,...

Using an XML document as the client of a provider

The TXMLTransformClient component acts as an adapter to let you use an XML document or set of documents as the client for an application server or simply as the client of a dataset to which it connects via a TDataSetProvider component . That is, TXMLTransform client lets you publish database data as an XML document and to make use of update requests insertions or deletions from an external application that supplies them in the form of XML documents. To specify the provider from which the...

Scroll boxes

Scroll boxes TScrollBox create scrolling areas within a form. Applications often need to display more information than will fit in a particular area. Some controls such as list boxes, memos, and forms themselves can automatically scroll their contents. Another use of scroll boxes is to create multiple scrolling areas views in a window. Views are common in commercial word-processor, spreadsheet, and project management applications. Scroll boxes give you the additional flexibility to define...