This is the only page you''ll get from this example.
Request: ' + RequestInfo.Document + '
' + 'Host: ' + RequestInfo.Host + '
' + 'Params: ' + RequestInfo.UnparsedParams + '
' + 'The headers of the request follow:
' + RequestInfo.RawHeaders.Text + '
This is a demo of the page produced by the <#appname> application on <#date>.
The prices in this catalog are valid until <#expiration days=21>.
Capital: <#capital>
Continent: <#continent>
Area: <#area>
Population: <#population>
Last updated on <#date>
HTML file produced by the program <#program>.
Page generated by Marco
';' + Query2.Fields [I].FieldName + ' | '#13'' + Query2.Fields [I].AsString + ' |
The time at this site is <#time>.
I also added code to the producer component's OnTag event handler to replace this tag with the current time. For the third page (the country page), modify the HTML to include tags for the various fields of the country table, as in: <% e = new Enumerator(Pages) s = '' c=0 for (; !e.atEnd(); e.moveNext()) { if (e.item().Published) { if (c > 0) s += ' | ' if (Page.Name != e.item().Name) s += '' + e.item().Title + '' else s += e.item().Title c++ } } This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . if (c>1) Response.Write(s) %> |
<% for (j=1;j<=5;j++) { %> | Column <%=j %> | <% } %>
---|---|
Line <%=i %> | <% for (j=1;j<=5;j++) { %>Value= <%=i*j %> | <% } %>
' + e.item().Title + ' | ')' + e.item().Title + ' | ') } } %>
This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks .
Figure 20.9: The Web Surface Designer for the inout page of the WSnap2 example, at design time
This script for the menu uses the Pages list and the Page and Application global scripting objects. WebSnap makes available a few other global objects, including EndUser and Session objects (in case you add the corresponding adapters to the application), the Modules object, and the Producer object, which allows access to the Producer component of the web page module. The script also has available the Response and Request objects of the web module.
Adapters In addition to these global objects, within a script you can access all the adapters available in the corresponding web page module. (Adapters in other modules, including shared web data modules, must be referenced by prefixing their name with the Modules object and the corresponding module.) Adapters allow you to pass information from your compiled Delphi code to the interpreted script, providing a scriptable interface to your Delphi application. Adapters contain fields that represent data and host actions that represent commands. The server-side scripts can access these values and issue these commands, passing specific parameters to them.
Adapter Fields For simple customizations, you can add new fields to specific adapters. For instance, in the WSnap2 example, I added a custom field to the application adapter. After selecting this component, you can either open its Fields editor (accessible via its shortcut menu) or work in the Object TreeView. After adding a new field (called AppHitCount in the example), you can assign a value to it in its OnGetValue event. Because you want to count the hits (or requests) on any page of the web application, you can also handle the OnBeforePageDispatch event of the global PageDispatcher component to increase the value of a local field, HitCount. Here is the code for the two methods: procedure Thome.PageDispatcherBeforeDispatchPage(Sender: TObject; const PageName: String; var Handled: Boolean); begin Inc (HitCount);
end; procedure Thome.AppHitCountGetValue(Sender: TObject; var Value: Variant); begin Value := HitCount;
end; Of course, you could use the page name to also count hits on each page (and you could add support for persistency, because the count is reset every time you run a new instance of the application). Now that you've added a custom field to an existing adapter (corresponding to the Application script object), you can access it from within any script, like this:
This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks .
Application hits since last activation: <%= Application.AppHitCount.Value %>
Session id: <#SessionID>
Session hits: <#SessionHits>
Session hits (via application): <%=Application.SessionHits.Value%>
Application hits: <%=Application.Hits.Value%>
This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . onclick='if (xml_ready) DataGrid1_Disp.first();'> ... // data grid heading
| | Figure 22.12: The result of an XSLT transformation generated (even at design time) by the XSLPageProducer This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register . it. Thanks component in the XslCust example Note The standard XSL template has been extended since Delphi 6, because the original versions didn't account for null fields omitted from the XML data packet. I presented several extensions to the original XSL code at the 2002 Borland Conference, and some of my suggestions have been incorporated in the template. This code generates an HTML table consisting of the expansion of field metadata and row data. The fields are used to generate the table heading, with a cell for each entry in a single row. The row data is used to fill in the other rows of the table. Taking the value of each attribute (select="@*") wouldn't be enough, because an attribute might be missing. For this reason, the list of fields and the current row are saved in two variables; then, for each field, the XSL code extracts the value of a row item having an attribute name (@*[name()=...) corresponding to the name of the current field stored in its attrname attribute (@attrname ). This code is far from simple, but it is a compact and portable way to examine different portions of an XML document at the same time. | Direct XSL Transformations with the DOM Using the XSLPageProducer can be handy, but generating multiple pages based on the same data just to handle different possible XSL styles with WebSnap isn't the best approach. I've built a plain CGI application called CdsXslt that can transform a ClientDataSet data packet into different types of HTML, depending on the name of the XSL file passed as a parameter. The advantage is that I can modify the existing XSL files and add new XSL files to the system without having to recompile the program. To obtain the XSL transformation, the program loads both the XML and the XSL files into two XMLDocument components called xmlDom and XslDom. Then it invokes the transformNode method of the XML document, passing the XSL document as a parameter and filling in a third XMLDocument component called HtmlDom: procedure TWebModule1.WebModule1WebActionItem1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var xslfile, xslfolder: string; attr: IDOMAttr; begin // open the client dataset and load its XML in a DOM ClientDataSet1.Open; XmlDom.Xml.Text := ClientDataSet1.XMLData; XmlDom.Active := True; // load the requested xsl file xslfile := Request.QueryFields.Values ['style']; if xslfile = '' then xslfile := 'customer.xsl'; xslfolder := ExtractFilePath (ParamStr (0)) + 'xsl\'; if FileExists (xslfolder + xslfile) then xslDom.LoadFromFile (xslfolder + xslfile) else raise Exception.Create('Missing file: ' + xslfolder + xslfile); XSLDom.Active := True; if xslfile = 'single.xsl' then begin attr := xslDom.DOMDocument.createAttribute('select'); attr.value := '//ROW[@CustNo="' + Request.QueryFields.Values ['id'] + '"]'; xslDom.DOMDocument.getElementsByTagName ('xsl:apply-templates'). item[0].attributes.setNamedItem(attr); end; // do the transformation HTMLDom.Active := True; xmlDom.DocumentElement.transformNode (xslDom.DocumentElement, HTMLDom); Response.Content := HTMLDom.XML.Text; end; The code uses the DOM to modify the XSL document for displaying a single record, adding the XPath statement for This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it.. Thanks selecting the record indicated by the id query field. This id is added to the hyperlink by the XSL with the list of records, but I'll skip listing more XSL files. They are available for study in the XSL subfolder of this example's folder. Warning To run this program, deploy the XSL files in a folder called XSL under the one where the script is located. You can find the demo files in the XSL subfolder of the scripts folder of this chapter. To deploy these files in a different location, change the code above that extracts the XSL folder name from the program name available in the first common line parameter (as the global Application object defined in the Forms unit is not accessible in a CGI application). This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Processing Large XML Documents As you have seen, there are often many different techniques to accomplish the same task with XML. In many cases you can choose any solution with the goal of writing less and more maintainable code; but when you need to process a large number of XML documents or very large XML documents, you must consider efficiency. Discussing theory by itself is not terribly useful, so I've built an example you can use (and modify) to test different solutions. The example is called LargeXml, and it covers a specific area: moving data from a database to an XML file and back. The example can open a dataset (using dbExpress) and then replicate the data many times in a ClientDataSet in memory. The structure of the in-memory ClientDataSet is cloned from that of the data access component: SimpleDataSet1.Open; ClientDataSet1.FieldDefs := SimpleDataSet1.FieldDefs; ClientDataSet1.CreateDataSet; After using a radio group to determine the amount of data you want to process (some options require minutes on a slow computer), the data is cloned with this code: while ClientDataSet1.RecordCount < nCount do begin SimpleDataSet1.RecNo := Random (SimpleDataSet1.RecordCount) + 1; ClientDataSet1.Insert; ClientDataSet1.Fields [0].AsInteger := Random (10000); for I := 1 to SimpleDataSet1.FieldCount - 1 do ClientDataSet1.Fields [i].AsString := SimpleDataSet1.Fields [i].AsString; ClientDataSet1.Post; end; From a ClientDataSet to an XML Document Now that the program has a (large) dataset in memory, it provides three different ways to save the dataset to a file. The first is to save the XMLData of the ClientDataSet directly to a file, obtaining an attribute-based document. This is probably not the format you want, so the second solution is to apply an XmlMapper transformation with an XMLTransformClient component. The third solution involves processing the dataset directly and writing out each record to a file: procedure TForm1.btnSaveCustomClick(Sender: TObject); var str: TFileStream; s: string; i: Integer; begin str := TFileStream.Create ('data3.xml', fmCreate); try ClientDataSet1.First; s := ' while not ClientDataSet1.EOF do begin s := ''; for i := 0 to ClientDataSet1.FieldCount - 1 do s := s + MakeXmlstr (ClientDataSet1.Fields[i].FieldName, ClientDataSet1.Fields[i].AsString); s := MakeXmlStr ('employeeData', s); str.Write(s[1], length (s)); ClientDataSet1.Next end; This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . s := ' finally str.Free; end; end; This code uses a simple (but effective) support function to create XML nodes: function MakeXmlstr (node, value: string): string; begin Result := '<' + node + '>' + value + ''; end; If you run the program, you can see the time taken by each operation, as shown in Figure 22.13. Saving the ClientDataSet data is the fastest approach, but you probably don't get the result you want. Custom streaming is only slightly slower; but you should consider that this code doesn't require you to first move the data to a ClientDataSet, because you can apply it directly even to a unidirectional dbExpress dataset. You should forget using the code based on the XmlMapper for a large dataset, because it is hundreds of times slower, even for a small dataset (I haven't been able to try a large dataset, because the process takes too long). For example, the 50 milliseconds required by custom streaming for a small dataset become more than 10 seconds when I use the mapping, and the result is very similar. Figure 22.13: The LargeXml example in action From an XML Document to a ClientDataSet Once you have a large XML document, obtained by a program (as in this case) or from an external source, you need to process it. As you have seen, XmlMapper support is far too slow, so you are left with three alternatives: an XSL transformation, a SAX, or a DOM. XSL trans-formations will probably be fast enough, but in this example I've opened the document with a SAX; it's the fastest approach and doesn't require much code. The program can also load a document in a DOM, but I haven't written the code to navigate the DOM and save the data back to a ClientDataSet. In both cases, I've tested the OpenXml engine versus the MSXML DOM. This allows you to see the two SAX solutions compared, because (unluckily) the code is slightly different. I can summarize the results here: Using the MSXML SAX is slightly faster than using the OpenXml SAX (the difference is about 20 percent), whereas loading in the DOM marks a large advantage in favor of MSXML. The MSXML SAX code uses the same architecture discussed in the SaxDemo1 example, so here I've listed only the code of the handlers you use. As you can see, at the beginning of an employeeData element you insert a new record, which is posted when the same node is closed. Lower-level nodes are added as fields of the current record. Here is the code: This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . procedure TMyDataSaxHandler.startElement(var strNamespaceURI, strLocalName, strQName: WideString; const oAttributes: IVBSAXAttributes); begin inherited; if strLocalName = 'employeeData' then Form1.clientdataset2.Insert; strCurrent := ''; end; procedure TMyDataSaxHandler.characters( var strChars: WideString); begin inherited; strCurrent := strCurrent + RemoveWhites(strChars); end; procedure TMyDataSaxHandler.endElement(var strNamespaceURI, strLocalName, strQName: WideString); begin if strLocalName = 'employeeData' then Form1.clientdataset2.Post; if stack.Count > 2 then Form1.ClientDataSet2.FieldByName (strLocalName).AsString := strCurrent; inherited; end; The code for the event handlers in the OpenXml version is similar. All that changes are the interface of the methods and the names of the parameters: type TDataSaxHandler = class (TXmlStandardHandler) protected stack: TStringList; strCurrent: string; public constructor Create(aowner: TComponent); override; function endElement(const sender: TXmlCustomProcessorAgent; const locator: TdomStandardLocator; namespaceURI, tagName: wideString): TXmlParserError; override; function PCDATA(const sender: TXmlCustomProcessorAgent; const locator: TdomStandardLocator; data: wideString): TXmlParserError; override; function startElement(const sender: TXmlCustomProcessorAgent; const locator: TdomStandardLocator; namespaceURI, tagName: wideString; attributes: TdomNameValueList): TXmlParserError; override; destructor Destroy; override; end; It is also more difficult to invoke the SAX engine, as shown in the following code (from which I've removed the code for the creation of the dataset, the timing, and the logging): procedure TForm1.btnReadSaxOpenClick(Sender: TObject); var agent: TXmlStandardProcessorAgent; reader: TXmlStandardDocReader; filename: string; begin Log := memoLog.Lines; filename := ExtractFilePath (Application.Exename) + 'data3.xml'; agent := TXmlStandardProcessorAgent.Create( nil); reader:= TXmlStandardDocReader.Create (nil); This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. try reader.NextHandler := TDataSaxHandler.Create ( nil); // our custom class agent.reader := reader; agent.processFile(filename, filename); finally agent.free; reader.free; end; end; This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. What's Next? In this chapter I've covered XML and related technologies, including DOM, SAX, XSLT, XML schemas, XPath, and a few more. You've seen how Delphi simplifies DOM programming with XML access using interfaces and XML transformations. I've also discussed the use of XSL for web programming, introducing the XSLT support of WebSnap and the Internet Express architecture. Chapter 23 will continue the discussion of XML with one of the most interesting and promising technologies of the last few years: web services. I'll cover SOAP and WSDL, and also introduce UDDI and other related technologies. If you are interested in the topics discussed here from the Delphi perspective, you should refer to books specifically devoted to XML, XML schemas, and XSLT. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Chapter 23: Web Services and SOAP Overview Of all the recent features of Delphi, one stands out clearly: the support for web services built into the product. The fact that I'm discussing it near the end of the book has nothing to do with its importance, but only with the logical flow of the text, and with the fact that this is not the starting point from which to learn Delphi programming. The topic of web services is broad and involves many technologies and business-related standards. As usual, I'll focus on the underlying Delphi implementation and the technical side of web services, rather than discuss the larger picture and business implications. This chapter is also relevant because Delphi 7 adds a lot of power to the implementation of web services provided by Delphi 6, including support for attachments, custom headers, and much more. You'll see how to create a web service client and a web service server, and also how to move database data over SOAP using the DataSnap technology. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Web Services The rapidly emerging web services technology has the potential to change the way the Internet works for businesses. Browsing web pages to enter orders is fine for individuals (business-to-consumer [B2C] applications) but not for companies (business-to-business [B2B] applications). If you want to buy a few books, going to a book vendor website and punching in your requests is probably fine. But if you run a bookstore and want to place hundreds of orders a day, this is far from a good approach, particularly if you have a program that helps you track your sales and determine reorders. Grabbing the output of this program and reentering it into another application is ridiculous. Web services are meant to solve this issue: The program used to track sales can automatically create a request and send it to a web service, which can immediately return information about the order. The next step might be to ask for a tracking number for the shipment. At this point, your program can use another web service to track the shipment until it is at its destination, so you can tell your customers how long they have to wait. As the shipment arrives, your program can send a reminder via SMS or pager to the people with pending orders, issue a payment with a bank web service, and … I could continue but I think I've given you the idea. Web services are meant for computer interoperability, much as the Web and e-mail let people interact. SOAP and WSDL Web services are made possible by the Simple Object Access Protocol (SOAP). SOAP is built over standard HTTP, so that a web server can handle the SOAP requests and the related data packets can pass though firewalls. SOAP defines an XML-based notation for requesting the execution of a method by an object on the server and passing parameters to it; another notation defines the format of a response. Note SOAP was originally developed by DevelopMentor (the training company run by COM expert Don Box) and Microsoft, to overcome weaknesses involved with using DCOM in web servers. Submitted to the W3C for standardization, it is being embraced by many companies, with a particular push from IBM. It is too early to know whether there will be standardization to let software programs from Microsoft, IBM, Sun, Oracle, and many others truly interoperate, or whether some of these vendors will try to push a private version of the standard. In any case, SOAP is a cornerstone of Microsoft's .NET architecture and also of the current platforms by Sun and Oracle. SOAP will replace COM invocation, at least between different computers. Similarly, the definition of a SOAP service in the Web Services Description Language (WSDL) format will replace the IDL and type libraries used by COM and COM+. WSDL documents are another type of XML document that provides the metadata definition of a SOAP request. As you get a file in this format (generally published to define a service), you'll be able to create a program to call it. Specifically, Delphi provides a bi-directional mapping between WSDL and interfaces. This means you can grab a WSDL file and generate an interface for it. You can then create a client program, embedding SOAP requests via these interfaces, and use a special Delphi component that lets you convert your local interface requests into SOAP calls (I doubt you want to manually generate the XML required for a SOAP request). The other way around, you can define an interface (or use an existing one) and let a Delphi component generate a WSDL description for it. Another component provides you with a SOAP-to-Pascal mapping, so that by embedding this component and an object implementing the interface within a server-side program, you can have your web service up and running in a matter of minutes. BabelFish Translations As a first example of the use of web service, I've built a client for the BabelFish translation service offered by AltaVista. You can find this and many other services for experimentation on the XMethods website (www.xmethods.com). After downloading the WSDL description of this service from XMethods (also available among the source code files for this chapter), I invoked Delphi's Web Services Importer in the Web Services page of the New Items dialog box and selected the file. The wizard lets you preview the structure of the service (see Figure 23.1) and generate the proper Delphi-language interfaces in a unit like the following (with many of the comments removed): This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Figure 23.1: The WSDL Import Wizard in action unit BabelFishService; interface uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns; type BabelFishPortType = interface(IInvokable) ['{D2DB6712-EBE0-1DA6-8DEC-8A445595AE0C}'] function BabelFish( const translationmode: WideString; const sourcedata: WideString): WideString; stdcall; end; function GetBabelFishPortType(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): BabelFishPortType; implementation // omitted initialization InvRegistry.RegisterInterface(TypeInfo(BabelFishPortType), 'urn:xmethodsBabelFish', ''); InvRegistry.RegisterDefaultSOAPAction(TypeInfo(BabelFishPortType), 'urn:xmethodsBabelFish#BabelFish'); end. Notice that the interface inherits from the IInvokable interface. This interface doesn't add anything in terms of methods to Delphi's IInterface base interface, but it is compiled with the flag used to enable RTTI generation, {$M+}, like the TPersistent class. In the initialization section, you notice that the interface is registered in the global invocation registry (or InvRegistry), passing the type information reference of the interface type. Note Having RTTI information for interfaces is the most important technological advance underlying SOAP invocation. Not that SOAP-to-Pascal mapping isn't important—it is crucial to simplify the process—but having RTTI for an interface makes the entire architecture powerful and robust. The third element of the unit generated by the WSDL Import Wizard is a global function named after the service, introduced in Delphi 7. This function helps simplify the code used to call the web service. The GetBabelFishPortType function returns an interface of the proper type, which you can use to issue a call directly. For instance, the following This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it.. Thanks code translates a short sentence from English into Italian (as indicated by the value of the first parameter, en_it) and shows it on screen: ShowMessage (GetBabelFishPortType.BabelFish('en_it', 'Hello, world!')); If you look at the code for the GetBabelFishPortType function, you'll see that it creates an internal invocation component of the class THTTPRIO to process the call. You can also place this component manually on the client form (as I've done in the example program) to gain better control over its various settings (and handle its events). This component can be configured in two basic ways: You can refer to the WSDL file or URL, import it, and extract from it the URL of the SOAP call; or, you can provide a direct URL to call. The example has two components that provide the alternative approaches (with exactly the same effect): object HTTPRIO1: THTTPRIO WSDLLocation = 'BabelFishService.xml' Service = 'BabelFish' Port = 'BabelFishPort' end object HTTPRIO2: THTTPRIO URL = 'http://services.xmethods.net:80/perl/soaplite.cgi' end At this point, there is little left to do. You have information about the service that can be used for its invocation, and you know the types of the parameters required by the only available method as they are listed in the interface. The two elements are merged by extracting the interface you want to call directly from the HTTPRIO component, with an expression like HTTPRIO1 as BabelFishPortType. It might seem astonishing at first, but it is also outrageously simple. This is the web service call done by the example: EditTarget.Text := (HTTPRIO1 as BabelFishPortType). BabelFish(ComboBoxType.Text, EditSource.Text); The program output, shown in Figure 23.2, allows you to learn foreign languages (although the teacher has its shortcomings!). I haven't replicated the same example with stock options, currencies, weather forecasts, and the many other services available, because they would look much the same. Figure 23.2: An example of a translation from English to German obtained by Alta-Vista's BabelFish via a web service Warning Although the web service interface provides you with the types of the parameters, in many cases you need to refer to some actual documentation of the service to know what the values of the parameters really mean and how they are interpreted by the service. The BabelFish web service is an example of this issue, as I had to look at some textual documentation to find out the list of translation types, available in the demo in a combo box. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Building Web Services If calling a web service in Delphi is straightforward, the same can be said of developing a service. If you go into the Web Services page of the New Items dialog box, you can see the SOAP Server Application option. Select it, and Delphi presents you with a list that's quite similar to what you see if you select a WebBroker application. A web service is typically hosted by a web server using one of the available web server extension technologies (CGI, ISAPI, Apache modules, and so on) or the Web App Debugger for your initial tests. After completing this step, Delphi adds three components to the resulting web module, which is just a plain web module with no special additions: The HTTPSoapDispatcher component receives the web request, as any other HTTP dispatcher does. The HTTPSoapPascalInvoker component does the reverse operation of the HTTPRIO component; it can translate SOAP requests into calls of Pascal interfaces (instead of shifting interface method calls into SOAP requests). The WSDLHTMLPublish component can be used to extract the WSDL definition of the service from the interfaces it support, and performs the opposite role of the Web Services Importer Wizard. Technically, this is another HTTP dispatcher. A Currency Conversion Web Service Once this framework is in place—something you can also do by adding the three components listed in the previous section to an existing web module—you can begin writing a service. As an example, I've taken the euro conversion example from Chapter 3, "The Run-Time Library," and transformed it into a web service called ConvertService. First, I've added to the program a unit defining the interface of the service, as follows: type IConvert = interface(IInvokable) ['{FF1EAA45-0B94-4630-9A18-E768A91A78E2}'] function ConvertCurrency (Source, Dest: string; Amount: Double): Double; stdcall; function ToEuro (Source: string; Amount: Double): Double; stdcall; function FromEuro (Dest: string; Amount: Double): Double; stdcall; function TypesList: string; stdcall; end; Defining an interface directly in code, without having to use a tool such as the Type Library Editor, provides a great advantage, as you can easily build an interface for an existing class and don't have to learn using a specific tool for this purpose. Notice that I've given a GUID to the interface, as usual, and used the stdcall calling convention, because the SOAP converter does not support the default register calling convention. In the same unit that defines the interface of the service, you should also register it. This operation will be necessary on both the client and server sides of the program, because you will be able to include this interface definition unit in both: uses InvokeRegistry; initialization InvRegistry.RegisterInterface(TypeInfo(IConvert)); Now that you have an interface you can expose to the public, you have to provide an implementation for it, again by means of the standard Delphi code (and with the help of the predefined TInvokableClass class: type TConvert = class (TInvokableClass, IConvert) protected function ConvertCurrency (Source, Dest: string; Amount: Double): Double; This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register . it. Thanks stdcall; function ToEuro (Source: string; Amount: Double): Double; stdcall; function FromEuro (Dest: string; Amount: Double): Double; stdcall; function TypesList: string; stdcall; end; The implementation of these functions, which call the code of the euro conversion system from Chapter 3, is not discussed here because it has little to do with the development of the service. However, it is important to notice that this implementation unit also has a registration call in its initialization section: InvRegistry.RegisterInvokableClass (TConvert); Publishing the WSDL By registering the interface, you make it possible for the program to generate a WSDL description. The web service application (since the Delphi 6.02 update) is capable of displaying a first page describing its interfaces and the detail of each interface, and returning the WSDL file. By connecting to the web service via a browser, you'll see something similar to Figure 23.3. Figure 23.3: The description of the Convert-Service web service provided by Delphi components Note Although other web service architectures automatically provide you with a way to execute the web service from the browser, this technique is mostly meaningless, because using web services makes sense in an architecture where different applications interoperate. If all you need to do is show data on a browser, you should build a website! This auto-descriptive feature was not available in web services produced in Delphi 6 (which provided only the lower-level WSDL listing), but it is quite easy to add (or customize). If you look at the Delphi 7 SOAP web module you'll notice a default action with an OnAction event handler invoking the following default behavior: WSDLHTMLPublish1.ServiceInfo(Sender, Request, Response, Handled); This is all you have to do to retrofit this feature into an existing Delphi web service that lacks it. To provide similar functionality manually, you must call into the invocation registry (the InvRegistry global object), with calls like GetInterfaceExternalName and GetMethExternalName. What's important is the web service application's ability to document itself to any other programmer or programming tool, by exposing the WSDL. Creating a Custom Client This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Let's move to the client application that calls the service. I don't need to start from the WSDL file, because I already have the Delphi interface. This time the form doesn't even have the HTTPRIO component, which is created in code: private Invoker: THTTPRio; procedure TForm1.FormCreate(Sender: TObject); begin Invoker := THTTPRio.Create( nil); Invoker.URL := 'http://localhost/scripts/ConvertService.exe/soap/iconvert'; ConvIntf := Invoker as IConvert; end; As an alternative to using a WSDL file, the SOAP invoker component can be associated with an URL. Once this association has been done and the required interface has been extracted from the component, you can begin writing straight Pascal code to invoke the service, as you saw earlier. A user fills the two combo boxes, calling the TypesList method, which returns a list of available currencies within a string (separated by semicolons). You extract this list by replacing each semicolon with a line break and then assigning the multiline string directly to the combo items: procedure TForm1.Button2Click(Sender: TObject); var TypeNames: string; begin TypeNames := ConvIntf.TypesList; ComboBoxFrom.Items.Text := StringReplace (TypeNames, ';', sLineBreak, [rfReplaceAll]); ComboBoxTo.Items := ComboBoxFrom.Items; end; After selecting two currencies, you can perform the conversion with this code (Figure 23.4 shows the result): procedure TForm1.Button1Click(Sender: TObject); begin LabelResult.Caption := Format ('%n', [(ConvIntf.ConvertCurrency( ComboBoxFrom.Text, ComboBoxTo.Text, StrToFloat(EditAmount.Text)))]); end; This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Figure 23.4: The ConvertCaller client of the Convert-Service web service shows how few German marks you used to get for so many Italian liras, before the euro changed everything. Asking for Database Data For this example, I built a web service (based on the Web App Debugger) capable of exposing data about employees of a company. This data is mapped to the EMPLOYEE table of sample InterBase database we've used so often throughout the book. The Delphi interface of the web service is defined in the SoapEmployeeIntf unit as follows: type ISoapEmployee = interface (IInvokable) ['{77D0D940-23EC-49A5-9630-ADE0751E3DB3}'] function GetEmployeeNames: string; stdcall; function GetEmployeeData (EmpID: string): string; stdcall; end; The first method returns a list of the names of all the employees in the company, and the second returns the details of a given employee. The implementation of this interface is provided in the Soap-EmployeeImpl unit with the following class: type TSoapEmployee = class (TInvokableClass, ISoapEmployee) public function GetEmployeeNames: string; stdcall; function GetEmployeeData (EmpID: string): string; stdcall; end; The implementation of the web service lies in the two previous methods and some helper functions to manage the XML data being returned. But before we get to the XML portion of the example, let me briefly discuss the database access section. Accessing the Data All the connectivity and SQL code in this example are hosted in a separate data module. Of course, I could have created some connection and dataset components dynamically in the methods, but doing so is contrary to the approach of a visual development tool like Delphi. The data module has the following structure: object DataModule3: TDataModule3 object SQLConnection: TSQLConnection ConnectionName = 'IBConnection' DriverName = 'Interbase' LoginPrompt = False Params.Strings = // omitted end object dsEmplList: TSQLDataSet CommandText = 'select EMP_NO, LAST_NAME, FIRST_NAME from EMPLOYEE' SQLConnection = SQLConnection object dsEmplListEMP_NO: TStringField object dsEmplListLAST_NAME: TStringField object dsEmplListFIRST_NAME: TStringField end object dsEmpData: TSQLDataSet CommandText = 'select * from EMPLOYEE where Emp_No = :id' Params = < item DataType = ftFixedChar Name = 'id' ParamType = ptInput end> SQLConnection = SQLConnection end This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . end As you can see, the data module has two SQL queries hosted by SQLDataSet components. The first is used to retrieve the name and ID of each employee, and the second returns the entire set of data for a given employee. Passing XML Documents The problem is how to return this data to a remote client program. In this example, I've used the approach I like best: I've returned XML documents, instead of working with complex SOAP data structures. (I don't get how XML can be seen as a messaging mechanism for SOAP invocation—along with the transport mechanism provided by HTTP—but then, it is not used for the data being transferred. Still, very few web services return XML documents, so I'm beginning to wonder if it's me or many other programmers who can't see the full picture.) In this example, the GetEmployeeNames method creates an XML document containing a list of employees, with their first and last names as values and the related database ID as an attribute, using two helper functions MakeXmlStr (already described in the last chapter) and MakeXmlAttribute (listed here): function TSoapEmployee.GetEmployeeNames: string; var dm: TDataModule3; begin dm := TDataModule3.Create (nil); try dm.dsEmplList.Open; Result := ' while not dm.dsEmplList.EOF do begin Result := Result + ' ' + MakeXmlStr ('employee', dm.dsEmplListLASTNAME.AsString + ' ' + dm.dsEmplListFIRSTNME.AsString, MakeXmlAttribute ('id', dm.dsEmplListEMPNO.AsString)) + sLineBreak; dm.dsEmplList.Next; end; Result := Result + ' finally dm.Free; end; end; function MakeXmlAttribute (attrName, attrValue: string): string; begin Result := attrName + '="' + attrValue + '"'; end; Instead of the manual XML generation, I could have used the XML Mapper or some other technology; but as you should know from Chapter 22 ("Using XML Technologies"), I rather prefer creating XML directly in strings. I'll use the XML Mapper to process the data received on the client side. Note You may wonder why the program creates a new instance of the data module each time. The negative side of this approach is that each time, the program establishes a new connection to the database (a rather slow operation); but the plus side is that you have no risk related to the use of a multithreaded application. If two web service requests are executed concurrently, you can use a shared connection to the database, but you must use different dataset components for the data access. You could move the datasets in the function code and keep only the connection on the data module, or have a global shared data module for the connection (used by multiple threads) and a specific instance of a second data module hosting the datasets for each method call. Let's now look at the second method, GetEmployeeData. It uses a parametric query and formats the resulting fields in separate XML nodes (using another helper function, FieldsToXml): function TSoapEmployee.GetEmployeeData(EmpID: string): string; var This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . dm: TDataModule3; begin dm := TDataModule3.Create (nil); try dm.dsEmpData.ParamByName('ID').AsString := EmpId; dm.dsEmpData.Open; Result := FieldsToXml ('employee', dm.dsEmpData); finally dm.Free; end; end; function FieldsToXml (rootName: string; data: TDataSet): string; var i: Integer; begin Result := '<' + rootName + '>' + sLineBreak;; for i := 0 to data.FieldCount - 1 do Result := Result + ' ' + MakeXmlStr ( LowerCase (data.Fields[i].FieldName), data.Fields[i].AsString) + sLineBreak; Result := Result + '' + sLineBreak;; end; The Client Program (with XML Mapping) The final step for this example is to write a test client program. You can do so as usual by importing the WSDL file defining the web service. In this case, you also have to convert the XML data you receive into something more manageable—particularly the list of employees returned by the GetEmployeeNames method. As mentioned earlier, I've used Delphi's XML Mapper to convert the list of employees received from the web service into a dataset I can visualize using a DBGrid. To accomplish this, I first wrote the code to receive the XML with the list of employees and copied it into a memo component and from there to a file. Then, I opened the XML Mapper, loaded the file, and generated from it the structure of the data packet and the transformation file. (You can find the transformation file among the source code files of the SoapEmployee example.) To show the XML data within a DBGrid, the program uses an XMLTransformProvider component, referring to the transformation file: object XMLTransformProvider1: TXMLTransformProvider TransformRead.TransformationFile = 'EmplListToDataPacket.xtr' end The ClientDataSet component is not hooked to the provider, because it would try to open the XML data file specified by the transformation. In this case, the XML data doesn't reside in a file, but is passed to the component after calling the web service. For this reason the program moves the data to the ClientDataSet directly in code: procedure TForm1.btnGetListClick(Sender: TObject); var strXml: string; begin strXml := GetISoapEmployee.GetEmployeeNames; strXML := XMLTransformProvider1.TransformRead.TransformXML(strXml); ClientDataSet1.XmlData := strXml; ClientDataSet1.Open; end; With this code, the program can display the list of employees in a DbGrid, as you can see in Figure 23.5. When you retrieve the data for the specific employee, the program extracts the ID of the active record from the ClientDataSet and then shows the resulting XML in a memo: procedure TForm1.btnGetDetailsClick(Sender: TObject); This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . begin Memo2.Lines.Text := GetISoapEmployee.GetEmployeeData( ClientDataSet1.FieldByName ('id').AsString); end; Figure 23.5: The client program of the SoapEmployee web service example Debugging the SOAP Headers One final note for this example relates to the use of the Web App Debugger for testing SOAP applications. Of course, you can run the server program from the Delphi IDE and debug it easily, but you can also monitor the SOAP headers passed on the HTTP connection. Although looking at SOAP from this low-level perspective can be far from simple, it is the ultimate way to check if something is wrong with either a server or a client SOAP application. As an example, in Figure 23.6 you can see the HTTP log of a SOAP request from the last example. Figure 23.6: The HTTP log of the Web App Debugger includes the low-level SOAP request. The Web App Debugger might not always be available, so another common technique is to handle the events of the HTTPRIO component, as the BabelFishDebug example does. The program's form has two memo components in which you can see the SOAP request and the SOAP response: procedure TForm1.HTTPRIO1BeforeExecute(const MethodName: String; This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . var SOAPRequest: WideString); begin MemoRequest.Text := SoapRequest; end; procedure TForm1.HTTPRIO1AfterExecute(const MethodName: String; SOAPResponse: TStream); begin SOAPResponse.Position := 0; MemoResponse.Lines.LoadFromStream(SOAPResponse); end; Exposing an Existing Class as a Web Service Although you might want to begin developing a web service from scratch, in some cases you may have existing code to make available. This process is not too complex, given Delphi's open architecture in this area. To try it, follow these steps: 1. Create a web service application or add the related components to an existing WebBroker project. 2. Define an interface inheriting from IInvokable and add to it the methods you want to make available in the web service (using the stdcall calling convention). The methods will be similar to those of the class you want to make available. 3. Define a new class that inherits from the class you want to expose and implements your interface. The methods will be implemented by calling the corresponding methods of the base class. 4. Write a factory method to create an object of your implementation class any time a SOAP request needs it. This last step is the most complex. You could define a factory and register it as follows: procedure MyObjFactory (out Obj: TObject); begin Obj := TMyImplClass.Create; end; initialization InvRegistry.RegisterInvokableClass(TMyImplClass, MyObjFactory); However, this code creates a new object for every call. Using a single global object would be equally bad: Many different users might try to use it, and if the object has state or its methods are not concurrent, you might be in for big problems. You're left with the need to implement some form of session management, which is a variation on the problem we had with the earlier web service connecting to the database. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . DataSnap over SOAP Now that you have a reasonably good idea how to build a SOAP server and a SOAP client, let's look at how to use this technology in building a multitier DataSnap application. You'll use a Soap Server Data Module to create the new web service and the SoapConnection component to connect a client application to it. Building the DataSnap SOAP Server Let's look at the server side first. Go to the Web Services page of the New Items dialog box and use the Soap Server Application icon to create a new web service, and then use the Soap Server Data Module icon to add a DataSnap server-side data module to the SOAP server. I did this in the SoapDataServer7 example (which uses the Web App Debugger architecture for testing purposes). From this point on, all you do is write a normal DataSnap server (or a middle-tier DataSnap application), as discussed in Chapter 16 ("Multitier DataSnap Applications"). In this case, I added InterBase access to the program by means of dbExpress, resulting in the following structure: object SoapTestDm: TSoapTestDm object SQLConnection1: TSQLConnection ConnectionName = 'IBLocal' end object SQLDataSet1: TSQLDataSet SQLConnection = SQLConnection1 CommandText = 'select * from EMPLOYEE' end object DataSetProvider1: TDataSetProvider DataSet = SQLDataSet1 end end The data module built for a SOAP-based DataSnap server defines a custom interface (so you can add methods to it) inheriting from IAppServerSOAP, which is defined as a published interface (even though it doesn't inherit from IInvokable). Tip Delphi 6 used DataSnap's standard IAppServer interface for exposing data via SOAP. Delphi 7 has replaced the default with the inherited IAppServerSOAP interface, which is functionally identical but allows the system to discriminate the type of call depending on the interface name. You'll see shortly how to call an older application from a client built in Delphi 7, because this process is not automatic. The implementation class, TSoapTestDm, is the data module, as in other DataSnap servers. Here is the code Delphi generated, with the addition of the custom method: type ISampleDataModule = interface(IAppServerSOAP) ['{D47A293F-4024-4690-9915-8A68CB273D39}'] function GetRecordCount: Integer; stdcall; end; TSampleDataModule = class (TSoapDataModule, ISampleDataModule, IAppServerSOAP, IAppServer) DataSetProvider1: TDataSetProvider; SQLConnection1: TSQLConnection; SQLDataSet1: TSQLDataSet; public function GetRecordCount: Integer; stdcall; end; The base TSoapDataModule doesn't inherit from TInvokableClass. This is not a problem as long as you provide an extra factory procedure to create the object (which is what TInvokableClass does for you) and add it to the registration code (as discussed earlier, in the section "Exposing an Existing Class as a Web Service"): This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . procedure TSampleDataModuleCreateInstance(out obj: TObject); begin obj := TSampleDataModule.Create(nil); end; initialization InvRegistry.RegisterInvokableClass( TSampleDataModule, TSampleDataModuleCreateInstance); InvRegistry.RegisterInterface(TypeInfo(ISampleDataModule)); The server application also publishes the IAppServerSOAP and IAppServer interfaces, thanks to the (little) code in the SOAPMidas unit. As a comparison, you can find a SOAP DataSnap server built with Delphi 6 in the SoapDataServer folder. The example can still be compiled in Delphi 7 and works fine, but you should write new programs using the structure of the newer; an example is in the SoapDataServer7 folder. Tip Web service applications in Delphi 7 can include more than one SOAP data module. To identify a specific SOAP data module, use the SOAPServerIID property of the SoapConnection component or add the data module interface name to the end of the URL. The server has a custom method (the Delphi 6 version of the program also had one, but it never worked) that uses a query with the select count(*) from EMPLOYEE SQL statement: function TSampleDataModule.GetRecordCount: Integer; begin // read in the record count by running a query SQLDataSet2.Open; Result := SQLDataSet2.Fields[0].AsInteger; SQLDataSet2.Close; end; Building the DataSnap SOAP Client To build the client application, called SoapDataClient7, I began with a plain program and added a SoapConnection component to it (from the Web Services page of the palette), hooking it to the URL of the DataSnap web service and referring to the specific interface I'm looking for: object SoapConnection1: TSoapConnection URL = 'http://localhost:1024/SoapDataServer7.soapdataserver/' + 'soap/Isampledatamodule' SOAPServerIID = 'IAppServerSOAP - {C99F4735-D6D2-495C-8CA2-E53E5A439E61}' UseSOAPAdapter = False end Notice the last property, UseSOAPAdapter, which indicates you are working against a server built with Delphi 7. As a comparison, the SoapDataClient (again, no 7) example, which uses a server created with Delphi 6 and recompiled with Delphi 7, must have this property set to True. This value forces the program to use the plain IAppServer interface instead of the new IAppServerSOAP interface. From this point on, you proceed as usual, adding a ClientDataSet component, a DataSource, and a DBGrid to the program; choosing the only available provider for the client dataset; and hooking the rest. Not surprisingly, for this simple example, the client application has little custom code: a single call to open the connection when a button is clicked (to avoid startup errors) and an ApplyUpdates call to send changes back to the database. SOAP versus Other DataSnap Connections Regardless of the apparent similarity of this program to all the other DataSnap client and server programs built in Chapter 16, there is a very important difference worth underlining: The SoapDataServer and SoapDataClient programs do not use COM to expose or call the IAppServerSOAP interface. Quite the opposite—the socket- and HTTP-based connections of DataSnap still rely on local COM objects and a registration of the server in the Windows Registry. The native SOAP-based support, however, allows for a totally custom solution that's independent of COM and that offers many more chances to be ported to other operating systems. (You can recompile this server in Kylix, This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. but not the programs built in Chapter 16.) The client program can also call the custom method I've added to the server to return the record count. This method could be used in a real-world application to show only a limited number of records but inform the user how many haven't yet been downloaded from the server. The client code to call the method relies on an extra HTTPRIO component: procedure TFormSDC.Button3Click(Sender: TObject); var SoapData: ISampleDataModule; begin SoapData := HttpRio1 as ISampleDataModule; ShowMessage (IntToStr (SoapData.GetRecordCount)); end; This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register . it. Thanks Handling Attachments One of the most important features Borland added to Delphi 7 is full support for SOAP attachments. Attachments in SOAP allow you to send data other than XML text, such as binary files or images. In Delphi, attachments are managed through streams. You can read or indicate the type of attachment encoding, but the transformation of a raw stream of bytes into and from a given encoding is up to your code. This process isn't too complex, though, if you consider that Indy includes a number of encoding components. As an example of how to use attachments, I've written a program that forwards the binary content of a ClientDataSet (also hosts images) or one of the images alone. The server has the following interface: type ISoapFish = interface(IInvokable) ['{4E4C57BF-4AC9-41C2-BB2A-64BCE470D450}'] function GetCds: TSoapAttachment; stdcall; function GetImage(fishName: string): TSoapAttachment; stdcall; end; The implementation of the GetCds method uses a ClientDataSet that refers to the classic BIOLIFE table, creates a memory stream, copies the data to it, and then attaches the stream to the TSoapAttachment result: function TSoapFish.GetCds: TSoapAttachment; stdcall; var memStr: TMemoryStream; begin Result := TSoapAttachment.Create; memStr := TMemoryStream.Create; WebModule2.cdsFish.SaveToStream(MemStr); // binary Result.SetSourceStream (memStr, soReference); end; On the client side, I prepared a form with a ClientDataSet component connected to a DBGrid and a DBImage. All you have to do is grab the SOAP attachment, save it to a temporarily in-memory stream, and then copy the data from the memory stream to the local ClientDataSet: procedure TForm1.btnGetCdsClick(Sender: TObject); var sAtt: TSoapAttachment; memStr: TMemoryStream; begin nRead := 0; sAtt := (HttpRio1 as ISoapFish).GetCds; try memStr := TMemoryStream.Create; try sAtt.SaveToStream(memStr); memStr.Position := 0; ClientDataSet1.LoadFromStream(MemStr); finally memStr.Free; end; finally DeleteFile (sAtt.CacheFile); sAtt.Free; end; end; This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Warning By default, SOAP attachments received by a client are saved to a temporary file, referenced by the CacheFile property of the TSOAPAttachment object. If you don't delete this file it will remain in a folder that hosts temporary files. This code produces the same visual effect as a client application loading a local file into a ClientDataSet, as you can see in Figure 23.7. In this SOAP client I used an HTTPRIO component explicitly to be able to monitor the incoming data (which will possibly be very large and slow); for this reason, I set a global nRead variable to zero before invoking the remote method. In the OnReceivingData event of the HTTPRIO object's HTTPWebNode property, you add the data received to the nRead variable. The Read and Total parameters passed to the event refer to the specific block of data sent over a socket, so they are almost useless by themselves to monitor progress: procedure TForm1.HTTPRIO1HTTPWebNode1ReceivingData( Read, Total: Integer); begin Inc (nRead, Read); StatusBar1.SimpleText := IntToStr (nRead); Application.ProcessMessages; end; Figure 23.7: The FishClient example receives a binary ClientDataSet within a SOAP attachment. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register . it. Thanks Supporting UDDI The increasing popularity of XML and SOAP opens the way for business-to-business communication applications to interoperate. XML and SOAP provide a foundation, but they are not enough—standardization in the XML formats, in the communication process, and in the availability of information about a business are all key elements of a real-world solution. Among the standards proposed to overcome this situation, the most notable are Universal Description, Discovery, and Integration (UDDI, www.uddi.org) and Electronic Business using eXtensible Markup Language (ebXML, www.ebxml.org ). These two solutions partially overlap and partially diverge and are now being further worked on by the OASIS consortium (Organization for the Advancement of Structured Information Standards, www.oasis-open.org). I won't get into the problems with business processes; instead I'll only discuss some of the technical elements of UDDI, because it is specifically supported by Delphi 7. What Is UDDI? The Universal Description, Discovery, and Integration (UDDI) specification is an effort to create a catalog of web services offered by companies throughout the world. The goal of this initiative is to build an open, global, platform-independent framework to let business entities find each other, define how they interact with the Internet network, and share a global business registry. Of course, the idea is to speed up the adoption of e-commerce, in the form of B2B applications. UDDI is basically a global business registry. Companies can register themselves on the system, describing their organization and the web services they offer (in UDDI the term web services is used in a very wide sense, including e-mail addresses and websites). The information in the UDDI registry for each company is divided into three areas: White Pages Include contact information, addresses, and the like. Yellow Pages Register the company in one or more taxonomies, including industrial categories, products sold by the company, geographical information, and other (possibly customizable) taxonomies. Green Pages List the web services offered by the company. Each service is listed under a service type (called a tModel), which can be predefined or a type specifically described by the company (for example, in terms of WSDL). Technically, the UDDI registry should be perceived like today's DNS, and should have a similar distributed nature: multiple servers, mirrored and caching data. Clients can cache data following given rules. UDDI defines specific data models for a business entity, a business service, and a binding template. The BusinessEntity type includes core information about the business, such as its name, the category it belongs to, and contact information. It supports the taxonomies of the yellow pages, with industry information, product types, and geographic details. The BusinessService type includes descriptions of web services (used for the green pages). The main type is only a container for the related services. The services can be bound to a taxonomy (geographical area, product, and so on). Every BusinessService structure includes one or more BindingTemplates (the reference to the service). The BindingTemplate has a tModel. The tModel includes information about formats, protocols, and security, and references to technical specifications (possibly using the WSDL format). If multiple companies share a tModel, a program can interact with all of them with the same code. A given business program, for example, can offer a tModel for other software programs to interact with it, regardless of the company that has adopted the software. The UDDI API is based on SOAP. Using SOAP, you can both register data and query a registry. Microsoft also offers a COM-based SDK, and IBM has a Java Open Source toolkit for UDDI. UDDI APIs include inquiry (find_xx and get_xx) and publishing (save_xx and delete_xx) on each of the four core data structures (businessEntity, businessService, bindingTemplate, and tModel). This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . UDDI in Delphi 7 Delphi 7 includes a UDDI browser you can use to find a web service while importing a WSDL file. The UDDI browser, shown in Figure 23.8, is activated by the WSDL Import Wizard. This browser uses only UDDI version 1 servers (a newer interface is available, but it isn't supported) and has a few predefined UDDI registries. You can add predefined settings in the UDDIBrow.ini file in the Delphi bin folder. Figure 23.8: The UDDI Browser embedded in the Delphi IDE This is a handy way to access web services information, but it is not all that Delphi provides. Although the UDDI Browser is not available as a stand-alone application, the UDDI interface units are available (and they are not trivial to import). So, you can write your own UDDI browser. I'll sketch a simple solution, which is a starting point for a full-blown UDDI browser. The UddiInquiry example, shown in action in Figure 23.9, has a number of features, but not all of them work smoothly (particularly the category search features). The reason lies in the fact that using UDDI implies navigating complex data structures, which are not always mapped in the most obvious way by the WSDL importer. This makes the example code fairly involved; so, I'll show you only the code for a plain search, and not even all of it (another reason is that some readers may not be particularly interested in UDDI). This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Figure 23.9: The UddiInquiry example features a limited UDDI browser. As the program starts, it binds the HTTPRIO component it hosts with the InquireSoap UDDI interface, defined in the inquire_v1 unit provided with Delphi 7: procedure TForm1.FormCreate(Sender: TObject); begin httprio1.Url := comboRegistry.Text; inftInquire := httprio1 as InquireSoap; end; Clicking the Search button makes the program call the find_business UDDI API. Because most UDDI functions require many parameters, it has been imported using a single record-based parameter of type FindBusiness; it returns a businessList2 object: procedure TForm1.btnSearchClick(Sender: TObject); var findBusinessData: Findbusiness; businessListData: businessList2; begin httprio1.Url := comboRegistry.Text; findBusinessData := FindBusiness.Create; findBusinessData.name := edSearch.Text; findBusinessData.generic := '1.0'; findBusinessData.maxRows := 20; businessListData := inftInquire.find_business(findBusinessData); BusinessListToListView (businessListData); findBusinessData.Free; end; The businessList2 object is a list that is processed by the businessListToListView method of the program's main form, showing the most relevant details in a list view component: procedure TForm1.businessListToListView(businessList: businessList2); var i: Integer; begin ListView1.Clear; This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it.. Thanks for i := 0 to businessList.businessInfos.Len do begin with ListView1.Items.Add do begin Caption := businessList.businessInfos [i].name; SubItems.Add (businessList.businessInfos [i].description); SubItems.Add (businessList.businessInfos [i].businessKey); end; end; end; By double-clicking on a list view item you can further explore its details, although the program shows the resulting XML information in a plain textual format (or a TWebBrowser -based XML view) and doesn't further process it. As mentioned, I don't want to get into technical details; if you're interested, you can find them by looking at the source code. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. What's Next? In this chapter, I've focused on web services, covering SOAP, WSDL, and UDDI. Refer to the W3C website and to the UDDI (www.uddi.org) and ebXML (www.ebxml.org ) sites for more information in the area of business-oriented web services. I didn't delve much into these non-technical issues, but they were worth mentioning. You should have noticed in this chapter that Delphi is strong player in the area of web services, with a powerful, open architecture. You can use web services to interact with applications written for the Microsoft .NET platform; Delphi has much to offer for this architecture, because it includes a Delphi for .NET preview (covered in the two final chapters of the book). Chapter 24, "The Microsoft .NET Architecture from the Delphi Perspective," is focused on the .NET platform; Chapter 25, "Delphi for .NET Preview: The Language and the RTL," covers the new Delphi compiler. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it.. Thanks Chapter 24: The Microsoft .NET Architecture from the Delphi Perspective Overview Every few years a new technology comes along that turns our industry upside down. Some of these technologies thrive, some mutate into something else, and many are revealed to be half-baked marketing fluff. Almost in military fashion, the arrival of a new technology is invariably preceded by an artillery barrage of hype. Experienced programmers know to keep their heads down until the hype barrage subsides. After all, the proof will be in the technical pudding, so to speak. Your reaction to Microsoft's .NET initiative will depend somewhat on your background. If you have previous experience with Java or Delphi, you might wonder what all the fuss is about. But, if you have been slogging it out in the trenches writing applications for Windows in C++ (or, heaven forbid, in C), you might be overwhelmed with joy. The purpose of this chapter is to explain some of the technologies that make up the .NET initiative and to show how they fit into the world of Windows programming in general and Delphi programming in particular. We will begin by installing and configuring the Delphi for .NET Preview compiler. Then we will broadly cover some of the .NET technologies. Finally, we will discuss these technologies in greater detail, weaving in some Delphi code for illustration. Note This chapter and the following one were by Marco with extensive help from John Bushakra, who works for Borland's RAD tools documentation department. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Installing the Delphi for .NET Preview The Delphi for .NET Preview requires but does not install .NET Framework Runtime, which is freely downloadable from Microsoft's MSDN website. As a developer, you'll probably want to take an extra step and install the more complete .NET Framework SDK, which includes documentation and tools for developers (but is also much larger). You should install the .NET Framework Runtime or SDK before you install the Delphi for .NET Preview. The Preview compiler is compatible with the .NET Framework SDK and service pack 1. If you have applied service pack 2 or later, then you will have to perform the extra step of rebuilding the precompiled units (the dcuil files) installed with the Preview. This requirement might go away in subsequent updates to the Delphi for .NET Preview compiler. Note A few months after Delphi 7 shipped (in November 2002), Borland released a significant update of the Delphi for .NET Preview. As a registered Delphi user, you can download updates to the Preview from the Borland website. Do this even before installing the version that comes in the Delphi box, as you'll need to uninstall it to update to a newer version. Warning I've used the November 2002 version of the Delphi for .NET Preview to test the examples of this and the .NET chapter, although most of them will also compile against the original version that shipped with Delphi 7. By the time you read this, a newer version might be available; check the author's website for updates of the examples. After installing the .NET Framework SDK, insert the Delphi for .NET Preview CD and run the setup program. The Preview will install itself in a separate directory from your Delphi 7 installation, and none of your Delphi 7 settings are affected by installing the Preview. Previously I mentioned that you would need to rebuild the precompiled units shipped with the compiler, if you have installed service pack 2 for the .NET Framework. If this applies to you, open a command window and navigate to the source\rtl directory under the root of the compiler installation directory. There, you will find a file called rebuild.bat, which you must execute to perform the rebuild. You might see some errors and warnings; these are known issues at the time of this writing, and might be cleared up in subsequent updates to the compiler. Once the batch file has completed, you will be ready to go. The dccil compiler is located in the bin directory. Along with the compiler, in this directory is a file called dccil.cfg that specifies the default unit search path (the -U compiler switch), which is the units directory under the root installation directory. As packaged, the Delphi for .NET Preview compiler is strictly for use with a command window. However, Borland has made available an unsupported plug-in to the Delphi 7 IDE on the Borland Developers Network website, referred to as Delphi for .NET common line compiler IDE integration. Using the plug-in, you can control the dccil compiler from within the IDE, as you can see in the menu installed by this plug-in. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Note, however, that the plug-in does not give you the full capability of designing forms and all the other things Delphi is famous for. The Delphi for .NET Preview compiler is intended to give you some advance warning about new language features and a glimpse into how the Delphi run-time library might look in the .NET context. You can download this plug-in from the Code Central area of the Borland Developer Network website, bdn.borland.com (if you cannot find it, look under the number 18889). Another valuable resource you might want to work with is the Reflector. This tool was written by Lutz Roeder (who happens to work at Microsoft, by the way) and is available on his own website, www.aisto.com/roeder/dotnet. Note Reflector is like Microsoft's Intermediate Language Disassembler (ILDASM) tool—it allows you to inspect .NET assemblies (executables and DLLs) and their types and members. Testing the Installation Now it's time to test your Delphi for .NET Preview installation by compiling a simple console program that prints a message. You can start this project using Delphi 7, or you can type in the text with your favorite editor: program HelloWorld; {$APPTYPE CONSOLE} uses Borland.Delphi.SysUtils; begin WriteLn ('Hello, Delphi! - Today is ' + DateToStr (Now)); end. Notice how similar the code looks to the Delphi applications you're used to. The only difference is the uses clause. Borland has organized the units of the Delphi library into namespaces similar to those of the Common Language Runtime (CLR). I will discuss this in more detail in the next chapter. Save the file as HelloWorld.dpr and open a command window. Navigate to the location of the file and type dccil HelloWorld.dpr The result should be an executable image, HelloWorld.exe, which you can run from the command line to produce a single line of output. If you are using the IDE plug-in, compiling and running the program will involve pressing Ctrl+F9 or F9 after you've enabled IDE hijacking (see the Hijack IDE menu item in the screenshot above). If this program seems boring, you can begin your exploration of .NET using the windowed version of the hello world program instead of the console version. Called HelloWin, this program creates and shows a window on the screen, writing into its caption. It also shows the call to Application.Run, used to activate the application's message processing loop: program HelloWin; uses System.Windows.Forms, This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Borland.Delphi.SysUtils; var aForm: Form; begin aForm := Form.Create; aForm.Text := 'Hello Delphi'; Application.Run (aForm); end. In .NET presentations, the previous code raises the enthusiasm of programmers used to Microsoft development tools. As a Delphi programmer, you might have used almost this same code since 1995, so you might wonder where this excitement comes from. The output of these programs is far from interesting, but you can at least prove they are not classic Win32 applications by running ILDASM on them (directly from the plug-in's menu). You can see the output for the HelloWorld executable in Figure 24.1. Notice that the unit's global code is wrapped in a pseudo class called uUnit . Unlike Delphi, the .NET runtime doesn't account for global procedures and functions, but only class methods. But I'm getting ahead of myself; let's start from the beginning and look at the NET platform. Figure 24.1: The HelloWorld demo as seen in ILDASM This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register . it. Thanks Microsoft's .NET Platform Microsoft's .NET platform comprises many different specifications and initiatives. The core functionality of the .NET platform has been given over to the European Computer Manufacturer's Association (ECMA) and is undergoing the standardization process. At the time of this writing, the C# language specification has just passed ECMA's process and is heading for ISO standardization. Note You can find the standard documents for the C# programming language and the Common Language Infrastructure (CLI) at www.ecma.ch. An interesting element of the CLI specification is the standard naming convention for variables and methods. From the programmer's standpoint, the core feature of the .NET platform is its managed environment, which allows the execution of intermediate code compiled by many different programming languages (provided they conform to a common definition of the base data types). This environment embeds many features ranging from sophisticated memory management up to integrated security, to name just two. On top of this managed environment, Microsoft has built a large class library, covering diverse areas of development (Windows-based forms, web development, web services development, XML processing, database access, and many more). This is only a short overview. To get more into the details we need to learn the precise terms used in the .NET Platform, most of which are indicated by of three-letter acronyms, introduced in the following subsections. The Common Language Infrastructure (CLI) The CLI is the main pillar of the .NET platform. It was submitted to the ECMA in December 2001. The CLI comprises many different specifications: Common Type System (CTS) The CTS lays the groundwork for integrating disparate programming languages. It specifies how types are declared and used, and language compilers must conform to this specification in order to take advantage of the .NET platform's cross-language integration. Extensible Metadata The CLI specifies that every unit of deployment (an assembly) must be a self-describing entity. Therefore, an assembly must carry with it data that fully identifies the assembly (its name, version, and optional culture and public key), data that describes the types defined within the assembly, data listing other files referenced, and any special security permissions that are required. Furthermore, the metadata system is extensible, so an assembly might also contain user-defined descriptive elements, known as custom attributes. Note The term culture is used by Microsoft as an extension of the term's language (the language used for the user messages of a library) and locale (the dates and number formatting settings for a country). The idea is to cover anything peculiar to a country, or portions of a country. Common Intermediate Language (CIL) CIL is the programming language of a virtual execution environment with an abstract microprocessor. Compilers targeting the .NET platform do not generate native CPU instructions, but instead generate instructions in the intermediate language of the abstract processor. In this respect, the CLI is similar to Java byte code. P/Invoke Programs that execute in the .NET runtime each play in their own private sandbox. Unlike the traditional Win32 programming model, a large and complicated layer of software exists between them and the operating system. But the .NET runtime does not completely replace the Win32 API, so there must be a way to bridge between the two worlds. This bridge is called Platform Invocation Service (in short, P/Invoke or PInvoke). Framework Class Library (FCL) The .NET Framework Class Library (FCL), or .NET Framework for short (or even .NET Fx), is a class hierarchy with a design similar to that of Borland's VCL. Features also available in the VCL are actually quite similar, although the .NET Framework has a much larger set of classes (covering many more areas of programming). The architectural This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register . it. Thanks difference between the .NET Framework and the VCL is that the .NET Framework is not only callable from other languages, it can be directly extended by other languages. This means that, as a Delphi programmer, you have the ability to directly inherit from classes in the .NET Framework, just as you would inherit from any other Delphi class. Moreover, the CLI gives you the ability to extend a class written in any language that has a compiler that targets the .NET runtime. The factorable part of the FCL means that parts of the class hierarchy can be factored out; for example, to create a stripped-down version for use on a handheld device. Extended Portable Executable (PE) File Format Microsoft is using its standard Portable Executable (PE) file format (the file format used by standard Win32 executable files) to support the metadata requirements of the CLI. The advantage of using this format is that the operating system can load a .NET application the same way it loads a native Win32 application. Common loading is about where the similarity ends though, since all managed code is in a special section. The framework modifies the loader so when it finds it is dealing with a .NET entity, it passes control over to the CLR that then works out how to call the managed entry points. The Common Language Runtime (CLR) The CLI is a specification, and the CLR is Microsoft's implementation of that specification. Not surprisingly, the CLR is a superset of the specification. To a programmer, the CLR is an all-encompassing run-time library that unifies the vast array of services provided by the Windows operating system and presents them to you in an object-oriented framework. On a larger scale, the CLR is responsible for every aspect of the .NET universe: loading the executable image, verifying its identity and type safety, compiling CIL code into native CPU instructions, and managing the application during its lifetime. CIL code that is intended to be run in the CLR is called managed code, whereas all other code (such as Intel executable code produced by Delphi 7) is unmanaged. Common Language Specification (CLS) Closely related to the Common Type System, the CLS is a subset of that specification that defines the rules that govern how types created in different programming languages can interoperate. Not all languages are created equal, and some languages have features that can't be found elsewhere. The CLS tries to find a happy medium, specifying those items that a large set of languages can implement. Microsoft tried to make the CLS as small as possible, yet still accommodate a large set of languages. Some features of Delphi are not CLS compliant. This does not mean the code cannot be executed by the CLR and work on the .NET platform; it only means you are using a language feature that can't be supported by other languages, so that particular part of your code cannot be used by other .NET applications if they are written in languages other than Delphi. Note If you have experience with Java, you might find some of these items familiar. The .NET platform shares many concepts with the Java platform, in particular the intermediate language and virtual execution system, although with the core difference of Java being pcode interpreted by default, whereas .NET is invariably JIT compiled. There are also relevant analogies in the class libraries. In most cases, however, don't take corresponding Java concepts for granted, because differences in the implementation details might significantly affect how you use an apparently similar feature. The various specifications of the CLI give a glimmer of hope about cross-platform development. But, you probably won't hear the "write once, run anywhere," mantra from Microsoft. This is due to the fact that they consider the user interface to be a key part of an application, and a normal PC screen compared to, say, a mobile phone screen has inherently different capabilities. There are two major ongoing efforts to implement the CLI on other operating systems. The Rotor project (officially called Microsoft Shared Source CLI or MS SSCLI) is written by the Microsoft Research team. Rotor consists of a large donation of software, under Microsoft's Shared Source license, and the necessary tools to build it on the FreeBSD, Win2, and Mac OS X 10.2 operating systems. The second well-known CLI implementation on another operating system is the Mono Project, which supports Win32 and Linux. Mono is building what is essentially a clean-room implementation of the CLI on Linux and is released with a much more open license. Borland has a wait-and-see approach about Mono; there has been no word about whether This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Delphi will be a player in that arena. The Rotor project seems to be aimed toward educators and people who are just curious about how the CLR is implemented, because its license is very open to academia but prohibits any commercial use. The Mono project, however, may give Microsoft some serious competition. The most serious stumbling block to true portability will probably continue to be the graphical user interface. The Rotor project does not include any GUI elements, while Mono has started developing WinForms using the WINE library. There is also a GTK# project associated with Mono, which is a binding of the GTK+ toolkit to the C# language. Today's computing environment is a nebulous mass of diverse possibilities. Handheld devices have complex operating systems of their own, and Microsoft has a keen interest in this arena. Microsoft is working on a version of the .NET platform called the .NET Compact Framework, which is intended for handheld devices. The .NET platform could also serve as a springboard for tomorrow's technologies. Sixty-four bit processors are just around the corner, and .NET will no doubt be running there. Does this mean you can run your managed application on Linux, 64-bit Windows, and your PDA? No. It is not reasonable to expect a user interface geared for a 1600×1200 pixel display on a 21-inch monitor to port to a handheld device. So, regarding .NET as a cross-platform tool, you will gain some advantage, but you should not expect your application to be a straight port especially if you are porting to another operating system or a handheld device. In the following sections, we will examine some components of the CLI in more detail. Assemblies Microsoft coined the term assembly to denote a "unit of deployment" in the .NET runtime environment. In manufacturing, an assembly is a group of separate but related parts that are put together to form a single functional unit. Sometimes an assembly consists of only one part, but it might consist of many. So it is with assemblies in .NET. Typically, an assembly consists of only one file—either a single executable or a dynamic link library. An assembly could consist of a group of related DLLs, or a DLL and associated resources like images or strings. Going back to the manufacturing analogy, each assembly, whether it consists of one part or multiple parts, contains a packing slip called a manifest. A manifest describes the contents of something, and an assembly manifest contains the metadata for an assembly. The manifest is the implementation of the extensible metadata system described in the CLI. As you look through the installation directory for the Delphi for .NET Preview compiler, you will find a units folder. In this folder are a number of files with the extensions .dcua and .dcuil . These are not PE files, so they cannot be examined with ILDASM. A .dcua file catalogs the namespaces and types in a .NET assembly (which, keep in mind, can consist of multiple executable files). A .dcuil file corresponds to a namespace. The .dcuil file contains all the compiler symbols for a namespace, as well as references to the .dcua files that contribute to that namespace (an assembly can contribute types to more than one namespace). Note A namespace is a hierarchical containment mechanism that organizes classes and other types. We will discuss namespaces in more detail in Chapter 25, "Delphi for .NET Preview: The Language and the RTL." An application is built against a certain set of assemblies; the application is said to reference these assemblies. When the set of assemblies changes, the compiler must rebuild any .dcuil files that contain references to .dcua files that are no longer in the set. Likewise, if a change is made to an assembly, the compiler must rebuild the corresponding .dcua and .dcuil files for that assembly. A .dcuil file is roughly equivalent to a Delphi .dcu file, but a .dcua file does not have a corresponding file type in the Delphi for Win32 universe. Different project types produce different types of .NET assemblies: A Delphi program produces an executable assembly; a library project produces a DLL assembly. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . The Intermediate Language The Common Language Runtime is an implementation of a virtual execution system, or virtual machine. Like all virtual machines, the CLR has its own abstract microprocessor. As already mentioned, the assembly language of the virtual processor is called Common Intermediate Language (CIL), although before being promoted as a standard it was called Microsoft Intermediate Language (MSIL), a terms you'll still see around often. Compilers that target the CLR do not generate code in the native instruction set of any specific, real microprocessor. Instead, .NET compilers target the abstract processor of the CLR. The hardware abstraction built into the CLR hints at some cross-platform viability. Remember, Microsoft's CLR is but one implementation of the CLI; any hardware/operating system platform that has a CLI-compliant execution environment built for it could be targeted. Of course, there is no real microprocessor that can execute CIL directly, so it must be compiled to the instruction set of the native hardware prior to execution. This is the job of the Just in Time (JIT) compiler. Here is where the CLR differs from other virtual machine implementations (like Java). The CLR is not an interpreter, nor does it execute bytecode. On the .NET platform, CIL is always compiled to native CPU instructions, and once compiled it is cached in memory; so chances are good that it will never have to be recompiled. Note In some memory-constrained environments (such as a PDA), compiled code can be discarded. In this case, the code would need to be recompiled if it was ever reloaded. Compiling IL is not a very expensive operation (MS Research has spent years developing technology to allow the JIT compilation to be as negligible as possible) but does imply a little overhead and it must be repeated every time you run even the same program. Most applications will see a little increase in startup time (what's particularly slow is loading all the .NET framework itself with the first .NET application run in a Windows session); however, this is limited because not all code in an application is compiled at once. The JIT compiler works in conjunction with the loader, and so IL code is not compiled until it is called (on a method by method basis). JIT compilation is the normal case on the .NET platform, but it is possible to compile a managed executable into native instructions and store the native image on disk. By doing so, you avoid the negative impact of JIT compilation on your application's startup time. The .NET Framework runtime contains a utility called the Native Image Generator (Ngen.exe) to accomplish this. The native image created by Ngen is stored in the native image cache. The next time the CLR tries to load the assembly, it looks in the native image cache first. If a native image of the assembly is found, it is preferred over the IL version. Note that you must also deploy the IL version of the assembly, because the native image does not contain any metadata. In addition, the end user or administrator could remove your native image from the cache. In this case, there would be no native image to find, and the CLR would revert back to the usual JIT compilation of the IL version. The ability to generate a native executable image can be helpful, but you should profile your application under both environments (JIT and native image) to see whether the detrimental effects of the JIT compiler are that bad. The JIT compiler is, after all, a real compiler for a specific microprocessor, and as such it can do some performance optimizations of its own. It employs good algorithms to reduce its overhead and also introduces optimizations to the compiled code (somewhat like Delphi does in its compilations). Looking over the IL code generated by your compiler can be highly educational. Microsoft provides a utility called the IL Disassembler (ildasm.exe) that you can use to dissect your assemblies at the lowest level. Located in the bin directory of your .NET Framework SDK installation, ildasm can load any assembly and its metadata: the manifest, the classes, their methods and properties, and, of course, the IL code generated by the compiler. We will look more at ILDASM in this chapter and the next. The Reflector tool mentioned earlier is also useful in this regard. Managed and Safe Code Simply put, managed code is any code that is loaded, JIT compiled, and executed under the auspice of the CLR. Like all executable and library modules on the Windows platform, managed code modules are stored in Microsoft's Portable Executable (PE) file format. A managed PE file contains additional header information and, when loaded, jumps into the runtime's execution engine (to a function in MSCorEE.dll). This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . The runtime initializes, and then it looks for the module's entry point. The IL code in the entry point is JIT compiled to native CPU instructions. Finally, execution begins at the module's entry point. The situation is similar for a library module; the PE file directs the loader to jump to a different function in MSCorEE.dll. In contrast, unmanaged code consists not of IL, but rather of traditional, native CPU instructions. Unmanaged code executes outside of the runtime and therefore can't take advantage of the services provided by the CLR—at least not without special measures. Unmanaged code can create .NET Framework classes using COM Interop services. The .NET Framework class is wrapped in a COM proxy and exposed to unmanaged code as if it were a COM object. The COM Interop bridge goes the other way too, allowing a COM objects in a COM server to be accessed by managed code. Finally, the Platform Invoke services of the CLR allow managed code to call the Win32 API directly. Note The Delphi for .NET Preview compiler produces fully managed code. There is currently no support for mixing managed and unmanaged (native) code within the same module, as you can with Microsoft's Visual C++ .NET (which uses a mechanism called IJW: It Just Works). A module is completely self-describing, because it contains both IL code and metadata that describes the data elements used by the code. Taking the IL code and the metadata together, the CLR can perform another level of verification beyond the static checking done by the compiler. This process, which is always performed unless a system administrator turns it off, verifies that code is type safe. Verifiably type-safe code is known as safe code. Safe code passes the following type-safety checks: Only valid operations are invoked on objects. This includes parameter validation, return type verification, and visibility checks. Objects are always assigned to compatible types. The code uses no explicit pointers, as they might refer to invalid memory locations. As you'd expect, unsafe code fails to pass these checks. But, just because code is not verifiably type safe does not mean it is unsafe; it simply means the code could not be verified, either due to a limitation in the verification process, or perhaps in the compiler itself. When it will be released as a finished product, the Delphi for .NET compiler is expected to generate verifiably type-safe code. Some Delphi language constructs are not CLS compliant, but this is different than not being verifiably type safe. Non-CLS-compliant language constructs will be covered more in Chapter 25. The .NET Framework SDK contains a PEVerify utility that exhaustively analyzes a managed PE for type safety (peverify.exe). The Delphi 7 IDE plug-in mentioned previously lets you automatically run PEVerify on your code after every build. The Common Type System The Common Type System (CTS) is the bulldozer that levels the playing field for programming languages in the .NET framework. The CTS fully specifies the primitive types and object types known to the CLR. These types are used to define an object model that is shared among all languages that target the CLR. The Component Object Model (COM) has been the usual way to achieve binary compatibility and language interoperability on the Windows platform. The CTS goes beyond that, allowing languages as different as Eiffel, C#, and Delphi to integrate with each other. Components written in these disparate languages can pass objects among themselves and directly extend their capabilities through inheritance. This level of integration of programming languages is unprecedented. All types defined by the CTS fall into two categories: value types and reference types. Value types, as their name implies, have pass-by-value semantics. For example, say you have a variable that is a value type. If you pass this variable as a parameter to a function and modify the parameter within the function, the original variable will be unaffected. Examples of value types include scalar types, enumerations, and records. Aggregate types such as Delphi records (or C# structures) are known as value classes within the CTS. On the other hand, reference types have alias, or pass-by-reference, semantics. If you have a variable that is a This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . reference type (for example, an instance of a class) and you pass that variable as a parameter to a function, any changes you make to the parameter will also affect the variable. Examples of reference types include class types and interfaces. Pointer types are also reference types, as are delegates, which will be discussed shortly. Objects and Properties Like Delphi, the CTS implements a single-inheritance model. A class must inherit from one and only one ancestor and may declare itself to be an implementer of zero or more interfaces. Other familiar object-oriented attributes of the CTS are private, public, and protected visibility of classes and class members (with other visibility specifiers available, as discussed in the next chapter). These CTS visibility specifiers have meanings similar to those in Delphi; however, they are more restricted, in line with C++ semantics. (In Chapter 25 we'll look at how Delphi's visibility specifiers map to the CTS versions, and examine the specific changes made to the language thus far to accommodate additional features of the CTS.) As you peruse the .NET literature, you will notice similarities between the capabilities of CTS class types and Delphi classes. The traditional object-oriented features of fields and methods are supported, of course. In addition, the CTS implements properties in a way that is conceptually similar to the familiar Delphi notion. Properties in CTS can have read and write access methods that restrict or compute values on the fly, or they can simply mask private fields. However there are also many differences, including the fact that property get/set methods must have the same visibility as the property itself to ensure languages that don't support property syntax can still access the property. Although Delphi doesn't enforce this in the source code, it modifies compiled code behind the scenes if necessary. Events and Delegates One reason the Win32 API has survived so long is that at its lowest levels it is based on fundamental concepts, such as using the address of a function as a callback mechanism. The entire Windows user interface event system is based on callback functions (and some of events in the VCL framework are built on top of even that system). The callback mechanism is so powerful that it surely must make its way into the CTS. Using callbacks in a type-safe, language-neutral way relies on a reference type called a delegate. CTS delegates are different from ordinary function pointers, in that they can reference both static and instance methods of a class. The declaration of a delegate must match the signature of the methods the delegate will reference. In Delphi for .NET, usage of delegates is similar to that of familiar procedural types: type TMyClass = class public procedure myMethod; end; var threadDelegate: System.Threading.ThreadStart; tmc: TMyClass; aThread: System.Threading.Thread; begin tmc := TMyClass.Create; threadDelegate := @tmc.myMethod; aThread := Thread.Create (threadDelegate); aThread.Start; The threadDelegate variable is of type System.Threading.ThreadStart, which is a CLR delegate class. Methods you assign to a delegate have a signature matching the delegate's, which in this case is a procedure taking no parameters. (You can find this code snippet in the Delegate sample folder.) The compiler is hiding a lot of complexity here. Behind the scenes, the compiler must create an instance of the class System.MulticastDelegate. The delegate—the function being encapsulated (myMethod in this case)—is invoked using methods on the MulticastDelegate class. This class supports the simultaneous encapsulation of multiple functions in a single delegate. In a user interface event model, this translates to having multiple listeners for an event. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Note Incidentally, the fact that delegates are classes tells you why you can declare a delegate outside the scope of a class. Because delegates are instances of System.MulticastDelegate (or a compiler-generated descendant class), you can declare them anywhere you can declare a class. Each specific language compiler implements some form of semantic sugar to make the creation of events and the addition and removal of event listeners less painful. For example, in C#, Microsoft used the += and -= operators to add and remove functions from the underlying delegate. Delphi for .NET uses set semantics for the same purpose. In Chapter 25 we'll explore this topic, showing how the functions Include and Exclude are used to assign event handlers. We'll also look at how Delphi's := assignment operator works, with regard to assigning event handlers in the .NET universe. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Garbage Collection The garbage collector is that part of the CLR that performs automatic management of memory allocation and deallocation. All Delphi 7 offers in this respect is reference counting for interface-based variables (see Chapter 2 for details). When there are no more references to an object, the memory for it is reclaimed. This is also the basic idea of the CLR garbage collector, but the similarities stop there. The CLR's garbage collector can detect that two objects are still referring one to the other, but there is no other reference to them, so they can be discarded, something a reference counting system (like the one in Delphi) fails to handle. Using a GC means you can create objects, reference one from another as you need, and simply forget about the hassles of deleting those objects. The system will do all that's needed for you. That's all you really need to know. Note that this implies that you don't need to balance object creation and destruction in your code architecture, nor do you need to use try/finally blocks to make sure objects are destroyed; these are just a couple of specific circumstances in which you'll benefit from a GC. Only when you need to write low-level classes will you have to remember to free unmanaged resources, such as window or file handles. The CLR class System.Object contains a protected Finalize method that you can override to free up unmanaged resources. You must be aware of some important things before you begin overriding Finalize. (If you want some in-depth information on this topic, see the sidebar "Issues with Overriding Finalize.") Issues with Overriding Finalize Overriding the Finalize method is inefficient because it requires your object to make at least two trips through the garbage collector. The job of the garbage collector is to reclaim memory, and it can't do this until it runs your object's Finalize method. So, the garbage collector must give special treatment to all objects with Finalize methods. It puts them on a special list, which has the side effect of keeping them alive through this round of garbage collection (because there is now another reference to the object). Eventually, a thread walks through the special list, runs each object's Finalize method, and removes the object from the list. Removing the object from the list takes away the last reference to it, so next time the garbage collector runs, the object's memory can be reclaimed. But inefficiency is not the only problem with finalizers. You also can never be sure when your object's finalizer will run. If you are relying on the Finalize method to give back unmanaged resources, the object might hold onto these resources longer than you expect. When Finalize runs, it does not run in the same thread of execution as your object. This means all thread synchronization and blocking must be avoided, because it's not your thread you are blocking, it's the CLR's finalizer thread. On a related note, if an exception is thrown from Finalize the CLR catches it, not you, and the exception will be swallowed. The recommended approach for freeing up unmanaged resources is to implement the dispose pattern. This is a strategy for providing an object both an automatic way to dispose the external resources it refers to when it is garbage collected and also a way to free the same resources upon the direct invocation of a method. In real terms, coding this pattern equates to implementing an interface called IDisposable. IDisposable consists of one method: Dispose. The IDisposable interface gives you deterministic control over freeing up resources used in your objects. Unlike Finalize, the Dispose method is public and is meant to be called by you (or users of your class), not by the garbage collector. You may have read .NET literature explaining how the C# language implements destructor semantics by having the compiler create a Finalize method on your class behind the scenes. To implement the IDisposable interface in C#, you must do so directly and wire everything so that the Dispose method can be called directly or from the automatically generated Finalize method. This is not the way things work in Delphi for .NET. Creating a destructor for your class does not cause the compiler to implement a finalizer behind the scenes. Instead, it causes the compiler to implement the IDisposable interface. But nothing is stopping you from implementing IDisposable This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . directly, so if you want to rely on the compiler's behind-the-scenes magic, you must follow a strict pattern. Your class destructor must be declared exactly as shown here: destructor Destroy; override; When the compiler sees this declaration, it generates code to mark your class as an implementor of IDisposable. Then, using a feature of CIL, your destructor is marked as the implementation of the Dispose method (this can be done even though the name of the method is Destroy, not Dispose). The usual way to dispose of objects in Delphi is to call the Free method on the object. In Delphi for .NET, the Free method is implemented so that it tests to see whether the object implements the IDisposable interface. If you follow the previous destructor signature, the compiler implements it for you; Free then calls Dispose, which winds up in your Destroy method. Let's create a project and declare a class with a destructor that follows the pattern. Then you'll use ILDASM to inspect the generated code. The code is available in Listings 24.1 and 24.2. Listing 24.1: The Project of the DestructorTest Example program DestructorTest; {$APPTYPE CONSOLE} uses MyClass in 'MyClass.pas'; var test : TMyClass; begin WriteLn ('DestructorTest starts'); test := TMyClass.Create; test.Free; WriteLn ('DestructorTest ends'); end. Listing 24.2: The Unit of the DestructorTest Example unit MyClass; interface type TMyClass = class public destructor Destroy; override; end; implementation destructor TMyClass.Destroy; begin WriteLn ('In destructor (which is actually the IDisposable.Dispose method)'); end; end. After compiling this program you can run it; but we are not so much interested in running the program as in inspecting it with ILDASM. Start ILDASM and select File | Open. Navigate to the directory where DestructorTest.exe is located, and This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . open it. You will see a window similar to that shown in Figure 24.2. Figure 24.2: The ILDASM output for the DestructorTest example The tree entry labeled MyClass represents the namespace created to hold all the symbols in the unit. Expand the MyClass node and notice the entries for TMyClass and Unit. Delphi for .NET creates a CLR class for each unit to implement initialization and finalization and also to let you still write global routines; they become methods of that Unit class. Expand the node for TMyClass and notice the Destroy node, which has a pink block. This node represents the Destroy method in TMyClass. Double-click the Destroy node to open a window displaying the full IL code for this method, as shown in Figure 24.3. Figure 24.3: The ILDASM IL window for the Destroy destructor The line you're looking for uses the .override directive: .override [mscorlib]System.IDisposable::Dispose This is an explicit override, and it says that the Destroy method is the implementation of Dispose in the IDisposable interface. The .override directive is how the thread of execution winds up in your destructor when Dispose is called from Free. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Note The way IDisposable was dealt with illustrates a familiar pattern in the ongoing work on the Delphi for .NET compiler. Unlike C#, Delphi is an old language with a large and loyal following and a sizable existing code base. Borland could not sweep everything aside and mandate a new way of doing things that would break all existing code. The implementation of IDisposable was done in a way that should allow Delphi programmers to continue using familiar paradigms and minimize the impact of porting their existing code to the .NET platform. Garbage Collection and Efficiency Among programmers, the use of a garbage collector (GC) is the topic of many debates. Most programmers like the fact that a GC helps them reduce the chance of memory management errors. Some programmers, though, fear that a GC might not be efficient enough, a fear that often prevented the widespread use of this technology. The inefficient GC of the early Java virtual machines didn't really help in this respect. Even Microsoft has a hard time convincing all programmers to use its GC, up to the point that they overrate their solution depicting it as perfect. Even in Microsoft technical documentation about the GC, you'll find lots of hype and little facts. Note This is not to say that the GC doesn't do an adequate job; quite the contrary. But it works differently than it is presented. At present, your only way to know how the GC works is to write test case programs and study their effect. As a starting point for your exploration, you can use the GarbageTest example. Use a Windows memory analysis tool to see how the memory is affected by program execution. The GarbageTest example declares the following class of large objects (about 10 KB): type TMyClass = class private data: Integer; list: array [1..10240] of Char; s: string; public constructor Create; end; The simplest test code is the following: for i := 1 to 10000 do begin mc := TMyClass.Create; WriteLn (mc.s); end; Writing this simple program in Delphi will flood the memory, because there is no call to Free. In .NET, however, the GC reuses the single memory block, so memory consumption is flat. If you save each object in an array declared as objlist: array [1..10000] of TMyClass; the memory consumption will increase at each cycle of the loop, causing problems! Keeping the object references in memory and then releasing them regularly or randomly can provide more complex tests. You'll find a few snippets in the program code, but you'll have to exercise your knowledge and imagination to build other significant test cases. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Deployment and Versioning Most Windows software developers have at some point felt the pain caused by deploying shared libraries. The .NET Framework can adapt to a number of different deployment scenarios. In the simplest scenario, the end user can copy files to a directory and go. When it's time to remove the application from the machine, the end user can remove the files, or the entire directory, if it doesn't contain any data. In this scenario there is no installer, no uninstaller, and no registry to deal with. Tip You can package your application for the Microsoft Installer if you want to and still deploy to a single directory, with no Registry impact. Outside of the easy scenario, the deployment options become complex and a bit bewildering, because the problem itself is complicated. How do you enable developers to deploy new versions of shared components, while at the same time ensuring that the new version won't break an application that depends on behavior provided by a prior version? The only answer is to develop a system that allows differing versions of the same component to be deployed side-by-side. The first thing you need to learn about deployment in the .NET Framework is that the days of deploying shared components to C:\Windows\System32 are gone. Instead, the .NET Framework includes two kinds of assemblies, well-defined rules governing how the system searches for them, and an infrastructure that supports the deployment of multiple versions of the same assembly on the same machine. Before talking about the two kinds of assemblies, I will explain the two kinds of deployment: Public, or Global A publicly deployed assembly is one you intend to share either among your own applications or with applications written by other people. The .NET Framework specifies a well-known location in which you are to deploy such assemblies. Private A privately deployed assembly is one you do not intend to share. It is typically deployed to your application's base installation directory. The type of assembly you create depends on how you intend to deploy it. The two types of assemblies are as follows: Strong Name Assemblies A strong name assembly is digitally signed. The signature consists of the assembly's identity (name, version, and optional culture plus a key pair with public and private components). All global assemblies must be strong name assemblies. The name, version, and culture are attributes of the assembly, stored in its metadata. How you create and update these attributes depends largely on your development tools. Everything Else There is no official name for an assembly that does not have a strong name. An assembly that does not have a strong name can only be deployed privately, and it cannot take advantage of the side-by-side versioning features of the CLR. The key pair that completes the signing of a strong name assembly is generated by a tool provided by the .NET Framework SDK, called SN (sn.exe). SN creates a key file, which is referenced by the assembly in an attribute. The signing of an assembly can only take place when it is created, or built. However, in the form of signing called delayed signing, developers work only with the public part of the key. Later, when the final build of the assembly is prepared, the private key is added to the signature. Currently the Delphi for .NET compiler is weak on custom attributes. Because attributes are required to express the identity and reference the key file, support for strong name assemblies isn't quite complete at the time of writing. Strong name assemblies are usually intended to be shared, so you deploy them in the Global Assembly Cache (GAC) (but they can be deployed privately as well). Because the GAC is a system folder with a specialized structure, you can't just copy the assembly there. Instead, you must use another tool contained in the .NET Framework runtime, called GACUTIL (gacutil.exe). GACUTIL installs files into and removes files from the GAC. The GAC is a special system folder with a hierarchy that supports side-by-side deployment of assemblies, as you can see in Figure 24.4. The intent is to hide the structure of the GAC so you don't have to worry about the complexities This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it.. Thanks involved. GACUTIL reads the assembly's identity from its metadata and uses that information to construct a folder within the GAC to hold the assembly. Figure 24.4: .NET's Global Assembly Cache as see in Windows Explorer Note You can see the true folder hierarchy by opening a command window and navigating to the C:\Windows\assembly directory. This hierarchy is hidden from you if you use Windows Explorer to view it. When you create a reference to a strong name assembly in the GAC, you are creating a reference to a specific version of that assembly. If a later version of that same assembly is deployed on the machine, it will be put into a separate location in the GAC, leaving the original intact. Because your assembly referenced a specific version, that's the version it always gets. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. What's Next? Your reaction to the .NET initiative will depend on your programming background. If you come from the Java environment, from a traditional Windows tool (even if object-oriented), or from Delphi, you may find many new features or many concepts you are already familiar with. The .NET platform is a technical achievement that offers a staggering array of options and possibilities. Compared with the earlier Microsoft system interfacing technologies (the Windows API and COM), the progress is significant. The best part is that you can take advantage of the platform using the tools and languages you feel are best for the job, soon including Delphi. In Chapter 25 we will examine specific changes to the Delphi language. We will look at deprecated features and types, new features that have already been added to the language, and examples demonstrating the use of .NET Framework classes from Delphi for .NET. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Chapter 25: Delphi for .NET Preview: The Language and the RTL Overview The last chapter introduced Microsoft's .NET architecture. Now it is time to focus on the Delphi for .NET Preview that ships with Delphi 7. This chapter will cover specific changes that were made to the Delphi language to make it compatible with the Common Language Runtime. There have been some important additions to the language, such as namespaces and new visibility specifiers. Other long-standing features of the language had to be dropped because they are not supported in a type-safe environment. This chapter discusses areas of the new compiler including the use of some of Microsoft's own class libraries for .NET and ASP support. Bear in mind that the Delphi for .NET compiler is still being crafted as I write this. Borland's plan was to release the Preview compiler with Delphi 7 and to provide periodic updates to registered Delphi customers throughout the remainder of 2002 and in the early 2003 (before the Galileo project is completed). Some of the language features discussed here may not be implemented, or may be in varying states of completeness, depending on which version of the compiler you are working with. At the end of this chapter I list web resources you can monitor to keep abreast of the changes and latest news regarding Borland's Delphi for .NET compiler. Note As was true in Chapter 24, most of this material comes from John Bushakra. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Deprecated Delphi Language Features We will begin by looking at some of the Delphi features that had to be dropped (deprecated) in order to be compatible with the Common Language Runtime (CLR). Then we'll look at new features added (or planned) in Delphi for .NET, which will shape the Delphi language in the near future, possibly also on the Win32 and Linux platforms. Deprecated Types Some of Delphi's types will not survive the transition to a managed, virtual execution system. So far, the following types are either known to be deprecated or have uncertain fates: Pointers Pointers are considered unsafe types by the CLR, and all forms of pointer arithmetic are forbidden. Unsafe means the code cannot be verified for type safety. The final version of the Delphi for .NET compiler may support unsafe, unmanaged pointers, but in the meantime you can use dynamic arrays to get back some of the functionality of the (also deprecated) GetMem , FreeMem, and ReallocMem functions. Types Based on file of supported because the compiler has no way to determine the size of a given type on the target platform. Pre-Delphi Object Syntax The pre-Delphi object syntax has been deprecated and will not be supported in the final release of the compiler. This syntax was introduced back in the Turbo Pascal era and allowed you to declare a new class with the syntax type MyClass = object;. Variables of this type were stack-based, contrary to the heap-based class type objects. Real48 and Comp These types won't be supported. Real48 type is a 6-byte floating-point type. The Comp type will be replaced by Int64 in the future, as noted in the Delphi 7 Language Reference. Strings and Other Types The following types, although not candidates for deprecation, will have changes made to their underlying implementation. These changes are almost transparent, but you can expect slightly different behavior in some circumstances: Strings In Delphi for .NET, strings map to the CLR type System.String and are wide by default. This means they use 16 bits per character, like the WideString type in Delphi 7. In addition, all characters are wide by default. Records Records are mapped to value types. Chapter 24, "The Microsoft .NET Architecture from the Delphi Perspective," talked about the two main categories of types specified by the Common Type System (CTS): reference types and value types. A record will be a value type on the .NET platform. The CLR demands that value types cannot have inheritance, but you can define methods on them (which, of course, is completely new to the Delphi language). Methods defined on value types must be declared as final. (The new final keyword is discussed in "New Delphi Language Features" section.) TDateTime In Delphi, this type is based on the same implementation as Microsoft's DATE type (see Chapter 2, "The Delphi Language," for more details). The .NET platform uses a different implementation. The System.DateTime structure (a descendant of System.ValueType) measures time from midnight, January 1, 0001 C.E. (Common Era) to 11:59:59 P.M., December 31, 9999 C.E. On this clock, one tick equals 100 nanoseconds. Going forward, Delphi for .NET will transition to the .NET platform standard for measuring time. Date calculations that depend on the floating-point implementation will require your attention when porting to the .NET platform. In particular, if you are using Delphi's Trunc and Frac functions to separate the date and time portions of the floating-point value, then you could be in for some interesting bugs in the future. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Currency Currency will be mapped to the CLR type System.Decimal. Deprecated Code Features As is the case with the types listed in the previous section, some Delphi features that have been part of the language a long time cannot be ported to the .NET platform: Variant Records Variant records with overlapping fields are not supported by the CLR. In general, you can't make any assumptions regarding the layout of fields in a record declaration, because the Just In-Time (JIT) compiler reserves the right to optimize things to suit the underlying platform. ExitProc Things don't always happen when you'd like them to, or in the order you'd like them to. Such problems with unit initialization and finalization have been overcome (although there are still issues to be aware of, as I discuss later in this chapter), but ExitProc is not supported. Dynamic Aggregation of Interfaces The CLR doesn't support dynamic aggregation of interfaces using the implements keyword, because it cannot be verified for type safety. A class must declare all interfaces it will implement. ASM Statements ASM statements and inline assembly language are not supported by the Delphi for .NET Preview compiler. The future of asm in the final version is doubtful. The compiler would have to be able to mix managed IL (Intermediate Language) and unmanaged native CPU instructions, like Microsoft's Visual C++ compiler. automated Keyword The automated keyword was created to support OLE Automation. It is not needed in the .NET environment. The same is true for the dispid keyword, which is used to dispatch COM Automation methods by number instead of by name. Notice that although they're no longer explicitly required, GUIDs are supported on the .NET platform; they appear as custom attributes on a type. Direct Memory Access Functions Direct memory access functions like BlockRead , BlockWrite, GetMem , FreeMem, and ReallocMem, as well as Absolute, and Addr, all deal with unmanaged pointers, and so cannot be used with managed, safe code. The @ operator is available in the current Preview version of the compiler (but is not expected to remain in the final version), although you cannot type cast pointers or do any pointer arithmetic. Note As discussed in Chapter 2, Delphi 7 provides a new set of compiler warnings to help you get ready to port your code. These warnings flag certain features and language constructs that are known to be unsafe on the .NET platform and therefore should be avoided. The warnings are turned off by default for a new Delphi 7 project but are active when you recompile an existing project. You can also turn them on with the {$WARN UNSAFE_CODE ON} compiler directive and similar directives. Refer toChapter 2 for more details. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . New Delphi Language Features The first release of the dccil compiler included new features required by the CLR, and more have been added in subsequent updates. Unit Namespaces Namespaces play an important role in the .NET Framework. They allow the class hierarchy to be extended by multiple third parties without fear of conflicting symbol names. Windows and COM use a 16-byte GUID to uniquely identify components, and this magic number must be recorded in the system registry. On the .NET platform, the concept of namespaces—plus metadata and the hard-and-fast rules about locating assemblies—makes GUIDs obsolete. Ironically, the idea of a Delphi unit is similar to the CLR's namespaces. It's not too far a leap, if you think of a unit as a container of symbols, and a namespace as a container of units. In Delphi for .NET, the namespace to which a unit belongs is declared in the unit clause: unit NamespaceA.NamespaceB.UnitA; The dots indicate the containment of one namespace within another, and ultimately of the unit within the namespace. The dots separate the declaration into components, and each component—up to but not including the rightmost one—is a namespace. The entire declaration taken as a whole, dots and all, is the unit name. The dots simply serve as separators; no new symbols are introduced by the declaration. In this example, NamespaceA.NamespaceB is the namespace, and NamespaceA.NamespaceB.UnitA is the name of the unit. NamespaceA.NamespaceB.UnitA.pas would be the name of the source file, and the compiler would produce an output file called NamespaceA.NamespaceB.UnitA.dcuil . The program statement (and eventually the package and library statements) optionally declares the default namespace for the entire project. Otherwise, the project is called a generic project, and the default namespace is that specified by the –ns compiler option. If no default project namespace is specified with compiler options, then behavior reverts to not using namespaces, like in Delphi 7 (and prior releases). The unit clause does not have to declare membership in any explicit namespace. It might look like a traditional Delphi statement: unit UnitA; A unit that does not declare membership in a namespace is called a generic unit. Generic units automatically become members of the project namespace. Note, however, that this does not affect the source filename. Warning At the time of this writing, namespace support is very limited; this section describes how it should work in the future, rather than how it works now. In the project file, you can specify a namespaces clause to list a set of namespaces for the compiler to search when it is trying to resolve references to generic units. The namespaces clause must appear immediately after the program (or package or library) statement and before any other clause or block type. The namespaces are separated by commas, and the list is terminated with a semicolon. For example: program NamespaceA.MyProgram namespaces Foo.Bar, Foo.Frob, Foo.Nitz; This example adds the namespaces Foo.Bar, Foo.Frob, and Foo.Nitz to the generic unit search space. This discussion leads up to showing you how the compiler searches for generic units when you build your program. When you use a unit and fully qualify its name with the full namespace declaration, there is no problem: uses Foo.Frob.Gizmos; The compiler knows the name of the dcuil file (or the .pas file) in this case. But suppose you only said the following: uses Gizmos; This is called a generic unit reference, and the compiler must have a way to find its dcuil file. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . The compiler searches namespaces in the following order: 1. The current unit namespace (if any) 2. The default project namespace (if any) 3. The namespaces listed in the project's namespaces clause (if any) 4. The namespaces specified by compiler options For the first item, if the current unit specifies a namespace, then subsequent generic unit references in the current unit's uses clause are looked for first in the current unit's namespace. Consider this example: unit Foo.Frob.Gizmos; uses doodads; The first search location for the unit doodads would be in the namespace Foo.Frob. So, the compiler would try to open Foo.Frob.Doodads.dcuil. Failing this, the compiler would move on and prefix the unit name doodads with the default project namespace, and so on down the list. The same symbol name can appear in different namespaces. When such ambiguity occurs, you must refer to the symbol by its full namespace and unit name. If you have a symbol named Hoozitz in unit Foo.Frob.Gizmos, you can refer to the symbol with either Hoozitz; // if the name is unambiguous Foo.Frob.Gizmos.Hoozitz; but not with Gizmos.Hoozitz; // error! Frob.Gizmos.Hoozitz; // error! Unit and namespace names can become quite long and unwieldy. You can create an alias for the fully qualified name with the as keyword in the uses clause: uses Foo.Frob.DepartmentOfRedundancyDepartment.UIToys as ToyUnit; Unit aliases introduce new identifiers, so their names cannot conflict with any other identifiers in the same unit (aliases are local to their unit). Even if you declare an alias, you can still use the original, longer name to refer to the unit. Note The case of a namespace declaration is preserved and emitted into assembly metadata as is. However, as far as Delphi is concerned, two namespaces that differ only in case are equivalent. Extended Identifiers The cross-language integration of the CTS and CLR brings up some interesting situations for compiler developers. For example, what if the name of an identifier in an assembly is the same as one of your language keywords? Consider the Delphi language keyword type. Type is also the name of a CLR class. Because type is a language keyword, it cannot be used as the name of an identifier. You can avoid this problem two ways in Delphi for .NET (these techniques were not implemented in Delphi 7 and previous versions). First, you can use the fully qualified name of the identifier: var T: System.Type; The second, shorter way is to use the new ampersand operator (&) to prefix the identifier. The following has the same effect as the previous example: var T: &Type; In this statement the ampersand tells the compiler to look for a symbol with the name Type and to not consider it as a keyword. The compiler will look for the Type symbol in the available units, finding it in System (the same mechanism works regardless of the unit defining the symbol). This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register . it. Thanks The final and sealed Keywords Two more concepts specified by the Common Language Infrastructure (CLI) have been added to the Delphi for .NET compiler: the class attribute sealed and the method attribute final . Putting the sealed attribute on a class effectively ends the class's ability to be used as a base class. Here is a sample code snippet: type TDeriv1 = class (TBase) procedure A; override; end sealed; A class cannot derive from a class that has been sealed. Similarly, a virtual method marked with the final attribute cannot be overridden in any descendant class, as in the following sample code. type TDeriv1 = class (TBase) procedure A; override; final; end; TDeriv2 = class (TDeriv1) procedure A; override; // error: "cannot override a final method" end; Borland added the sealed and final keywords to map an existing feature of .NET, but why did Microsoft introduce these attributes? The final and sealed attributes give users of your code important insights into how you intend your classes to be used. Moreover, these attributes give the compiler hints that allow it to generate more efficient Common Intermediate Language (CIL). New Visibility and Access Specifiers Delphi's notion of visibility—public, protected, and private—is a bit different from that of the CLI. In languages like C++ and Java, when you specify a visibility of private or protected on a class member, that class member is only visible to descendants of the class in which it is defined. As you saw in Chapter 2, however, Delphi enforces the idea of private and protected only for classes in different units, because everything is visible within a single unit. To be CTS compliant, the language required new visibility specifiers: class private A member declared with class private visibility follows the C++ and Java rules. That is, class private members can be accessed only in methods or properties of the declaring class. Procedures and functions declared at the unit level and methods of other classes do not have access. class protected Similarly, class protected members are visible only within the declaring class, and to descendants of the declaring class. Other classes in the same unit have access only if they inherit from this class. See the ProtectedPrivate example in the LanguageTest folder of the chapter's source code for a trivial test case. Class Static Members Delphi has long supported class methods—methods you can apply to a class as a whole and also as a specific instance, even if the methods' code cannot refer to the current object (the Self parameter of a class methods references the current class, not the current object). Delphi for .NET extends this idea by adding the class static specifier, class properties, class static fields, and class constructors: Class Static Methods Like Delphi 7 class methods, class static members can be called without an object instance, and no Self parameter refers to an object. Unlike in Delphi 7, however, you cannot refer to the class itself. For example, calling the ClassName method will fail. Also unlike in Delphi 7, you cannot use the virtual keyword with class static methods. Class Static Properties Like class methods, class static properties can be accessed without an This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . object instance. The access methods or backing fields for class static properties must be declared class static themselves. Class static properties cannot be published, nor can they have stored or default value definitions. Class Static Fields A class static field can be accessed without an object instance. Class static fields and properties are typically used as design tools; they allow you to declare variables and constants within the meaningful context of a class declaration. Class Constructor A class constructor is a private constructor (it must be declared with class private visibility) that runs prior to the first use of the declaring class. The CLR offers no guarantee of when this will happen, except to say it will happen before the first use of the class. In CLR terms, this can get a bit tricky, because code is not considered "used" unless (and until) it is executed. A class can declare only one class constructor. Descendants can declare their own class constructors, but only one can be declared in any class. You can't call a class constructor from source code; it is called automatically as a way to initialize class static fields and properties. Even the inherited keyword is prohibited, because the compiler takes care of this for you. The following example class declaration illustrates the syntax for these new specifiers: TMyClass = class class private // can only be accessed within TMyClass // Class constructor must have class private visibility class constructor Create; class protected // can be accessed in TMyClass and in descendants // Class static accessors for class static property P1, below class static function getP1 : Integer; class static procedure setP1(val : Integer); public // fx can be called without an object instance class static function fx(p : Integer) : Integer; // Class static property P1 must have class static accessors class static property P1 : Integer read getP1 write setP1; end; Nested Types Nested types are similar to class fields, in that they can be accessed through a class reference; an object instance is not needed. Declared within the scope of a class, nested types give you a way to use the enclosing class as a kind of namespace for the type. Multicast Events Delphi has always had the ability to set an event listener—a function that is called when an event is fired. The CLR supports the use of multiple event listeners so that more than one function can respond when an event is fired. These are called multicast events. Delphi for .NET introduces two new property access methods, add and remove , to support multicast events. The add and remove methods can be used only on properties that are events. To support multicast events, you must have a way to store all the functions that register themselves as listeners. As stated in Chapter 24, multicast events are implemented using the CLR MulticastDelegate class. And, as discussed there, the compiler hides a lot of complexity behind the scenes. The add and remove keywords handle the storage and removal of event listeners, but the containment mechanism is an implementation detail you aren't expected to deal with. The compiler automatically generates add and remove methods for you, and these methods implement storage of event listeners in an efficient way. In the final release of Delphi for .NET, the add and remove methods should work hand in hand with an overloaded version of the standard functions Include and Exclude. In your source code, when you'd want to register a method as an event listener, you call Include. To remove a method, call Exclude. For example: This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Include(EventProp, eventHandler); Exclude(EventProp, eventHandler); Behind the scenes, Include and Exclude will call the methods assigned to the add and remove access functions, respectively. At the time of this writing, this technology wasn't working, so the book examples don't use it. To support legacy code, the Delphi assignment operator ( :=) still works as a way to assign a single event handler. The compiler generates code to go back and replace the last event handler (and only that event handler) that was set with the assignment operator. The assignment operator works separately and independently from the add/remove (or Include/Exclude) mechanism. In other words, the use of the assignment operator does not affect the list of event handlers that have been added to the MulticastDelegate. As an example, you can refer to the XmlDemo program. The following code snippet (the working code at the time of this writing) creates a button at run time and installs two event handlers for its Click event: MyButton := Button.Create; MyButton.Location := Point.Create ( Width div 2 - MyButton.Width div 2, 2); MyButton.Text := 'Load'; MyButton.add_Click (OnButtonClick); MyButton.add_click (OnButtonClick2); Controls.Add (MyButton); Custom Attributes Recall from Chapter 24 that one of the requirements of the CLI is an extensible metadata system. All .NET language compilers are required to emit metadata for the types defined within an assembly. The extensible part of extensible metadata means that programmers can define their own attributes and apply them to just about anything: assemblies, classes, methods, and more. The compiler emits these into the assembly's metadata. At run time, you can query for the attributes that were applied to an entity (assembly, class, method, and so on) using the methods of the CLR class System.Type . Custom attributes are reference types derived from the CLR class System.Attribute . Declaring a custom attribute class is just like declaring any other class (this code snippet is extracted from the trivial NetAttributes project part of the LanguageTest folder): type TMyCustomAttribute = class (TCustomAttribute) private FAttr : Integer; public constructor Create(val: Integer); property customAttribute : Integer read FAttr write FAttr; end; ... constructor TMyCustomAttribute.Create(val: Integer) begin inherited Create; customAttribute := val; end; The syntax for applying the custom attribute is similar to that of C#: type [TMyCustomAttribute(17)] TFoo = class public function P1(X : Integer) : Integer; end; The custom attribute is applied to the construct immediately following it. In the example, it is applied to the class TFoo . No doubt you noticed that the custom attribute syntax is nearly identical to that of Delphi's GUID syntax. Here we have This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . a problem: GUIDs are applied to interfaces; they must immediately follow the interface declaration. Custom attributes, on the other hand, must immediately precede the declaration to which they apply. How can the compiler determine whether the thing in the square brackets is a traditional Delphi-style GUID (which should be applied to the preceding interface declaration) or a .NET-style custom attribute (which should be applied to the first member of the interface)? There is no way to tell, so you have to punt—make a special case for custom attributes and interfaces. If you apply a GUID to an interface, it must immediately follow the declaration of the interface, and it must follow the established Delphi syntax: type interface IMyInterface ['(12345678-1234-1234-1234-1234567890ab)'] CLR's GuidAttribute custom attribute is used to apply GUIDs; it is part of the System.Runtime.InteropServices namespace. If you use this custom attribute to apply a GUID, then you must follow the CLR standard and put the attribute declaration before the interface. Class Helpers Class helpers are an intriguing new language feature added to Delphi for .NET. The main reason for supporting class helpers is the way Borland maps .NET core classes with its own RTL classes, as covered later in the section "Class Helpers for the RTL." Here I will focus on this feature from a language perspective. A class helper gives you a way to extend a class without using derivation, by adding new methods (but not new data). The odd fact, compared to inheritance, is that you can create objects of the original class, which is extended maintaining the same name. This means you can plug-in methods to an existing object of an existing class. A simple example will help clarify the idea. Suppose you have a class (probably one you haven't written yourself—otherwise you could have extended it right away) like this: type TMyObject = class private Value: Integer; Text: string; public procedure Increase; end; Now you can add a Show method to objects of this class by writing a class helper to extend it: type TMyObjectHelper = class helper for TMyObject public procedure Show; end; procedure TMyObjectHelper.Show; begin WriteLn (Text + ' ' + IntToStr (Value) + ' -- ' + Self.ClassType.ClassName + ' -- ' + ToString); end; Notice that Self in the class helper method is the object of the class that the helper is for. You can use it like this: Obj := TMyObject.Create; ... Obj.Show; You'll end up seeing the name of the TMyObject class in the output. If you inherit from the class, however, the class helper will also be usable on the derived class (so you end up adding a method to an entire hierarchy), and everything This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . will work properly. For your experiments, refer to the ClassHelperDemo example in the LanguageTest folder. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . The Run-time Library and VCL Located in the source\rtl directory of the Delphi for .NET Preview installation, you will find the source files for the run-time library (RTL). You can already see the migration of units into CLR namespaces, as reflected in the source filenames. Borland is taking the approach (for the most part) of preserving the original unit name and prefixing it with the namespace name Borland.Delphi. Operating system–specific things (such as registry and ini file utilities) go in the Borland.Win32 namespace, because these classes, procedures, and functions are Borland-specific wrappers of Windows-specific features. The naming trend should continue, although not all units will make the transition, and some will have their contents reorganized into an appropriate namespace. Perusing the RTL source files is both highly educational and highly recommended; however, remember that you are looking at a preview release of a product, not the final version. The contents of the RTL source files are still subject to change—you should not make any assumptions, and you should definitely not introduce dependencies into your own code based on what you see there. Class Helpers for the RTL With the warnings out of the way, let's see what has been done to the RTL so far. The most interesting change is perhaps the introduction of class helpers. Borland.Delphi.System.pas includes the following declaration: type TObject = System.Object; It tells you that Delphi's TObject class is an alias for the CLR class System.Object. This is important: TObject is not a descendant of System.Object—it is semantically equivalent. What happened to the methods that used to be defined in TObject, such as ClassName and ClassParent? That's where the class helper comes in. The methods that used to be directly declared and implemented in TObject are now declared and implemented in a class called TObjectHelper. TObjectHelper is then declared to be a class helper for TObject. In Borland.Delphi.System.pas is the following: type TObjectHelper = class helper for TObject procedure Free; function ClassType: TClass; class function ClassName: string; class function ClassNameIs(const Name: string): Boolean; class function ClassParent: TClass; class function ClassInfo: TObject; class function InheritsFrom(AClass: TClass): Boolean; class function MethodAddress(const Name: string): TObject; class function SystemType: System.Type; function FieldAddress(const Name: string): TObject; procedure Dispatch(var Message); end; A class helper gives you a way to extend a class without using derivation. You might want to extend a CLR class but not derive from it in order to use the CLR class with existing Delphi code. No doubt you've noticed that Delphi's class framework and the .NET Framework share a fair amount of functionality. In some cases there are name clashes between the two—for example, Borland's Exception class and the CLR's System.Exception class. On one hand, the two classes do basically the same thing, but they expose that functionality in different ways. On the other hand, large amounts of existing Delphi code have been using Borland's Exception class for This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. a long time. The only workable solution was to create a mechanism that would allow developers (including Borland) to leverage the CLR classes, and that would also allow the CLR classes to be extended to include long-standing behaviors expected by existing Delphi code. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register . it. Thanks The VCL The .NET Framework classes in the System.Windows.Forms namespace are not a replacement for the GUI portion of the Win32 API. The same happens with most other portions of the .NET Framework: its role is to make the underlying API easier to use by providing an easier object-oriented interface compatible with the core services of the .NET environment. The GUI subset of Win32 is still there, occupying the same place it always has. System.Windows.Forms organizes this GUI subset of the Win32 API, presents it in an object-oriented way, and layers an event model on top of it; but classes in System.Windows.Forms call the unmanaged code in Win32. When you use System.Windows.Forms, you are still calling the Win32 APIs, but now you have a large layer of software called the CLR sitting between your code and Win32. This entire preamble is important to acknowledge why the VCL takes this same approach. TObject is rooted (if you will) from System.Object through the use of a class helper. TPersistent and TComponent still descend from there. Thus the VCL class TForm, for example, is not a descendant of the class System.Windows.Forms.Form. Instead, the entire VCL hierarchy remains much as it is today. TForm will ultimately descend from TWinControl, which itself is a descendant of TControl and then TComponent. If you consider the entire System.Windows.Forms namespace as a single entity, the VCL then becomes a kind of sibling to it, rather than a child of it. Both frameworks ultimately rely on the native, unmanaged Win32 API for the underlying implementation of the user interface controls. Looking into the VCL.NET Source The update of the Delphi .NET Preview compiler made available by Borland in November 2002, although still preliminary, provides details about the architecture the company is planning. If you open the Borland.Vcl.Controls unit, you'll be surprised by its similarity to the Win32 version. The source code is almost identical; the differences exist behind the scenes at the TObject and TComponent level. I've already covered the former, so let's focus on the core component class, which is defined in three steps: type TComponent = System.ComponentModel.Component; TComponentHelper = class helper (TPersistentHelper) for TComponent TComponentSite = class (TObject, ISite, IServiceProvider) The TComponent class corresponds to the .NET Framework class, with a helper providing extra methods and properties and a further class offering the extra data required by the helper class. The situation is complex, and I don't want to get into the details because the TComponent class is marked as experimental and may change in further updates. Getting back to the VCL, a large set of components is already available, so you can begin porting code. The only trouble you'll face with the November 2002 update is that streaming is not supported; so, you must add the component-creation code in the form constructor (an action that will not be required by the final version of Delphi for .NET). As an interesting example to help you figure out the architecture of the VCL classes, I've ported to .NET the ClassInfo example from Chapter 3, "The Run-Time Library." The NetClassInfo example uses this modified code in the project source (again, something you won't have to do in the future): Application.Initialize; Form1 := TForm1.Create (Application); Application.MainForm := Form1; The code for the form, as I've mentioned, has an extra method called by the constructor and used to initialize the controls. This method is quite long, so I'll provide only a few excerpts here: procedure TForm1.InitializeControls; begin // creating all controls... Label3:= TLabel.Create(Self); Panel1:= TPanel.Create( Self); This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks Label1:= TLabel.Create(Self); Label2:= TLabel.Create(Self); ... // setting form properties and events Left:= 217; Top:= 109; Caption:= 'Class Info'; OnCreate:= FormCreate; // initializing controls (only one is listed here) with Label3 do begin Parent:= Self; Left:= 8; Top:= 8; Width:= 56; Height:= 13; Caption:= 'Class Name'; end; The rest of the application's code remains almost identical, which is surprising considering that this is a low-level example. I had to remove the call to InstanceSize, because the compiler cannot resolve the size of an object given the architecture of .NET, and I had to test for the base class against Object instead of TObject. Here is the code snippet that produces the output shown in Figure 25.1: procedure TForm1.ListClassesClick(Sender: TObject); var MyClass: TClass; begin MyClass := ClassArray [ListClasses.ItemIndex]; EditInfo.Text := Format ('Name: %s - Size: %d bytes', [MyClass.ClassName, 0 {MyClass.InstanceSize}]); with ListParent.Items do begin Clear; while MyClass.ClassName <> 'Object' do begin MyClass := MyClass.ClassParent; Add (MyClass.ClassName); end; end; end; Figure 25.1: The NetClassInfo example shows the base classes of a given component. Further VCL Examples . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it.. Thanks To provide starting points for your own experiments with the VCL under .NET, I've built two more examples. NetEuroConv is a port of the EuroConv example from Chapter 3 based on the RTL's conversion engine. NetLibSpeed is a port of the LibSpeed example used in Chapter 5 ("Visual Controls") to compare the VCL and VisualCLX libraries' speed in creating visual components. The number you'll see makes little sense in such a preliminary version of a library, although the fact that VCL.NET takes four to five times as long for the same purpose may worry you. As I mentioned, these examples are meant to be only starting points for your experiments. They may not work with further updates of the Delphi for .NET Preview. Note Stay tuned to my website for updates of this section of the book and the related examples. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Using Microsoft Libraries The VCL is not quite ready, but you can use the .NET Framework class library as a basis for experimentation with the Delphi for .NET Preview compiler. It can be educational to build programs with the compiler and then inspect them with Intermediate Language Disassembler (ILDASM), for instance. This will be the aim of this section. If you want to look at a simpler example using XML support, refer to the XmlDemo mentioned earlier in the chapter. The CLRReflection program opens an assembly and then uses reflection to inspect the modules and types defined within that assembly. This program demonstrates using a common dialog box (the OpenFileDialog), constructing menus, handling events, using Delphi's dynamic arrays, and, of course, reflection. Let's look at the project file first: program CLRReflection; uses System.Windows.Forms, ReflectionUnit; var reflectForm : ReflectionForm; begin reflectForm := ReflectionForm.Create; System.Windows.Forms.Application.Run(reflectForm); end. The code looks almost like a good old VCL application. You define a variable for your main form, and then you create the form. Then you use the Run method of the .NET Framework class System.Windows.Forms.Application. Here the code is analogous (at least in concept) to the way it is done in the VCL. Note that throughout this example I have given the fully qualified name for .NET Framework classes. I did so to make sure you know where these classes are located. Because the uses clause includes System.Windows.Forms, you could shorten the expression System.Windows.Forms.Application.Run(reflectForm); to Application.Run(reflectForm); Now, look at Listing 25.1, which shows the unit where the main form is defined. Note that this code compiles with the November 2002 update of the Delphi for .NET Preview, but not with the version originally shipping with Delphi 7. Listing 25.1: The ReflectionUnit Unit of the CLRReflection Example unit ReflectionUnit; interface uses System.Windows.Forms, System.Reflection, System.Drawing, Borland.Delphi.SysUtils; type ReflectionForm = class (System.Windows.Forms.Form) private mainMenu: System.Windows.Forms.MainMenu; fileMenu: System.Windows.Forms.MenuItem; separatorItem: System.Windows.Forms.MenuItem; openItem: System.Windows.Forms.MenuItem; This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . exitItem: System.Windows.Forms.MenuItem; showFileLabel: System.Windows.Forms.Label; typesListBox: System.Windows.Forms.ListBox; openFileDialog: System.WIndows.Forms.OpenFileDialog; protected procedure InitializeMenu; procedure InitializeControls; procedure PopulateTypes(fileName: String); { Event Handlers } procedure exitItemClick(sender: TObject; Args: System.EventArgs); procedure openItemClick(sender: TObject; Args: System.EventArgs); public constructor Create; end; implementation constructor ReflectionForm.Create; begin inherited Create; SuspendLayout; InitializeMenu; InitializeControls; { Initialize the form and other member variables } openFileDialog := System.Windows.Forms.OpenFileDialog.Create; openFileDialog.Filter := 'Assemblies (*.dll;*.exe)|*.dll;*.exe'; openFileDialog.Title := 'Open an assembly'; AutoScaleBaseSize := System.Drawing.Size.Create(5, 13); ClientSize := System.Drawing.Size.Create(631, 357); Menu := mainMenu; Name := 'reflectionForm'; Text := 'Reflection in Delphi for .NET'; { Add the controls to the form's collection. } Controls.Add(showFileLabel); Controls.Add(typesListBox); ResumeLayout; end; { Build the main menu } procedure ReflectionForm.InitializeMenu; var menuItemArray : array of System.Windows.Forms.MenuItem; begin mainMenu := System.Windows.Forms.MainMenu.Create; fileMenu := System.Windows.Forms.MenuItem.Create; openItem := System.Windows.Forms.MenuItem.Create; separatorItem := System.Windows.Forms.MenuItem.Create; exitItem := System.Windows.Forms.MenuItem.Create; { Initialize mainMenu } mainMenu.MenuItems.Add(fileMenu); { Initialize fileMenu } fileMenu.Index := 0; SetLength(menuItemArray, 3); This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register . it. Thanks menuItemArray[0] := openItem; menuItemArray[1] := separatorItem; menuItemArray[2] := exitItem; fileMenu.MenuItems.AddRange(menuItemArray); fileMenu.Text := '&File'; // openItem openItem.Index := 0; openItem.Text := '&Open...'; openItem.add_Click(openItemClick); // separatorItem separatorItem.Index := 1; separatorItem.Text := '-'; // exitItem exitItem.Index := 2; exitItem.Text := 'E&xit'; exitItem.add_Click(exitItemClick); end; { Create the controls and populate the form } procedure ReflectionForm.InitializeControls; begin { Initialize showFileLabel } showFileLabel := System.Windows.Forms.Label.Create; showFileLabel.Location := System.Drawing.Point.Create(5, 6); showFileLabel.Name := 'showFileLabel'; showFileLabel.Size := System.Drawing.Size.Create(616, 37); showFileLabel.TabIndex := 0; showFileLabel.Anchor := System.Windows.Forms.AnchorStyles.Top or System.Windows.Forms.AnchorStyles.Left or System.Windows.Forms.AnchorStyles.Right showFileLabel.Text := 'Showing types in: '; { Initialize typesListBox } typesListBox := System.Windows.Forms.ListBox.Create; typesListBox.Anchor := System.Windows.Forms.AnchorStyles.Top or System.Windows.Forms.AnchorStyles.Bottom or System.Windows.Forms.AnchorStyles.Left or System.Windows.Forms.AnchorStyles.Right; typesListBox.Location := System.Drawing.Point.Create(8, 46); typesListBox.Name := 'typesListBox'; typesListBox.Size := System.Drawing.Size.Create(610, 303); typesListBox.Font := System.Drawing.Font.Create('Lucida Console', 8.25, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 0); typesListBox.TabIndex := 1; end; { Event handler for the Exit menu item } procedure ReflectionForm.exitItemClick(sender: TObject; Args: System.EventArgs); begin System.Windows.Forms.Application.Exit; end; { Event handler for the Open menu item } procedure ReflectionForm.openItemClick(sender: TObject; Args: System.EventArgs); begin if openFileDialog.ShowDialog = DialogResult.OK then begin This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register . it. Thanks showFileLabel.Text := 'Showing types in: ' + openFileDialog.FileName; PopulateTypes(openFileDialog.FileName); end; end; { Open the given assembly, and reflect over its modules } { and types. } procedure ReflectionForm.PopulateTypes(fileName : String); var assy: System.Reflection.Assembly; modules: array of System.Reflection.Module; module: System.Reflection.Module; types: array of System.Type; t: System.Type; members: array of System.Reflection.MemberInfo; m: System.Reflection.MemberInfo; i,j,k: Integer; s: String; begin try { Clear the listbox } typesListBox.BeginUpdate; typesListBox.Items.Clear; { Load the assembly and get its modules } assy := System.Reflection.Assembly.LoadFrom(fileName); modules := assy.GetModules; {For every module, get all types } for i := 0 to High(modules) do begin module := modules[i]; types := module.GetTypes; { For every type, get all of its members } for j := 0 to High(types) do begin t := types[j]; members := t.GetMembers; { for every member, get type information and add to list box } for k := 0 to High(members) do begin m := members[k]; s := module.Name + ':' + t.Name + ': ' + m.Name + ' (' + m.MemberType.ToString + ')'; typesListBox.Items.Add(s); end; end; end; typesListBox.EndUpdate; except System.Windows.Forms.MessageBox.Show('Could not load the assembly.'); end; end; end. The unit begins by declaring its dependency on .NET Framework dcuil files and on the Borland.Delphi.SysUtils unit. From This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . there it goes straight into declaring the class for the main form, which is a descendent of the .NET Framework class, System.Windows.Forms.Form. The form class layout looks familiar: You have member variables for all the controls, and these are declared to be of types found in the .NET Framework class library. The functions exitItemClick and openItemClick are event handler declarations. The signature of event handler methods is specified by the CLR. All event handlers are procedures that take two parameters: the object that fired the event (a derivative of System.Object) and the event arguments, which are wrapped in the System.EventArgs (or a derived) class. (You will see how to hook up these event handlers in a moment.) Let's move on to the class constructor. I must call attention to the first statement in the constructor, which calls inherited Create. Warning Here you see a major departure from the .NET Framework way of life, compared to what you are used to with the VCL and with Delphi in general. In Delphi, the constructor initializes member variables, putting the object instance into a known-good state; it does not do any memory allocation. So, it is not uncommon to see a constructor make assignments and then call the inherited constructor. Indeed, you might not call the inherited constructor at all. In Delphi for .NET, you can't get away with this approach. In your constructor, you must call inherited Create, and it must be the method's first executable statement. Currently, if you fail to do so, you will get a compiler error saying that Self is uninitialized and that the inherited constructor must be called prior to accessing any ancestor fields. After calling the inherited constructor, you are back in familiar territory. Although this code uses a different class hierarchy, it should be clear to any Delphi programmer. You make an instance of System.Windows.Forms.OpenFileDialog by calling the Create constructor—this is how you create an instance of any .NET Framework class. The next few lines demonstrate setting properties, both of the OpenFileDialog object instance and of the form itself. Finally, you add two controls (a label for the filename and the ListBox that will hold the assembly) to the form's Controls collection, which is a property of type Control.ControlCollection. The InitializeMenu procedure demonstrates allocation and layout of a System.Windows.Forms .MainMenu object instance. Where the File menu is initialized, a dynamic array holds each menu item. The dynamic array is then passed to the AddRange method. This code could have been accomplished by calling the Add method separately for each menu item. The next interesting thing in InitializeMenu is the wiring of the menu item event handlers. In Chapter 24 and earlier in this chapter, I mentioned the behind-the-scenes complexity involved with delegates and multicast events. Here you see some of that complexity coming to the foreground. You can't do it yet in Delphi for .NET, but in other .NET languages such as C#, you can use the language keyword event to introduce an event handler delegate. The event declaration specifies a delegate to use as a callback mechanism. Because the event is a System.MulticastDelegate derivative (a System.EventHandler delegate in this case), other objects can add and remove event handlers, and these handlers are called when the event fires. The C# language adds a bit of syntactic sugar to help this pill go down more easily. C# defines += and -= operators for adding and removing event handlers, respectively. Eventually Delphi will get its own spoonful of sugar, with the Include/Exclude mechanism mentioned previously. CTS mandates that all .NET compilers targeting this event model must generate methods named add_ This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. dynamic arrays for properties that expose a collection with a System.Array. Finally, each individual member of the module and types arrays contains a Name property, which you can use to build a string to display in the ListBox. The final effect of the code is visible in Figure 25.2. Figure 25.2: The CLRReflection example, with an assembly loaded This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . ASP.NET with the Delphi Language You might like it or not (I'm not that fond of it), but Microsoft's ASP technology plays a significant role in the development of web applications, as least on the Windows platform. With the transition to ASP.NET, this technology has fully embraced the .NET Framework; now, with the availability of a Delphi compiler for .NET, the Delphi language can be your language of choice in the development of ASP applications. To create a test, configure IIS to support ASP.NET (I won't cover these steps, which are beyond the scope of this book, but you can find more information on www.asp.net) and then place in the target folder the web.config file distributed by Borland along with the Delphi for .NET Preview (and available in the aspx subfolder). This configuration file defines the mapping of the language to a specific library, again provided by Borland. The core of the file (which uses XML format) has the following elements: To test that the configuration is correct, nothing is better than trying an example. Create a new file (I've called mine aspbase.aspx, available in the DelphiAsp folder of the chapter source code) and type something like the following: ASP.NET with Delphi<% HelloMessage('Delphi for .NET Preview made this'); %>The effect is to execute the Delphi code after transforming this file into a .NET source, compiling it with the Delphi preview compiler, and compiling the IL into assembly code (remember, even scripts in .NET are compiled before they are executed). If everything goes well, the browser should display output like that shown in Figure 25.3. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Figure 25.3: The aspbase.aspx example in a browser From this point on, you can do anything an ASP.NET application provides. The only other example I want to show you is the use of controls with event handlers, which I've covered in a different situation for .NET applications based on Windows forms. This example, saved in the aspui.aspx file in the AspDelphi folder, uses HTML to define a form with a textbox (that is, an edit control) and a button, plus an output label. The button has a Delphi language event handler attached to it, which moves the user input to the label (the output of the program appears in Figure 25.4): ASP.NET with DelphiThis document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Figure 25.4: The output of the aspui.aspx example, after typing in the edit box and clicking the button This has been a limited introduction to ASP.NET with the Delphi language provider. However, it should give you a feeling for the possibilities opening up for Delphi programmers in this new world of .NET. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. What's Next? While you're waiting for the Delphi for .NET product, currently code-named Galileo, you can begin experimenting with the Delphi for .NET Preview that ships with Delphi 7 (and the subsequent updates made available by Borland). Of course, you should stay tuned to Borland's Developer Network website (bdn.borland.com) and newsgroups and to the author's site for update information about this area of Delphi, which is definitely a work in progress. Just as Borland wants to provide the best tools to developers, I hope this book has helped you master Delphi, the most successful tool Borland has brought to the market in the last few years. Remember to check from time to time the reference, foundations, and advanced material I've collected on my website (www.marcocantu.com ). Much of this material could not be included in this book, because of space constraints; see Appendix C, "Free Companion Books on Delphi," for more information. Appendixes A and B discuss some of the add-ins I've built, which are freely available on my site, and a few other notable free Delphi tools. Also check my site for updates and integration of the material in the book, and feel free to use the newsgroups hosted there for your questions about the book and about Delphi in general. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it.. Thanks Appendix A: Extra Delphi Tools by the Author Overview During the last few years I have developed a number of small components and Delphi add-in tools. Some of these tools were written for books or were the result of extending examples from books. Others were written as a helper for repetitive operations. All these tools are available for free, and some include the source code. This appendix provides a list, including in particular tools mentioned in the book. Support for all these tools is available on my newsgroups (see www.marcocantu.com for directions). This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . CanTools Wizards This is a set of wizards you can install in Delphi, either within an extra pull-down menu or as a submenu of the Tools menu). The wizards (freely available at www.marcocantu.com/cantoolsw) are unrelated and offer disparate features: List Template Wizard Streamlines the development of similar list-based classes, each with its own type of objects. This wizard is mentioned in Chapter 4. Because it does a search-and-replace operation on a base source file, it can be used any time you need repeated code and the name of a class (or other entity) varies. OOP Form Wizard (Mentioned in Chapter 4.) Allows you to hide the published components of a form, making your form more object-oriented and providing a better encapsulation mechanism. Start it when a form is active, and it will fill the OnCreate event handler. Then you must manually move part of the code into the unit initialization section. Object Inspector Font Wizard Lets you change the font of the Object Inspector (something particularly useful for presentations, because the Object Inspector's font is too small to be seen easily on a projection screen). Another option available in the settings dialog allows you to toggle an internal feature of the Object Inspector and display the font names (in the drop-down combo box for that property) using a specific font. Rebuild Wizard Allows you to rebuild all the Delphi projects in a given subfolder after loading each of them in sequence in the IDE. You can use this wizard to grab a series of projects (like those in a book) and open the one you are interested in by clicking on the list: You can also automatically compile a given project or start a (slow) multiproject build: In the compiler results dialog, you click a button to proceed only if the corresponding environment option is set. If this environment option is not set, you won't see the compiler errors, because the compiler messages are superceded at every compilation. Clip History Viewer Keeps track of a list of text items you've copied to the Clipboard. A memo in the viewer's window shows the last 100 clipped lines. Editing the memo (and clicking Save) modifies this Clipboard history. If you keep Delphi open, the Clipboard will also get text from other programs (but only text, of course). I've seen occasional Clipboard-related error messages caused by this wizard. VCL Hierarchy Wizard Shows the (almost) complete hierarchy of the VCL, including third-party This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it.. Thanks components you've installed, and allows you to search one class and see many details (base and subclasses, published properties, and so on). Clicking the button regenerates both the list and the tree (in sequence—hence the progress bar runs twice): The list of classes is generated by using predefined core classes (some are still missing; feel free to send suggestions) and then adding each component of the installed packages (Delphi's, yours, third parties'…) along with the classes of all the published properties having a class type. However, classes used only as public properties are not included. Extended Database Forms Wizard Does much more than the Database Forms Wizard available in the Delphi IDE, allowing you to choose the fields to place on a form and also to use a dataset other than those based on the BDE. Multiline Palette Manager Allows you to turn Delphi's Component Palette into a TabControl with multiple lines of tabs: This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. VclToClx Conversion Program You can use this stand-alone tool to convert a Delphi project from VCL to CLX (and vice versa, if you configure it to do so). It can simultaneously convert all the files in a given folder and its subfolders. Here's an example of its output: The program's source code is available in the Tools folder of the book's source code. The VclToClx program converts unit names (based on a configuration file) and handles the DFM issue by renaming the DFM files to XFM and fixing the references in the source code. The program is unsophisticated—it doesn't parse the source code but instead looks for occurrences of the unit names followed by a comma or semicolon, as happens in a uses statement. It also requires the unit name to be preceded by a space, but you can modify the program to look for a comma. Don't skip this extra test; otherwise the Forms unit will be converted to QForms, but the QForms unit will be re-converted to QQForms! This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to registe Object Debugger At design time, you can use the Object Inspector to set the properties of the components of your forms and other designers. In Delphi 4, Borland introduced a run-time Debug Inspector, which has a similar interface and shows similar information. Before Borland added this feature, I implemented a run-time clone of the Object Inspector meant for debugging programs: It allows read-write access to all the published properties of a component, and has two combo boxes that let you select a form and a component within the form. Some of the property types have custom property editors (lists and so on). You can place the Object Debugger component on a program's main form (or you can create it dynamically in code): It will appear in its own window. There is room for improvement, but even in its current form this tool is handy and has numerous users. This component's source code is freely available in the Tools folder of the book's source code. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Memory Snap There are many tools to track the memory status of a Delphi application. During the development of a project, I had to write such a tool, and afterward I made it available. I've written a custom memory manager that plugs into Delphi's default memory manager, keeping track of all memory allocations and de-allocations. In addition to reporting the total number (something Delphi also does now by default), it can save a detailed description of the memory status to a file. Memory Snap keeps in memory a list of allocated blocks (up to a given total number, which can be easily varied), so that it can dump the contents of the heap to a file with a low-level perspective. This list is generated by examining each memory block and determining its nature with empirical techniques you can see in the source code (although they are not easy to understand). The output is saved in a file, because this is the only activity that doesn't require a memory allocation that would affect the results. Here is a snippet of a sample file: 157) 00C035CC: object: [TList - 16] 158) 00C035E0: buffer with heap pointer [00C032B0] 159) 00C03730: string: [5-1]: Edit1 160) 00C03744: object: [TEdit - 544] 161) 00C03968: object: [TFont - 36] 162) 00C03990: object: [TSizeConstraints - 32] 163) 00C039B4: object: [TBrush - 24] 164) 00C039F4: buffer with heap pointer [00C01FE4] 165) 00C03B34: buffer with heap pointer [00C01F18] 166) 00C03B48: string: [0-0]: dD 167) 00C03B58: string: [11-2]: c:\mman.log The program could be extended to profile memory usage by type (strings, objects, other blocks), track unreleased blocks, and keep memory allocations under control. Again, the source code of this component is freely available in the Tools folder of the book's source code. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Licensing and Contributions As you have seen, some of these tools are available with full source code. They are licensed under the LGPL (Lesser General Public License, www.gnu.org/copyleft/lesser.html), which means you can freely use and redistribute them in any way, including making modifications, while the author retains the original copyright. The LGPL doesn't allow you to close-source your extensions, but you can use this library code within programs you sell, regardless of the source code availability. If you extend these tools by fixing bugs or adding new features, I ask you to send your updates to me so I can further distribute the enhancements and we can avoid forking the code into too many versions. The license does not require you to do so, though. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Appendix B: Extra Delphi Tools from Other Sources Thousands of Delphi add-on components and tools are available on the market, ranging from simple freebies to large open-source projects, from shareware programs to highly professional components. This appendix provides a list of notable open-source projects I've mentioned elsewhere in the book. Delphi Preinstalled Open-Source Components Delphi 7 includes the source code for two notable open-source projects: Internet Direct (Indy) This project is covered in detail in Chapter 19, "Internet Programming: Sockets and Indy." The official website for Indy is www.nevrona.com/indy , but you should also refer to the Indy Portal at www.atozedsoftware.com/indy. Support is available on Borland's newsgroups. Open XML This is a Delphi-based XML DOM and SAX engine, which I covered in Chapter 22 ("Using XML Technologies"). Refer to www.philo.de/xml for updates and more information. Support for Open XML is available on a mailing list you can sign up for on the website. Delphi also includes a third open-source project: the ZLib compression library, covered in Chapter 4 ("Core Library Classes"). It isn't listed here because it is not Delphi based. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it.. Thanks Other Open-Source Projects The Delphi programmers' community has been very active since its inception and has produced numerous tools that were and are freely distributed among programmers. A subset of these tools is available with complete source code, as is often true for commercial Delphi components as well. Project JEDI The Joint Endeavor of Delphi Innovators, better known as Project JEDI (www.delphi-jedi.org), is not a single project but rather is the largest community of open-source Delphi developers. The site hosts its own projects, plus others contributed and maintained by members on separate websites. Project JEDI started as an effort to translate APIs for specific Windows libraries distributed by Microsoft or other companies. Making available the Delphi units with the declarations of those APIs allowed any Delphi developer to use them easily. More recently, the goals of Project JEDI have been extended with the definition of many subprojects and groups. In addition to an ever-growing API library, you can find projects including the JEDI Visual Component Library (JVCL), the JEDI Code Library (JCL, a set of utility functions and non-visual classes, including a nice un-handled exception stack tracer), plus many projects in the area of graphics, multimedia, and game programming. Other activities range from a JEDI Version Control System client to the DARTH header conversion kit, from a programmer's editor to online tutorials. Other JEDI-associated projects include Indy (covered earlier), GExperts, and the Delphree site (covered next). GExperts GExperts (www.gexperts.org) is probably the most widespread add-in for the Delphi IDE, providing features ranging from a multiline Component Palette to source code navigation aids. Self-described as "a set of tools built to increase the productivity of Delphi and C++Builder programmers," it includes a large collection of wizards, including Procedure List, Clipboard History, Expert Manager, Grep Search, Grep Regular Expressions, Grep Results, Message Dialog, Backup Project, Set Tab Order, Clean Directories, Favorite Files, Class Browser, Source Export, Code Librarian, ASCII Chart, PE Information, Replace Components, Component Grid, IDE Menu Shortcuts, Project Dependencies, Perfect Layout, To Do List, Code Proofreader, Project Option Sets, and Components to Code. The Delphree Site There are many other Delphi-related projects in the open-source and community development areas. Although I cannot list all the relevant ones here, I can refer you to a website that tries to track all such projects. The Delphree (Delphi Free) website is available at delphree.clexpert.com . This site has a comprehensive list of Delphi open-source projects, ranging from libraries to programmers' tools to end user applications. DUnit Among the many ideas promoted by extreme programming, I find unit testing particularly interesting. Unit Testing is the continuous development of test code even before a program is written. To do this, it is important to have a proper test framework. A group of Delphi programmers created such an architecture, called DUnit. You can find it on SourceForge at dunit.sourceforge.net. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it.. Thanks Appendix C: Free Companion Books on Delphi Overview This is the seventh edition of Mastering Delphi, and I've also written other books, material for classes and conference presentations, and much more; so, in addition to the thousand or so pages this book can accommodate, I have a lot of other material about Delphi programming, particularly introductory material. Over the last few years, I've turned this information into electronic books (in HTML or PDF format) available for free on my website. This appendix outlines the titles and their contents, and provides references to the download pages (all hosted on www.marcocantu.com ). This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Essential Pascal Essential Pascal is an introduction to the foundations of the language invented by Professor Nicklaus Wirth and spread by Borland with its world-famous Turbo Pascal compilers during the 1980s. The 100-page book doesn't cover the OOP extensions, but details many features Borland added to the core language over the years. The following is a list of this e-book's chapters, available at www.marcocantu.com/epascal: Chapter 1: "Pascal History" Chapter 2: "Coding in Pascal" Chapter 3: "Types, Variables, and Constants" Chapter 4: "User-Defined Data Types" Chapter 5: "Statements" Chapter 6: "Procedures and Functions" Chapter 7: "Handling Strings" Chapter 8: "Memory (and Dynamic Arrays)" Chapter 9: "Windows Programming" Chapter 10: "Variants" Chapter 11: "Programs and Units" Chapter 12: "Files in the Pascal Language" Appendix A: "Glossary of Terms" Appendix B: "Examples" As you can see on the website, the book has been translated by volunteers into quite a few languages. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it.. Thanks Essential Delphi Mastering Delphi has changed from an introductory text to an intermediate one as I've tried to cover most of the features Borland has added to Delphi over the years. In the process, I had to cut some of the material aimed at programmers who've never used Delphi or a visual tool. This material is now contained in the Essential Delphi e-book, freely available in PDF format on my site at www.marcocantu.com/edelphi . Here is the table of contents (which is still under development): Chapter 1: "A Form Is a Window" Chapter 2: "Highlights of the Delphi Environment" Chapter 3: "The Object Repository and the Delphi Wizards" Chapter 4: "A Tour of the Basic Components" Chapter 5: "Creating and Handing Menus" Chapter 6: "Multimedia Fun" Chapter 7: "Saving Settings: From INI Files to the Registry" Chapter 8: "More on Forms" Chapter 9: "Delphi Database 101 (with Paradox)" Chapter 10: "Printing" Appendix A: "Essential SQL" Appendix B: "Common VCL Properties" This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it.. Thanks Delphi Power Book Finally, I'm making available more material that covers advanced topics, in a collection called Delphi Power Book. At the time of this writing, only four chapters of this e-book are available: "Graphics in Delphi", "Examples of Using Interfaces", "COM Shell Extensions", and "Debugging." A lot more will come; stay tuned to the website www.marcocantu.com/delphipowerbook. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Index Note to the Reader: Throughout this index boldfaced page numbers indicate primary discussions of a topic. Italicized page numbers indicate illustrations. A About boxes, 289?292, 290 Absolute function, 921 abstract classes, 69, 338 abstract methods, 66?67 AbstractAnimals example, 67 acBoldUpdate method, 229 accelerator keys, 181?182 Access databases, 624 access rights in WebSnap, 808 access specifiers, 48?50, 925 acCountcharsUpdate method, 229 acCutUpdate method, 229 AcManTest example, 244?247, 244 acPasteUpdate method, 229?230 acSaveUpdate method, 229 action objects, 222 Action parameter in close, 279 Action property, 223 ActionBars collection, 244, 246 ActionBoldExecute method, 227 ActionCount object, 227 ActionCountExecute method, 227 ActionEnableExecute method, 227 ActionFont object, 313 ActionFontExecute method, 313 ActionFontUpdate method, 314 ActionIncreaseExecute method, 539 ActionLink object, 223 ActionList component, 173, 222?224, 223 example, 225?228, 226, 228 predefined actions in, 224?225 with toolbars, 229?230 ActionList editor, 226, 226 ActionListUpdate method, 230 ActionMainMenuBar control, 242 ActionManager architecture, 241?242 example, 242?245, 243?244 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks for least-recently used menu items, 245?247, 245 for list actions, 248?250, 249 for porting programs, 247?248 ActionManager component, 242 ActionNewExecute method, 314 ActionOpenExecute method, 314 actions, 173 ActionList for, 222?224, 223 defining, 385?388 example, 225?228, 226, 228 list, 248?250, 249 predefined, 224?225 for toolbars, 229?230 for transactions, 596 Actions example, 225?228, 226, 228 Actions property, 771?772 ActionSaveAsExecute method, 314 ActionSaveExecute method, 315 ActionSaveUpdate method, 314 ActionShowStatusExecute method, 246 ActionToolBar control, 242 ActionTotalExecute method, 539 ActivApp example, 298, 298 activating applications and forms, 298, 298 controls, 159 activation messages, 374 active documents, 456 Active property, 350, 509 ActiveButton component, 372?373, 373 ActiveChange method, 676 ActiveChanged method, 678?679, 683 ActiveForm property, 299 ActiveForm Wizard dialog box, 491 ActiveForms, 491?492 ActiveMDIChild property, 312 ActiveScripting engine, 791 ActiveX Control Wizard, 487?488, 487 ActiveX controls, 456, 483?484 ActiveForms, 491?492 arrow, 487?488, 487 vs. components, 484?485 properties for, 488?489, 488 property pages for, 489?491, 490 in Web pages, 492?493, 493 WebBrowser control, 485?486, 486 XClock, 492?493, 493 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. ActiveX Data Objects. See ADO (ActiveX Data Objects) ActiveX libraries, 34, 460?461, 488 ActiveX page, 461, 487, 489 activity diagrams, 434 actors in use case diagrams, 434 AdapterCommandGroup, 795 AdapterDispatcher component, 787 AdapterErrorList component, 803 AdapterFieldGroup component, 795 AdapterGrid component, 799 AdapterMode property, 801, 803 AdapterPageProducer component, 795?797, 796 for formview page, 802?803 for logins, 807 for main page, 798?801 for master/detail relationships, 803 adapters, 794 AdapterPageProducer for, 795?797, 796 components for, 794?795 fields for, 794 for locating files, 798 scripts for, 797?798 adCriteria constants, 640 Add Field command, 531 Add Fields dialog box, 526, 526 Add Files to Model option, 437 Add method for collections, 382 in Delphi for .NET Preview, 926?927 in TBucketList, 132 in TList, 133 in TMdObjDataSet, 713 in TreeView, 194 in TStringList and TStrings, 128 Add To-Do Item command, 9 Add To Interface dialog box, 488?489, 488 Add to Model option, 437 Add To Repository command, 40 AddChild method, 194 AddChild node, 844 AddColors method, 187?188 AddDefaultCommands property, 796 AddDefaultFields property, 796 AddFilesToList function, 103 Additional page, 180 AddNode method, 197 AddObject method, 187 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Addr function, 921 AddRecord method, 701 _AddRef method, 70, 457 addresses of functions, 63 of methods, 115 in socket programming, 739 AddToList method, 751, 753 AddWebModuleFactory method, 792 AdjustLineBreaks function, 87 administrative components in IBX, 593 ADO (ActiveX Data Objects), 508, 615?616 briefcase model in, 645 client indexes in, 632 cloning in, 633, 633 connection pooling in, 643?644 cursors in, 629?632 Data Link files for, 621 dbGo for, 618?620, 619?620 dynamic properties in, 622 Jet engine for, 624?629, 625?626 locks in, 635?636, 639?641 in MDAC, 616?617 OLE DB providers, 616?617 recordsets in disconnected, 642?643 persistent, 644?645 schema information in, 622?623, 623 transaction processing in, 634?636 updates in, 615 batch, 638?642 joins, 636?637 ADO Cursor Engine, 629 ADO Multi-Dimensional (ADOMD), 617 ADO.NET, 645?646 ADOCommand component, 508, 618 ADOConnection component, 508, 618, 621, 628, 634?635 ADODataSet component, 508, 618?619, 626 ADOExpress, 616 ADOMD (ADO Multi-Dimensional), 617 ADOQuery component, 508, 618?619, 626 ADOStoredProc component, 508, 618?619 ADOTable component, 508, 618?619, 621, 624, 626 ADOUpdatesPending function, 638 ADOX technology, 623 ADTG (Advanced Data Table Gram) format, 644?645 Advanced page, 619 AfterEdit event, 524 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks AfterInsert event, 547 aggregates, 550?552, 550 Aggregates property, 550 aggregation of interfaces, 921 Align property, 181 Alignment dialog box, 19 Alignment property, 528, 658 Alignment toolbar, 718 All page, 619, 624 AllocMemCount variable, 84, 335 AllocMemSize variable, 84, 335 AllocRecordBuffer method, 699 AllowAllUp property, 230 AllowGrayed property, 165?166 AllowHiding property, 244 alpha blending, 267, 267 AlphaBlend function, 267 AlphaBlendValue property, 267?268 AlphaDIBBlend function, 267 alter procedure statement, 565 alter trigger statement, 566 alternatives in XSLT, 864 ampersands (&) for accelerator keys, 181 ancestor classes, 63 AncestorIsValid function, 148 Anchors example, 179?180, 179 anchors for controls, 179?180, 179 Anchors property, 179 angle brackets (<>) in XML, 834 animated displays, 268 AnimateWindow API, 268 annotations on diagrams, 435 AnsiContainsText function, 91 AnsiDequotedStr function, 87 AnsiIndexText function, 91?92 AnsiMatchText function, 91?92 AnsiQuoteStr function, 87 AnsiReplaceText function, 91 AnsiResembleText function, 91 Apache Web Server, 767, 781?872 apartment threading model, 463 AppendRecord method, 701 AppID property, 817 Application Form option, 820 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks application-level interfaces, 615 Application mode in IntraWeb, 815 Application object, 183, 219, 295?297, 793 for activating applications and forms, 298, 298 application window in, 297?298 with DLLs, 411 from TCGIApplication, 771 for tracking forms, 299?302, 300 Application page, 295 application window, 297?298 Application Wizard, 825 ApplicationAdapter component, 788 ApplicationEvents component, 296 applications activating, 298, 298 MDI. See MDI (Multiple Document Interface) applications messages for, 374 titles for, 297 upsizing, 556 Web. See IntraWeb library Applications page, 28 ApplicationTitle property, 788 ApplyBitBtnClick method, 287 ApplyUpdates method, 575, 586, 589, 660, 803 AppServ2 example, 657?658 AppServer property, 664 AppSPlus example, 662?664, 668 Architect Studio edition, 4 Arrange option, 21 ArrangeIons method, 312 array-based properties, 52 arrays in ModelMaker, 450 Arrow component, 358 ActiveX, 487?488, 487 enumerated properties for, 358?360 events for, 364?366 paint method for, 361?362, 362 persistent properties for, 362?364, 364 registering property categories for, 366?367, 367 arrow keys for moving components, 18 ArrowDblClick method, 365 ArrowHeight property, 359, 489 AS methods in IAppServer, 650 as operator, 68, 70, 465 As properties, 528 ASCII text files, source files as, 38 AsDateTime property, 574 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. ASM statements, 921 ASP.NET, 940?942, 942?943 aspbase.aspx example, 941?942, 942 aspui.aspx example, 942, 943 assemblies in .NET architecture, 906?907 type of, 916 Assign method, 57?58 in TClipboard and TBitmap, 208 in TList, 128 in TPersistent, 113 assigning objects, 56?58, 56 AssignPrn method, 582 AssignTo method, 113 Associate property, 172, 275 association symbols in diagrams, 435 associative lists, 132?133 AsSQLTimeStamp property, 574 AsText method, 495 asymmetric arithmetic rounding, 90 atomic operations, 589 AttachedMenu property, 816 attachments, 892?893, 894 Attribute class, 928 attributes in Delphi for .NET Preview, 927?928 in XML, 835 in XSLT, 865 Attributes property, 635 AutoActivate property, 482 AutoCheck property, 173, 222 AutoComplete property, 168 AutoConnect property, 477 AutoDock property, 235 AutoDrag property, 235 AutoHotkeys property, 182 automated keyword, 921 automatic operations form scaling, 276?277 form scrolling, 272?273 mail message generation, 748 Automation, 456, 467?468 call dispatching in, 468?470, 469 clients in, 474?475 compound documents, 479?483, 482 internal objects in, 482?483, 483 object scope in, 476?477 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Office programs with, 478?479 servers, 470, 470 code for, 472?473 in components, 477?478, 477 registering, 473?474 type-library editor for, 470?472, 471 speed differences in, 476 types in, 478 Automation Object Wizard, 470, 470 AutoSave feature, 11 AutoScroll property, 270, 272, 275, 277 AutoSize property, 234?235 AutoSnap property, 181 availability in InterBase, 561 AxBorderStyle property, 492 AxCtrls unit, 478 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks Index B B2B (business-to-business) applications, 875 BabelFish translations, 876?879, 877, 879 background processing, 304 BackPages object, 212 BackTask example, 305?307 band components, 726?728, 727 Band Style Editor, 727?728, 727 Bands property, 231 BandStyle property, 726 banker's rounding, 90 bar code components, 725 BarMenuClick method, 234 base classes, 330?333, 340 base forms inheritance from, 319?321, 319?320 and interfaces, 330, 333?334 base types, 84 BaseCLX, 110?111 batch updates, 615, 638?642 BDE (Borland Database Engine), 507, 615 BeforeDestruction method, 279 BeforeEdit event, 524 BeforePost event, 546 beginning-of-file cracks, 697 BeginThread function, 84 BeginTrans method, 634 Beveled property, 180 Beyond Compare utility, 11 bi constants, 256?257 BIcons example, 256?257, 257 binary large object (BLOB) fields in DataSnap, 666 in record viewer, 682 streams for, 136, 139 binding late. See late binding resource files into executables, 30 binding interfaces in XML, 846?850, 847 Bitmap component, 724 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. bitmaps for Component Palette, 348, 349 for components, 340, 348 for ListView, 188 for Rave, 724 for TabControl, 209 viewer for, 207?210, 207 black box programming, 48 BLOB (binary large object) fields in DataSnap, 666 in record viewer, 682 streams for, 136, 139 blocking sockets, 738 BlockRead function, 921 BlockWrite function, 921 BMP files, 34. See also bitmaps BmpSide constant, 210 BmpViewer example, 207?210, 207 Bof tests, 537 BofCracks, 697 BoldExecute method, 215 booking classes, 608?611, 610 Bookmark property, 538, 542 bookmarks, 537?538, 633, 695?698, 696 shortcut keys for, 16 in TDataSet, 687 Boolean conversions, 86 BoolToStr function, 86 border icons, 256?257, 257 BorderIcons property, 255?256 Borders example, 254?256, 254 borders for forms, 254?256, 254 BorderStyle property, 254?255 Borland Database Engine, 507, 615 Borland Registry Cleanup Utility, 33 Borland resource compiler tool, 33 BorlndMM.DLL file, 405?406 BoundsRect method, 159 BPG files, 28, 34 BPL files, 34, 338, 347 BPL folder, 347 BRC32.exe and BRCC32.exe tools, 33 Break property, 174 briefcase model, 645 Bring To Front command, 204 BringToFront method, 302, 328 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. BrokDemo example, 774?778, 777 BrowseFast example, 756?757, 757 browsers creating, 756?757, 757 in UDDI, 895?898, 896 browsing in editor, 12?13 bs constants, 255 btnSendClick method, 745 BtnTodayClick method, 56?58 BucketCount property, 133 BucketFor function, 133 buffers and caches with ClientDataSet, 584 for dataset records, 698?703 in TDataSet, 687 Build Later command, 27 Build Sooner command, 27 building projects, 30?32 Bushakra, John, 899 business rules, 648, 656?657, 711 business-to-business (B2B) applications, 875 BusinessEntity type, 895 BusinessService type, 895 BusinessTemplate type, 895 button wheels, 261 ButtonLoadClick method, 323 ButtonStyle property, 516, 533 Byte type, 478 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks Index C C# programming language, 10 C++ programming language, 401?402 CAB files, 34, 493 cached updates, 638?642 CacheFile property, 893 caches and buffers with ClientDataSet, 584 for dataset records, 698?703 in TDataSet, 687 CacheSize property, 630?631 caFree value, 279 caHide value, 279 Calc example, 531?533, 533 CalcController component, 733 CalcOp component, 733?734 CalcText component, 729?730 CalcTotal component, 733 CalcType property, 730 calculated fields adding, 530?533, 531, 533 internally calculated, 513 calculations in Rave, 733?734 callback functions, 308 callback interfaces, 497?498 callback mechanisms, 910 CallFirst example, 406, 407 calling DLLs, 406, 407, 408?410 procedures, 409?410 caMinimize value, 279 CancelBatch method, 638 CancelUpdates method, 638 caNone value, 279 CanTools wizards, 945?947 Canvas property, 262 CaptionPlus method, 57 captions and Caption property for actions, 222 inputting, 260 for menu items, 174 for property pages, 490 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks removing, 258 in TabSheet, 203 toolbar, 236 Capture property, 264?265 Cascade method, 312 Cascading Style Sheets (CSS), 764?765, 797, 859 case-insensitive searches, 602?603 case toggling, shortcut keys for, 16 casting RTTI for, 67?69 type-safe down-casting, 67?69 categories, property in Object Inspector, 21?22 registering, 366?367, 367 Category property, 222, 224 CCLibDir entry, 26 CDATA section, 834 CDK (Component Development Kit), 340 CDS formats, 511, 512 cdsCalcFields method, 531?532 CdsCalcs example, 549?553, 550 CdsDelta example, 586?588, 586 CdsXstl example, 868?869 CFG files, 34 CGI programs, 768?769, 769 CgiDate example, 768?769, 769 CgiIntra example, 823?824 ChangeAlignment method, 230 ChangeColor method, 476 Changed method, 344, 383 ChangedAllowed property, 244 ChangeFamily method, 97 ChangeFormFont property, 344, 348 ChangeOwner example, 119?120, 120 ChangesToClone property, 712 character sets in XML, 835 characters event, 850, 852 characters method, 872 CheckBiDirectional function, 572 CheckBox component, 165?166 CheckBoxList component, 169 CheckCapsLock method, 218 Checked property for actions, 222, 230 in CheckBoxList, 169 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks child components, messages for, 374 child forms in MDI applications, 315?316, 315 child windows in MDI applications, 311?315, 313 CIL (Common Intermediate Language), 904, 907?908 CTS in, 909?911 managed and safe code in, 908?909 class completion in editor, 13?14 for methods, 45 Class_DColorPropPage constant, 489 Class_DFontPropPage constant, 489 Class_DPicturePropPage constant, 489 Class_DStringPropPage constant, 489 class factories, 460 class helpers, 929?931 class interfaces, 48 class references, 76?78, 78 classes, 109. See also components in Delphi, 44?48 diagrams for, 431?432, 432?433 for exceptions, 73?75 for fields, 529?530 information for, 104?108, 108 interposer, 332?333 moving, 446 in Project Explorer, 32 reparenting, 446 Classes unit, 147?148 ClassHelperDemo example, 929 ClassInfo example, 107?108, 108 ClassInfo method, 106 ClassName method, 104?105 ClassParent method, 105 ClassRef example, 77?78, 78 ClassType method, 105 clear method for dialog boxes, 283?284 CLI (Common Language Infrastructure), 903?904 client areas in controls, 159 in forms, 269 for mouse events, 262 client cursors, 629 client indexes in ADO, 632 client/server programming, 555?557 with ClientDataSet aggregates in, 550?552, 550 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. grouping in, 549, 550 packets and caches in, 584 transactions in, 589?591, 591 updates in, 584?589, 585?586, 588 database design for, 557?561 with dbExpress library, 566 components, 569?574, 571, 573 metadata in, 578?579, 579 parametric queries in, 579?581, 580?581 platforms and databases, 567?569 printing in, 581?584 single and multiple components with, 575?578, 577 unidirectional cursors, 566?567 with InterBase, 561?566, 563?564 unidirectional cursors in, 560?561 client socket connections, 740 client windows, subclassing, 317?318 ClientDataSet component, 508?509, 567, 575 client/server programming with aggregates in, 550?552, 550 grouping in, 549, 550 packets and caches in, 584 transactions in, 589?591, 591 updates in, 584?589, 585?586, 588 for DataSnap, 649, 655?656, 656 filtering for, 513 formats in, 511 indexing for, 512?513 local tables for connections for, 509?510, 510 defining, 511?512, 512 locating records in, 514?515 master/detail structures in, 552?553, 553 Midas library for, 510?511 for updates, 576 in WebSearch program, 785 in WebSnap, 799, 803 in XML, 838, 854?856, 870?873 ClientHandle property, 312 ClientHeight property, 269 ClientRefresh example, 661, 661 clients Automation, 474?475 for DataSnap, 652?653 MDI, 310?311 thin, 649 in Web database applications, 831?832, 832 ClientToScreen method, 175, 183 ClientWidth property, 269 Clip History Viewer, 946 Clipboard for actions, 229?230 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. for components, 24?25 for DDE, 456 with TabControl, 208?209 for toolbar operations, 214?215 ClipBrd unit, 208 ClipCursor function, 263 clocks digital, 349?352 XClock, 492?493, 493 Clone method, 633 cloneNode, 843 clones in ADO, 633, 633 property, 187 recordset, 633 Close method, 279?280 closing datasets, 694?695 forms, 279?280 closing markers in XML, 834?835 CLR (Common Language Runtime), 905?906 CLRReflection example, 934?940, 940 CLS (Common Language Specification), 905?906 CLX (Component Library for Cross-Platform), 5, 110? 112 structure of, 111?112 styles for, 219?220, 220 cm_ prefix, 373?378 cm_DialogChar message, 377 cm_DialogKey message, 260, 377 cm_FocusChanged message, 378 cm_MouseEnter message, 372 cm_MouseExit message, 372 CmdGotoPage command, 799 CmdLine global variable, 84 CmdNextPage command, 799 CmdPrevPage command, 799 CmExit method, 677 CMNTest example, 377?378 cn_ prefix, 373, 377 CNHScroll method, 676 CNVScroll method, 676?677 CoCreateGuid function, 459 code completion, 14?15 Code Explorer window, 11?12, 12 code generation vs. streaming, 113?114 code in Delphi for .NET Preview, 921?922 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. code insight technology, 14 code parameters, 15 Code Template Parameters dialog box, 450, 450 code templates, 15 CoFirstServer class, 475 ColHeights property, 683 collaboration diagrams, 434 collections classes in, 131 for properties, 381?385, 383 colons (:) in to-do items, 9 color for controls, 160?161 converting to strings, 187?188 in DLLs, 404, 410?411 list box of, 186?188 messages for, 377 in Object Inspector, 20 transparent, 267, 267 Color property in Splitter, 180 in TControl, 159?160 ColorBox component, 169 ColorDialog component, 288 ColorDrawItem method, 185?186 ColorKeyHole example, 267?268, 267 ColorRef type, 404 Colors toolbar in Rave, 718 ColorToString function, 187?188 Column property, 763 ColumnLayout property, 167 columns and Columns property in DataSetTableProducer, 763 in DBGrid, 382, 516 editing, 539?540 in ListBox, 167 in RadioGroup, 166 totals of, 537, 537 Columns property editor, 533 COM (Component Object Model), 455?456 and ADO.NET, 645?646 class factories in, 460 data types in, 478 in Delphi, 500?502, 502 GUIDs in, 458?460, 459 history of, 456?457 instancing and threading methods in, 463 Interop services in, 908 IUnknown for, 457?458 server for, 460?461 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. interface properties for, 465?466 interfaces and objects for, 461?463, 462 object initialization for, 464 testing, 464?466 virtual methods in, 466?467 COM+, 456, 494, 650 components for, 494?496, 495?496 events for, 497?500, 499 transactional data modules for, 497 COM Component Install Wizard, 498 COM+ Event Object wizard, 498 COM Object Wizard, 461?462, 462, 498 combo boxes, 216?217, 341?348, 345?346 ComboBox component, 168 ComboBoxEx component, 169 ComConts unit, 96 ComDlg32.DLL file, 287 CommandHandlers class, 741 commands, 173 and actions, 173 Menu Designer for, 174, 174 pop-up menus, 174?176 CommandText Editor, 573, 573 CommandText property in SQLDataSet, 573 in TADODataSet, 626 CommandType property in SQLDataSet, 573 in TADODataSet, 626 CommDlg example, 287?288, 288 comments in ModelMaker, 444?445, 444 TODO, 7?9 in XML, 834 Commit action, 596 Commit method, 589 CommitRetaining command, 596?597 CommitTrans method, 634 common dialog boxes, 287?288, 288 Common Intermediate Language (CIL), 904, 907?908 CTS in, 909?911 managed and safe code in, 908?909 Common Language Infrastructure (CLI), 903?904 Common Language Runtime (CLR), 905?906 Common Language Specification (CLS), 905?906 Common Object Request Broker Architecture (CORBA), 651 Common Type System (CTS), 903?904, 909 events and delegates in, 910?911 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. objects and properties in, 909?910 ComObj unit, 96, 457 Comp type, 920 CompareValue function, 89 comparisons for ClientDataSet, 513 with floating-point numbers, 89 with strings, 91?92 compatibility in DLLs, 404?405 with Linux, 88 type, in inheritance, 62?63 compilation conditional, 156 for libraries, 156 .NET Preview, 900 for projects, 30?32 compiler messages, 9?10, 31, 31 Compiler Messages page, 31, 31 Compiler page, 28 complex numbers, 95 Component Development Kit (CDK), 340 component diagrams, 434 Component Library for Cross-Platform (CLX), 5, 110? 112 structure of, 111?112 styles for, 219?220, 220 Component Object Model. See COM (Component Object Model) Component Palette, 23?24 bitmaps for, 348, 349 for copying and pasting components, 24?25 for databases, 507 submenus on, 5 templates and frames in, 25?26, 26 Component property, 395 component streaming system, 52 Component Template Information dialog box, 25 component templates, 25?26 Component Wizard, 341?342 ComponentCount property, 119 ComponentIndex property, 118 components, 109, 162. See also classes; controls vs. ActiveX controls, 484?485 for adapters, 794?795 Automation servers in, 477?478, 477 base classes for, 340 class references for, 76?78, 78 collection properties, 381?385, 383 for COM+, 494?496, 495?496 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks commands, 173?176 compound, 349 external components in, 352?354, 353 frames for, 357?358 graphical. See Arrow component interfaces for, 354?356 internal components in, 349?350 publishing subcomponents of, 350?352, 352 copying and pasting, 24?25 dynamic creation of, 47?48, 47 editors for, 392?395, 394 extending libraries for, 337?340 Fonts combo box, 341?348, 341, 345?346 hiding, 159 input focus, 176?178, 176?177 lists, 167?172, 170 messages for, 376 without names, 122 nonvisual dialog, 378?381, 381 for options, 165?166 packages for, 337?339 property editors, 388?392, 390?391 ranges, 172?173 text-input, 162?165, 165 windows controls. See windows writing, 339?340 Components property, 118?120 ComponentState property, 300 ComponentStyle property, 351 ComponentToDOM method, 845 compound components, 349 external components in, 352?354, 353 frames for, 357?358 graphical. See Arrow component interfaces for, 354?356 internal components in, 349?350 publishing subcomponents of, 350?352, 352 compound documents, 456, 479?483, 482 compressed CAB files, 493 compressing streams, 145?146, 145 CompressStream function, 146 ComputePoints method, 360?361, 365 ComputerName property, 652, 655 ComServ unit, 96 concurrency access in, 557 in COM+, 496 InterBase for, 561 conditional compilation, 156 conflicts in ADO, 641?642 Connected property, 655 Connection component, 575 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. connection protocols for DataSnap, 650?651 connection string editor, 618?619, 619?620 connection strings, 618?619 ConnectionBroker component, 652?653, 666 ConnectionName property, 571 connections ClientDataSet, 509?510, 510 dbExpress, 576?577, 577 pooling, 643?644 socket, 740, 744?747 connections.ini file, 570, 572 ConnectionString property, 618?619, 621, 629 ConnectKind property, 478 constant strings, 85 ConstraintErrorMessage property, 657 constraints and Constraints property, 179, 657 in DataSnap example, 657?658 for forms, 270 in Splitter, 180 constructor keyword, 54 constructors, 54?55, 926 container classes, 131?132 containers, type-safe, 133?135 contains keyword, 346 contains lists, 345?346 Contains section, 348 Content method in DataSetTableProducer, 762 in PageProducer, 760 in QueryTableProducer, 778 Content property, 772 ContentFields property, 778 ContentStream property, 784 ContentType property, 784 Contnrs unit, 131 Contrib.INI file, 692?693 ControlBar component, 231?234, 232 docking toolbars in, 235?239, 236 menus ins, 234 ControlBarLowerDockOver method, 247?248 ControllerBand property, 727, 731 controllers in Automation, 467 controls, 111, 149. See also components activation and visibility of, 159 ActiveX. See ActiveX controls anchors for, 179?180, 179 colors for, 160?161 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks converting, 156?158 data-aware. See data-aware controls dual libraries support for, 151?155, 152 fonts, 159?160 forms. See forms ListView, 188?193, 191 menus. See menus owner-draw, 184?185 list box of colors, 186?188 menu items, 185?186, 186 parents of, 158?159 size and position of, 159 status bars, 217?219, 218 TControl for, 158?162 ToolBar, 213?219, 214 TreeView, 193?197, 194, 199 TWidgetControl, 161?162 TWinControl, 161 VCL vs. VisualCLX, 149?158, 152 windows. See windows Controls property, 159 ConvDemo example, 97, 98 conversions, 96?99, 98 Booleans, 86 colors, 187?188 controls, 156?158 currency, 99?102, 101, 880?882, 881, 883 DFM files, 33, 153 floating-point numbers, 87 members, 447 stream data, 140?142 strings, 86?87, 187?188 temperatures, 96 types, 67?69 to uppercase names, 602?603 CONVERT.EXE utility, 33, 140 Convert function, 96 Convert Project to Model option, 437 Convert to Model option, 437 Convert tool, 33, 140 ConvertAndShow method, 141 ConvertIt demo, 100 ConvertService service, 880?882, 881, 883 ConvUtils unit, 91, 96 CoolBar component, 230?231 coordinates for controls, 159 in dragging, 544 for mouse-related keys, 262 in Rave, 719 in scrolling, 273?274, 273 Copy1Click method, 209 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. CopyFile method, 138?139 copying components, 24?25 files, 138?139 CORBA (Common Object Request Broker Architecture), 651 core library classes, 109, 148 Classes unit, 147?148 collections, 131 containers, 131?135 events, 124?128 lists, 128?131, 130, 133?135 RTL package, 110?112, 110 streaming, 135?148, 141 TComponent, 117?124, 120 TPersistent, 112?117, 117 core syntax of XML, 834?835 Count command, 316 Count property, 128 count(*) wildcard, 561 CountBlanks property, 730 counters hit, 782?785 in Interbase 6, 565 CountSubstr function, 93 CountSubstrEx function, 93 CppDll example, 401?402, 402 cracks in datasets, 697 Create constructors, 54 for file streams, 138 overloaded, 54?55 in TMdClock, 351 in TObject, 54 Create XML From Datapacket command, 856?857 CreateComObject function, 460, 465, 475 CreateComps example, 47?48, 47 CreateDataSet method, 511 createElement method, 842 CreateFileMapping function, 413?414 CreateForm method, 77, 277 CreateGUID function, 87 CreateHandle method, 161 CreateInstance method in IClassFactory, 460 in IObjectContext, 497 CreateMutex method, 308 CreateOleObject function, 475 CreateParams method, 161, 258 CreatePolygonalRgn method, 365 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. CreateTable method, 695 CreateWindowEx function, 258 CreateWindowHandle method, 161 CreateWnd method, 161, 327, 342?343 creation classes, 475 Creational Wizard, 452 CreatOrd program, 279 CSS (Cascading Style Sheets), 764?765, 797, 859 CTS (Common Type System), 903?904, 909 events and delegates in, 909?910 objects and properties in, 909?910 culture, 904 CUR files, 34 currency converting, 99?102, 101, 880?882, 881, 883 in Delphi for .NET Preview, 921 floating-point numbers with, 87 Currency property, 658 CurrentYear function, 87 Cursor Service, 618 CursorLocation property, 629 cursors in ADO, 629 locations, 629?630 types, 630?631 unidirectional, 560?561, 566?567 CurValue property, 641?642 CustHint example, 183?184, 184 CustLookup example, 519, 519 custom attributes, 927?928 custom classes for streaming, 142?145 custom drawing technique, 185 custom method calls, 663?664 custom variant types, 94?95, 94 CustomConstraint property, 657 Customizable option, 244 CustomizeDlg component, 242, 244 CustomNodes example, 197?198, 199 CustQueP example, 774, 778?780, 780 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Index D D7RegClean.exe utility, 33 data access components, 725?726, 725 data-aware components, 728?730, 729 data-aware controls, 162, 515 DBNavigator, 516 graphical, 520 grids, 516 list-based, 517?518, 518 lookup, 519?520, 519 mimicking, 545?547, 545 replicable, 674 text-based, 516 data binding interfaces, 846?850, 847 data connections in Rave, 721?722, 722 data links, 669?671 for ADO, 621 record viewer component, 678?683, 682 Data Lookup Security option, 726 data modules, 535, 648 for COM+, 497 for WebSnap, 798?799 data packets, 651?652, 667?668 Data property for OLE objects, 481 in TBucketList, 132 Data Text Editor, 728?729, 729 data types, COM, 478 Data View Dictionary, 717, 723 DataBand component, 726?727 Database Connections option in Rave, 726 Database Desktop tool, 33 Database Explorer tool, 33 database independence, 615 databases ADO for, 508 BDE for, 507, 615 client/server programming for. See client/server programming ClientDataSet for. See ClientDataSet component data-aware controls for. See data-aware controls DataSet for. See datasets and DataSet component; fields dbExpress library for, 506?507 design issues entities and relations, 557?558 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. primary keys and OIDs, 558?560 error management for, 553?554 grids for, 540?544, 542?543 multitier. See DataSnap platforms for, 567?569 reports for. See Rave sending data over socket connections, 744?747, 747 standard controls, 544?545 data-aware-like, 545?547, 545 for sending requests, 547?549, 548 Web applications, 825?827, 827 client side, 831?832, 832 linking to details, 827?830, 828, 830 Web services for, 883?887, 887 WebSnap application, 798 data editing, 801?803, 802 data module for, 798?799 DataSetAdapter for, 799?801, 800 master/detail in, 803?805, 805 DataChange method, 673 DataClone example, 633, 633 DataCLX, 110?112 DataCycle component, 730 DataEvent method, 670 DataField property for data-aware controls, 515, 669, 672 in Data Text Editor, 728?729 datagrams, 739 DataLinkDir function, 621 DataMemo component, 729 DataMirrorSection component, 732?733 DataRelation class, 646 DataSet component, See datasets and DataSet component DataSet property for ClientDataSet connections, 509 in DataSetTableProducer, 762 DataSetAdapter component, 794, 799?801, 800, 803?805, 805 DataSetPageProducer component, 759, 761?762, 776, 789 DataSetProvider component, 575, 653 DataSetReader class, 646 datasets and DataSet component, 520?524 actions in, 224, 516 class definitions for, 687?690 closing, 694?695 custom, 686?687 in dbExpress, 572?574, 573 directories in, 705?709, 709 fields of. See fields in IBX, 592?593 initializing, 690?691 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. . Thanks navigating, 536?540, 695?698, 696 bookmarks for, 537?538 editing columns, 539?540 totals of columns, 537, 537 of objects, 710?713, 713 opening, 690?694 record buffers in, 698?703 status of, 524?525 testing, 703?704, 704 DataSetTableProducer component, 759, 762?764, 763, 776, 791 DataSetToDOM method, 843?844 DataSnap, 647 ConnectionBroker in, 666 custom method calls in, 663?664 data packets in, 651?652, 667?668 example, 653 client features in, 659?662, 659, 661 first server, 653?655, 654 first thin client, 655?656, 656 server constraints in, 657?658 IAppServer interface for, 649?650 levels in, 647?649 master/detail relations in, 664?665, 665 object pooling in, 667 parametric queries in, 663, 663 protocols for, 650?651 provider options in, 666?667 SimpleObjectBroker in, 667 over SOAP, 889?892 support components for, 652?653 technical foundation of, 649 DataSource component, 575, 669 DataSource property for data-aware controls, 515, 669 in SQLDataSet, 581 in TDataSet, 552 in TMdDbProgress, 672 DataTable class, 646 DataView property in Data Text Editor, 729 in DataBand, 726 DateCopy example, 57?58 DateList example, 134?135 DateProp example, 51, 51 dates conversions with, 87 native formats for, 709 unit for, 91 DateTimeToNative function, 709 DateTimeToSQLTimeStamp function, 574 DateUtils unit, 91 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. DAX (Delphi ActiveX) framework, 112 DaysBetween function, 91 DbAware example, 517?518, 518 DBCheckBox component, 515, 517 DBComboBox component, 517 DBCtrlGrid component, 674 DBEdit component, 515?516 DBError example, 553?554 dbExpress Connection Editor, 571, 571 dbExpress Draft Specification, 567 dbExpress library, 506?507 client/server programming with, 566 components, 569?574, 571, 573 metadata in, 578?579, 579 parametric queries in, 579?581, 580?581 platforms and databases, 567?569 printing in, 581?584 single and multiple components with, 575?578, 577 unidirectional cursors, 566?567 components dataset, 572?574, 573 SQLConnection, 569?574, 571 SQLMonitor, 574 drivers for, 567?569 dbGo package, 508, 616, 618?620, 619?620 DBGrid control, 515?516, 544 customizing, 683?686, 683 dragging with, 544 with multiple selections, 542?543, 543 painting, 540?542, 542 DBI files, 38 DBImage component, 520 DBListBox component, 517 DBLookupComboBox component, 518?519 DBLookupListBox component, 518 DBMemo component, 516 DBNavigator component, 515?516 DbProgr example, 673, 673 DBRadioGroup component, 517?518, 518 DBText component, 516 DbTrack example, 677, 677 DBX. See dbExpress library DbxExplorer example, 579 DbxMulti example, 568, 575?578 DbxSingle example, 575?578, 577 DCC.exe tool, 33 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks dccil compiler, 900 DCI files, 37 DCOM (Distributed COM), 650 DCOMConnection component, 652, 655 DCOMConnection1 class, 655 DCP files, 35, 347 DCR (Delphi Component Resource) project type, 348 DCT files, 38 DCU (Delphi Compiled Unit) files, 30, 35, 338?339, 416 .dcua files, 906?907 .dcuil files, 906?907 DDE (Dynamic Data Exchange), 456 DDP (Delphi Diagram Portfolio) files, 35 debugger, 42 Debugger Options dialog box, 74 debugging, 33 and exceptions, 74 SOAP headers, 887?888, 888 in WebBroker technology, 772?774, 774 Decision Cube components, 112 declarations, external, 398, 406 _declspec declaration, 401 DecodeDateFully function, 87 DecompressStream function, 146 Decorator pattern, 449 DefAttributes property, 164 default exception handlers, 74 default keyword for styles, 343 default values for methods, 46 DefaultColumnWidth property, 680 DefaultDrawColumnCell method, 540 DefaultDrawing property, 540, 682 DefaultExpression property, 657 DefaultRowHeight property, 683, 685 DefaultStyle property, 219 DefaultTextLineBreakStyle variable, 85 DefaultTimeout property, 805 Define command in Fields editor, 526 DefineProperties method, 113, 187, 683 DefinePropertyPage method, 491 DefinePropertyPages method, 491 defining actions, 385?388 events and event handlers, 364?365 symbols, 156 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks definitions external, 400 links to, 13 delayed signing, 917 delegates in CTS, 909?910 delegation in event handling, 124 Delete method, 128 delete operations, trigger firing from, 565 Delete1Click method, 209 Delphi ActiveX (DAX) framework, 112 Delphi Compiled Unit (DCU) files, 30, 35, 338?339, 416 Delphi compiler tool, 33 Delphi Component Palette, 287 Delphi Component Resource (DCR) project type, 348 Delphi Diagram Portfolio (DDP) files, 35 Delphi for .NET Preview, 900?902, 903, 919 ASP.NET with, 940?942, 942?943 class helpers in, 929?931 custom attributes in, 927?928 deprecated features for, 920?922 extended identifiers in, 924 final and sealed keywords in, 924?925 Microsoft libraries for, 934?940, 940 multicast events in, 926?927 nested types in, 926 run-time library for, 930?931 static members in, 925?926 unit namespaces in, 922?924 VCL for, 931?933, 933 visibility and access specifiers in, 925 Delphi internal messages, 374 Delphi language, 43?44 class references in, 76?78, 78 classes and objects in, 44?48 for components, 339 constructors in, 54?55 dynamic objects in, 47?48, 47 encapsulation in, 48 access specifiers for, 48?50, 60?62 and forms, 52?54, 53 with properties, 50?52, 51 exceptions in, 71?75, 76 inheritance in, 59?63, 60 interfaces in, 69?71 late binding in, 63?67, 64 type-safe down-casting in, 67?69 Delphi Power Book, 954 Delphi project (DPR) files, 39 DELPHI32.DCT file, 26 DelphiMM unit, 95?96 Delphree site, 952 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. delta caches, 652 Delta memory area, 514 delta packets, 651 Delta property, 585?586, 586 deltas in aggregates, 550 in batch updates, 638 in ClientDataSet, 585?586, 586, 652 DEM files, 38 demoscript pages, 792?793, 792 dependencies, 339 deployment in library selection, 155 in .NET architecture, 916?917, 917 deployment diagrams, 434 deprecated features, 920?922 descendant classes, 63 DESCRIPTION directive, 346 Description property, 353 design critics, 452 design-only component packages, 338 design patterns, 447?450 design-time packages, 338 design-time properties, 52 Designer page, 19, 280 Designer toolbar in Rave, 718 Desktop (DSK) files, 36, 39 desktop settings, saving, 5?6 Dessena, Nando, 600 Destination property, 249 DestParan property, 733 Destroy method, 55, 59, 912?914, 914 DestroyComponents method, 118 destroying objects, 58?59 destructors, 55, 59 DestructorTest class, 912?914, 914 DetailKey property, 731 details, linking, in Web databases, 827?830, 828, 830 Details view in Object Repository, 40 ~DF files, 35 DFM files, 19, 33, 35, 38, 152?154 DFN files, 35 Diagram view, 16?18, 17?18 diagrams for classes, 431?432, 432?433 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. common elements in, 435?436, 436 non-UML, 435 for sequences, 433?434, 433 for use cases, 434 dialog actions, 224 dialog boxes, 280?281 creating, 282?287, 284?285 modeless, 285?287, 285 nonvisual, 378?381, 381 predefined, 287?289, 288 dialog menu items, 173 diamond symbol in Band Style Editor, 728 Difference view, 442?443, 443 digital clock, 349?352 DirDemo example, 709, 709 Direct Data View option, 726 Direct Driver View option, 726 direct form input, 259 keyboard, 259?261, 260 mouse, 261?265 direct memory access functions, 921 Direction property, 489 directives, 44, 347 directories for components, 347 in datasets, 705?709, 709 Directories/Conditionals page, 477 DisableCommit method, 497 DisableControls method, 538?539 DisabledImages property, 213 DisableIfNoHandler property, 223, 227 disabling aggregates, 551 disconnected recordsets, 642?643 dispatching calls in Automation, 468?470, 469 dispid keyword, 470 dispinterface keyword, 469?470, 472, 488 Display method, 422 DisplayFormat property, 658?659, 733 in DataSetTableProducer, 763 in TFloatField, 527, 532 DisplayLabel property, 527?528, 658 DisplayType property, 801 DisplayValues property, 658 DisplayWidth property, 528, 658 Dispose method, 912 Distributed COM (DCOM), 650 distribution of updated packages, 416 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . DivideTwicePlusOne example, 73?75 DivMod function, 89 DlgApply example, 285?287, 285 DllCanUnloadNow function, 461 DLLGetClassObject method, 460 DllMem example, 412?413 DllRegisterServer function, 461 DLLs (dynamic link libraries), 35, 397 for ActiveX controls, 484 C++, 401?402 calling, 406, 407, 408?410 creating, 402?406 dynamic linking in, 397?398 exporting strings from, 404?406 forms in, 410?411 with ISAPI, 769?770 in memory, 411?414, 415 overloaded functions in, 404 and packages, 30, 338, 345, 415?416 purpose of, 398?399 rules for, 399?400 using, 400?402, 402 wizards for, 41 DllUnregisterServer function, 461 DMT files, 37 doAutoIndent option, 842 DoChange method, 126?127 Dock method, 235 DockClientCount property, 235 DockClients property, 235 docking support, 234?235 in control bars, 235?239, 236 messages for, 376 for page controls, 239?241, 241 DockPage example, 239?241, 241 DockSite property, 234 DoConvert method, 98?99 DoCreate method, 330?331 document management in XML, 837?838, 840, 843, 846 Document Object Model (DOM) programming with, 838?846, 840, 843, 846 XSL transformations with, 868?869 document type definitions (DTDs), 849 documentation in ModelMaker, 444?445, 444 DoDestroy method, 331 Does Not Support Transaction option, 495 DOF files, 28, 35 DOM (Document Object Model) This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. programming with, 838?846, 840, 843, 846 XSL transformations with, 868?869 domain names, 739 DomCreate example, 839, 842?846, 843, 846 DOMDocument property, 838 DOMPersist property, 836 DOMVendor property, 836 dot-notation for methods, 46 Double type, 478 DoVerb method, 481 down-casting, type-safe, 67?69 ~DP files, 36 DPK files, 35, 345 DPKL files, 35 DPKW files, 35 DPR (Delphi project) files, 36, 39 dragging, 98 with DBGrid control, 544 with mouse, 262?265, 265 in Object TreeView, 23 source code files, 27 DragKind property, 234?235 DragMode property, 98 in TControl, 234?235 in TreeView, 195 DragToGrid example, 544 DragTree example, 194?197, 194 DrawCell method, 680?682 DrawColumnCell, 685?686 DrawData program, 540?542, 542 DrawFocusRect method, 264 drawing with mouse, 262?265, 265 Rave components for, 725 DrawPoint method, 263 DrawText function, 209, 682 DriverName property, 570 drivers for dbExpress, 567?569 drivers.ini file, 569?570 Drivers Settings window, 571, 571 DRO files, 37 drop-down fonts, 21 drop procedure statement, 565 drop trigger statement, 566 DropdownMenu property, 213, 215 DropDownRows property, 516 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. DropDownWidth property, 519 dsBrowse value, 524 dsCalcFields value, 524 dsCurValue value, 524 dsEdit value, 524 dsFilter value, 524 dsInactive value, 524 dsInsert value, 524 DSIntf.pas unit, 510 DSK (Desktop) files, 36, 39 DSM files, 36 dsNewValue value, 524 dsOldValue value, 524 DST files, 6, 38 DTDs (document type definitions), 849 dual interfaces, 470 dual libraries support, 151?155, 152 DUnit architecture, 952 DynaCall example, 408?410 DynaForm example, 252?253, 253 dynamic aggregation of interfaces, 921 dynamic binding. See late binding dynamic components, 47?48, 47 dynamic cursors, 631 Dynamic Data Exchange (DDE), 456 dynamic database reporting, 776?777, 777 dynamic link libraries. See DLLs (dynamic link libraries) dynamic linking, 397?398 dynamic methods vs. virtual, 65?66 dynamic pages, 764?765 dynamic properties, 622 dynamic Web pages, 768 and CGI, 768?769, 769 DLLs, 769?770 DynaPackForm example, 419?420 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks Index E e-mail, 748?750, 749 E object, 75 early binding, 63 ebXML (Electronic Business using Extensible Markup Language), 894 EchoActionFieldValue property, 797 EchoMode property, 163 ECMAScript, 791 EDBClient class, 553 Edit command, 520 Edit component, 163 Edit method in IComponentEditor, 393 in TSoundProperty, 389?390 Edit Tab Order dialog box, 176, 176 Edit To-Do Item window, 8, 8 edit verbs, 480 EditFirstNameExit method, 178 EditFormat property, 658 editing actions for, 224 columns, 539?540 connection properties, 571 HTML, 788 in-place, 480 records, 520 textual form descriptions, 38 visual, 484 WebSnap data, 801?803, 802 editions, 3?4 EditLabel property, 163 EditMask property, 163?164, 658 Editor Properties dialog box, 10?11, 10 editors, 10?11, 10 ActionManager, 242?245, 243?245 for columns, 533 for commands, 573, 573 for components, 392?395, 394 for connection strings, 618?619, 619?620 Delphi browsing in, 12?13 class completion in, 13?14 Code Explorer window in, 11?12, 12 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. code insight technology in, 14 loadable views in, 16?18, 17?18 shortcut keys in, 16 for fields, 525?527, 526, 550 for images, 33, 348 for input masks, 163?164 Method Implementation Code Editor, 441?442, 442 for packages, 345, 345, 347?348, 417, 417 for properties, 388?392, 390?391, 533 type-library, 470?472, 471 for unit code, 439?441 EDivByZero exception, 73 Electronic Business using Extensible Markup Language (ebXML), 894 ellipsis (...) on menus, 173 embedded units, 568?569 embedding, 480?481 EMdDataSetError class, 687?688 Empty Project template, 40?41 empty values with field events, 535 Enable property, 863 EnableCommit method, 497 EnableControls method, 538?539 Enabled property for actions, 222, 227 in TControl, 159 in Timer, 350 encapsulation, 48 access specifiers for, 48?50, 60?62 and forms, 52?54, 53 with properties, 50?52, 51 end-of-file cracks, 697 endDocument event, 850, 852 endElement event, 850, 872 EndThread function, 84 EndUser object, 793, 795 EndUserSession adapter, 795 EndUserSessionAdapter component, 807?808 EnlargeFont1Click method, 816 EnsureRange function, 89 Enterprise Studio edition, 4 entities in database design, 557?558 enumerated properties, 358?360 EnumModules function, 84, 425?426 EnumWindows functions, 308 EnumWndProc method, 308?309 Environment Options dialog box, 6?7 for AutoSave feature, 11 for Code Explorer, 11?12 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. for compiler, 30 for DFM file saving, 19 for HTML editing, 788 for Project Explorer, 32 for secondary forms, 280 for type libraries, 471 environment variables in CGI programs, 769 Environment Variables page, 7 Eof tests, 536 EofCracks, 697 EqualsValue constant, 89 equi-joins, 636 error method, 851 ErrorLog example, 75?76, 76 errors. See also exceptions in ADO, 641 database, 553?554 logging, 75?76, 76 Essential Delphi, 954 Essential Pascal, 953?954 etm60.exe tool, 33 EuroConv example, 100?102, 101 EuroRound function, 102 euros, converting, 100?102, 101 event-driven programming, 302?303 Event Editor in Rave, 717, 731?732 Event Types view, 443 EventHandler method, 162 events, 124 for ActiveX controls, 484 for applications, 296 for Arrow component, 364?366 for COM+, 497?500, 499 in CTS, 909?910 in DataSnap example, 658?659 defining, 364?365 in Delphi for .NET Preview, 926?927 in Interbase 6, 565?566 method pointers for, 125?126 null values with, 535?536, 536 as properties, 126?128 in Qt, 162 EvtSubscriber library, 498 Excel with Automation, 479 Jet engine for, 625?626, 626 Excel IISAM, 626 except blocks, 71?73 Exception class, 75 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks Exception1 example, 73?75 exceptions, 71 in calculated fields, 532 classes for, 73?75 for components, 339 and debugging, 74 error logging, 75?76, 76 program flow and finally block in, 72?73 Exclude method, 927 EXE files, 36 ExecSQL method, 572 executable files, 30, 82?83 executable viewer tool, 33 Execute method in TFindWebThread, 753 in TMdListBoxDialog, 380 in TMdListCompEditor, 395 in TPrimeAdder, 305?306 ExecuteTarget method, 385?387 ExecuteVerb method in IComponentEditor, 393 in TMdListCompEditor, 394 exitItemClick method, 937, 939?940 ExitProc function, 921 ExpandAll1lick method, 816 ExpandFileName function, 87 expanding component references in-place, 20 explicit transactions, 589 Explorer page, 32 exploring projects, 32, 32 exporting Jet engine for, 628?629 strings from DLLs, 404?406 exports clause in Apache, 782 for DLLs, 399, 404 expression evaluation, tooltip, 16 ExtCtrls unit, 163 Extended Database Form Wizard, 947 extended identifiers, 924 extended ListBox selections, 167 Extended Properties property, 624, 626, 629 ExtendedSelect property, 167 extending libraries, 337?340 Extensible Stylesheet Language (XSLT), 864 examples, 865?866 with WebSnap, 866?868, 866 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks XPath in, 864?865 external components in compound components, 352?354, 353 interfaces for, 354?356 external declarations, 398, 406 external definitions for DLLs, 400 external keys, 559 external symbols, 15 External Translation Manager tool, 33 $EXTERNALSYM directive, 400 ExtraCode property, 197 ExtractStrings method, 147 Extras key for hot-track activation, 24 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Index F fake implementation code, 498 fArrowDblClick method pointer, 364?365 fatalError method, 851 FCL (Framework Class Library), 904 FetchBlobs method, 584, 666 FetchDetails method, 584, 666 FetchOnDemand property, 666 FetchParams method, 663 field-oriented data-aware controls read-only progress bar, 671?673, 673 read-write TrackBar, 674?677, 677 Field property, 671 FieldAcc example, 527?528, 528 FieldAddress method, 115 FieldByName method, 525, 527 FieldDefs property, 511, 690 FieldLookup example, 534, 534 FieldName property in TField, 527 in TFieldDataLink, 671 fields for adapters, 794 in databases, 525?527, 526, 698?702 calculated, 530?533, 531, 533 class hierarchy for, 529?530 constraints on, 657?658 events for, 658?659 lookup, 533?534, 534 null values with events for, 535?536, 536 objects for, 527?528, 528 properties for, 658 in Delphi for .NET Preview, 926 hiding, 122?123 names for, 360 removing, 121?122 virtual, 50 Fields editor, 525?527, 526, 550 Fields property, 525, 527 FieldsToXml function, 886 FieldValues property, 525, 527 file management, 102?104, 103?104 File Transfer Protocol (FTP) This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks API for, 754?755 ports for, 739 FileCreate function, 87 FileName property, 244 files actions for, 224 copying, 138?139 locating, 798 produced by system, 34?38 source code, 38?39 streaming, 138?139 FilesList example, 102?104, 103?104 Filled property, 359, 366?367, 489 FillFormList method, 299?300 FillFormsList method, 300 Fills toolbar in Rave, 718 Filter property, 513 FilterGroup property, 638, 641 filtering for ClientDataSet, 513 final keyword, 924?925 Finalize method, 911?912 finally blocks, 71?73 Find and Replace dialog boxes, 288 find_business API, 897 Find method, 132 FindClose function, 102 FindComponent method, 121, 286?287, 765 FindFirst function, 102 FindGlobalComponent function, 121 FindNearest method, 777 FindNext function, 102 FindNextPage function, 205?206 FindWindow function, 307 FirstDll example, 405?406 FishClient example, 893, 894 Flat property, 213 floating-point numbers comparisons with, 89 conversions with, 87 FloatingDockSiteClass property, 234 FloatToCurr function, 87 FloatToDateTime function, 87 fly-by-hints, 182?184, 184, 218, 218 fm flags, 138 FocusControl property, 177 Font dialog box, 288, 288 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Font property, 21, 159 FontDialog component, 288 FontMaster component in Rave, 724 FontMirror property, 724 FontNamePropertyDisplayFontNames variable, 21 fonts in Automation, 478 for controls, 159?160 for dialog boxes, 288, 288 listing, 299 for menu items, 216 in Object Inspector, 21 size of, 276?277 with toolbars, 215 Fonts combo box, 341?344 package for, 344?347, 345?346 using, 347?348 Fonts toolbar in Rave, 718 ForEach method, 133 ForEachFactory method, 462 ForEachModule function, 425?426 Form component, 119 Form Designer, 18?19 Format function, 85, 582 FormatDateTime function, 60 formats for Rave, 720?721, 720 FormatXMLData method, 842, 857 FormCount property, 821 FormCreate method, 127 for pages, 204 in TDateForm, 127 in TForm1, 196?197 in TFormUseIntf, 423 FormDestroy method, 131 FormDLL example, 411 FormIntf demo, 330?331 FormMouseDown method, 263?264 FormMouseMove method, 263?264 FormMouseUp method, 263, 265 FormProp example, 53, 53 forms, 251 About boxes and splash screens for, 289?292, 290 activating, 298, 298 border icons for, 256?257, 257 borders for, 254?256, 254 client area in, 269 closing, 279?280 constraints in, 270 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. creating, 277?279, 278 dialog boxes creating, 282?287, 284?285 predefined, 287?289, 288 direct input keyboard, 259?261, 260 mouse, 261?265 displaying, 267?268, 267 in DLLs, 410?411 and encapsulation, 52?54, 53 fields in hiding, 122?123 removing, 121?122 inheritance in from base forms, 319?321, 319?320 polymorphic, 321?324, 322 multiple-page, 202 image viewer in, 207?210, 207 PageControl and TabSheet for, 202?207, 204?205 for user interface wizard, 210?213, 211 in packages, 417?419, 417 painting in, 265?267 plain, 252?253, 253 position of, 268?269 properties for, 53?54, 53 scaling, 274?277 scrolling, 270?271 automatic, 272?273 coordinates in, 273?274, 273 example, 271?272, 272 secondary, 280?281 size of, 269 snapping in, 269 splitting, 180?181, 180 style of, 254 TForm class, 251?259, 253?254, 257?258 tracking, 299?302, 300 WebBroker technology for, 777?781, 780 windows for, 257?259, 258 Forms page, 28, 277, 278, 280 FormStyle property, 254, 257, 311 FormToText program, 140?141, 141 forward-only cursors, 630?631 Frac function, 921 FramePag example, 327?328, 327 frames, 324?326, 325 in Component Palette, 26, 26 for compound components, 357?358 in MDI applications, 311?315, 313 with pages, 326?328, 327 without pages, 328?330, 329 Frames1 example, 26, 26 Frames2 example, 324?326, 325 FrameTab example, 328?330, 329 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it.. Thanks Framework Assembly Registration Utility (regasm), 501 Framework Class Library (FCL), 904 Free method, 55?56, 58?59, 912 free query forms, 613, 613 Free threading model, 463 FreeAndNil method, 55, 59 FreeInstance class, 335 FreeLibrary function, 408?409 FreeMem method, 84, 921 FreeNotification method, 302, 354, 356 FreeRecordBuffer method, 699 FROM clause in SELECT, 628 FromStart property, 826 fs constants, 254, 311 FTimer class, 351 FTP (File Transfer Protocol) API for, 754?755 ports for, 739 FullExpand method, 194 functions addresses of, 63 names for, 360 overloaded, 46, 404 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Index G GAC (Global Assembly Cache), 917, 917 GACUTIL utility, 917 garbage collection, 911?916 Garbage Test example, 915?916 gen_id function, 566 GeneratorField property, 593, 601 generators, 565?566, 600?602, 601 generic projects, 922 generic unit references, 923 generic units, 922 Get methods in TAXForm1, 491 in WebBroker, 778 Get_Value method, 473 GetAttributes function, 388?389 GetBookmarkData method, 696 GetBookmarkFlag method, 696 GetBufStart method, 194 GetCanModify method, 706 GetCds method, 892 GetClass function, 419 GetCollString method, 384 GetColor function, 410?411 GetControl function, 386?387 GetData method, 547, 702 GetDataAsXml method, 857 GetDataField method, 672 GetDataSource method, 672 GetDriverFunc function, 570 GetDriverVersion method, 568 GetEmployeeData method, 885?886 GetEmployeeNames method, 884?885 GetEnumName function, 585 GetEnvironmentVariable function, 87 GetExtraCode function, 197 GetField method in TMdDataSetOne, 703 in TMdDbProgress, 672 GetFieldData method This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. in TMdDataSetOne, 702?703 in TMdDirDataset, 708 in TObjDataSet, 711?712 GetFileVersion function, 88 GetHeapStatus function, 84 GetIDsOfNames method, 468 GetInterfaceExternalName, 882 GetKeyState function, 218 GetLines method, 379?380 GetLocaleFormatSettings function, 88 GetLongHint method, 218 GetMem method, 84, 921 GetMemo function, 335 GetMemoryManager function, 84, 334 GetMethExternalName, 882 GetModuleFilename, 309 GetNamePath method, 113 GetNewId function, 601 GetNextPacket method, 584 GetObjectContext method, 497 GetOleFont method, 478 GetOleStrings function, 478 GetOptionalParameter method, 668 GetOwner method in TMdMyCollection, 382?383 in TPersistent, 113 GetPackageDescription function, 424 GetPackageInfo function, 424, 426?427 GetPackageInfoTable function, 84, 424 GetProcAddress function, 408, 412 GetPropInfo function, 116 GetPropValue function, 116 GetRecNo method, 698 GetRecord method, 699?700 GetRecordCount method, 698, 891 GetRecordSize method, 699 GetSelItem function, 380 GetShareData method, 414 GetShortHint method, 218 GetStrProp function, 116 GetSubDirs function, 103 GetSystemMetrics function, 259 GetText method, 59?60 GetTextHeight method, 187 GetTickCount function, 476 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. GetValue method, 390 GetValues method, 389 GetVerb method in IComponentEditor, 393 in TMdListCompEditor, 394 GetVerbCount method, 393 GetWindowLong function, 298 GetYear method, 51 GExperts tool, 952 Global Assembly Cache (GAC), 917, 917 global data for DLLs, 400 in Project Explorer, 32 in System unit, 84 global deployment, 916 global handlers, 72 Global Page Catalog node, 717, 723 GlobalCount variable, 821 GlobalEnter method, 178 Globally Unique Identifiers (GUIDs) conversions with, 87 in DCOMConnection, 655 in Delphi for .NET Preview, 928 for interfaces, 69 in IUnknown, 458?460, 459 Google website, 751?752 GotoPage method, 485 GrabHtml method in TFindWebThread, 752?753 in WebSearch program, 785 graphic toolbars, 213 graphical components in Rave, 724 graphical controls, 158. See also images compound components. See Arrow component data-aware, 520 hit counters, 783?784 GreaterThanValue constant, 89 Green Pages in UDDI, 895 Grep.exe tool, 33 GridDemo example, 686 grids data-aware controls for, 516 for databases. See DBGrid control GroupBox component, 119, 166 Grouped property, 230 GroupIndex property for actions, 230 for menu items, 481 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks for radio items, 173 groups in ClientDataSet, 549, 550 project, 26?27 GUIDs (Globally Unique Identifiers) conversions with, 87 in DCOMConnection, 655 in Delphi for .NET Preview, 928 for interfaces, 69 in IUnknown, 458?460, 459 GUIDToString function, 459 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks Index H H files, 401?402 hacks, 62 Handle property in Application, 297 in TWinControl, 161 HandleMessages function, 303?304 HandleNeeded method, 161 HandleReconcileError function, 588 HandlesPackages lists, 422 HandlesTarget method, 385 hashed associative lists, 132?133 header files, 401?402 headers in CGI programs, 769 Height property for components, 18 for forms, 268?269 in TControl, 159 in TMdArrow, 359 HelloWorld example, 901?902, 903 Help actions, 224 Help files, 33, 340 HelpContext property, 222, 256 Hide method, 159 HideComp example, 122?123 HideOptions property, 808 HideUnused property, 246 hiding components, 159 form fields, 122?123 forms, 279 high-level protocols in socket programming, 740 high-low technique, 600 hint directives, 44 Hint property for actions, 222 in Application, 217 for toolbars, 236 HintColor property, 182 HintHidePause property, 182 HintPause property, 182 hints in ToolBar, 182?184, 184, 218, 218, 236 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. HintShortPause property, 182 hit counters, 782?785 HitsGetValue method, 806 HookEvents method, 162 horizontal splitting of forms, 181 HorzScrollBar property, 270, 273 hosts file in IP addresses, 739 hosts in socket programming, 741 HOSTS.SAM file, 739 hot-track activation, 24 HotImages property, 213 Hower, Chad Z., 809 HTM files, 36 HTML (Hypertext Markup Language), 758?759 for data, 761?762, 762 for dynamic pages, 764?765 for pages, 759?761, 760 producer components for, 759 style sheets for, 764?765 for tables, 762?764, 763 templates for, 788 HTML editor, 788 HTML Import, 629 HTML tab, 862 HTMLDoc property, 788 HtmlDom component, 868 HtmlEdit example, 165, 165 HTMLFile property, 788 HtmlProd example, 759?764, 760, 762 HtmlStringToCds method, 785 HtmlToList method, 752?754 HTTP (Hypertext Transfer Protocol), 651, 750?751 API for, 754 for browsers, 756?757, 757 grabbing content in, 751?754, 755 ports for, 739 server, 757?758, 758 WinInet API for, 754?756 HttpDecode function, 743 HttpEncode function, 743 HTTPRIO component, 879 HttpServ example, 757?758, 758 HTTPSoapDispatcher component, 879 HTTPSoapPascalInvoker component, 879 httpsrvr.dll file, 651 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. HTTPWebNode property, 893 HttpWork method, 754 Hypertext Markup Language. See HTML (Hypertext Markup Language) Hypertext Transfer Protocol. See HTTP (Hypertext Transfer Protocol) This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Index I IAppServer interface, 649?650, 667, 890?891 IAppServerOne interface, 654 IAppServerSOAP interface, 891 IB provider, 618 IB_WISQL tool, 564 IBClasses dataset, 610 IBClassReg dataset, 609?610 IBConsole application, 562?564, 563?564 IBDatabase component, 592 IBDatabaseInfo component, 592 IBDataSet component, 592 IBEvents component, 592 IBM DB2 drivers, 567 IBPeopleReg dataset, 610 IBQuery component, 592 IBSQL component, 592 IBSQLMonitor component, 592, 598 IBStoredProc component, 592 IBTable component, 592 IBTransaction component, 592 IBUpdateSQL component, 592 IBX. See InterBase Express (IBX) IbxEmp example, 593?595 IbxMon example, 598, 599 IbxUpdSql example, 595?597, 598 ICO files, 34 IComponentEditor interface, 393 icons for applications, 297 for borders, 256?257, 257 IdAntiFreeze component, 738 IDAPI (Independent Database Application Programming Interface), 615 IDE (Integrated Development Environment), 3?4, 5 compiler messages, 9?10 Component Palette. See Component Palette debugger, 42 desktop settings in, 5?6 editor. See editors environment settings in, 6?7 Form Designer, 18?19 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks libraries in, 5 menus, 7 Object Inspector, 19?23 project management in, 26?32, 27, 32 to-do lists, 7?9, 8 tools, 33?34 identifiers, 924 IDispatch interface, 84, 458, 467?469, 851 IDisposable interface, 912, 915 idle state, 302 IdMessage class, 748 IDockManager interface, 235 IDOMAttr interface, 838 IDOMDocument interface, 838 IDOMElement interface, 838 IDOMNode interface, 838 IDOMNodeList interface, 838 IDOMParseError interface, 836 IDOMText interface, 838 IdPop3 component, 748 IDs GUIDs. See GUIDs (Globally Unique Identifiers) in Interbase, 600?602, 601 IdSMTP component, 748 IdTCPClient component, 741 IdTCPServer component, 741 idThreadMgrDefault component, 738 idThreadMgrPool component, 738 IeFirst example, 860?864, 861, 863 $IF directive, 44 IFirstServer interface, 471?473 IFontDisp interface, 478 IFormOperations interface, 333 IfSender example, 106?107, 106 IfThen function, 88?89, 92 ignorableWarning method, 851 IIDs (interface IDs), 459 IInterface interface, 69, 84, 457 IInvokable interface, 84, 878 IISAM (Installable Indexed Sequential Access Method) drivers, 624 IL Disassembler (ildasm.exe), 908 ildasm.exe (IL Disassembler), 908 Image Editor tool, 33, 348 image viewer in multiple-page forms, 207?210, 207 ImagEdit.exe tool, 33 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks ImageIndex property for actions, 222 in ListView, 189 for menu items, 174 ImageList class, 189, 203, 213 images for dialog boxes, 288 in ListView controls, 188?193, 191 on menus, 185 Images property for menu items, 174 for toolbars, 213 IMdInform interface, 498 IMdWArrowX interface, 488 implementation diagrams, 434 Implementation File Update Wizard, 495 implementation section for DLLs, 400 uses statement in, 256 implicit transactions, 589 Import Source File dialog box, 438 Import Type Library dialog box, 477 ImportedConstraint property, 657 importing Jet engine for, 628?629 in ModelMaker, 437?438 IN clause in SELECT, 628 in-place activation, 484 in-place editing, 480 in-place expansion of component references, 20 in-process servers, 457 Include method, 927 IncludePathURL property, 860 IncludeTrailingPathDelimiter function, 87 Increase method, 49, 495 Increment property, 270 incremental searches, shortcut keys for, 16 indenting, shortcut keys for, 16 Independent Database Application Programming Interface (IDAPI), 615 IndexDefs property, 513 indexes in ADO, 632 in ClientDataSet, 512?513 IndexFieldNames property, 512, 632 Indexing Service, 618 IndexOf method, 128 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Indy (Internet Direct) components, 738, 741?744, 744 HTML. See HTML (Hypertext Markup Language) HTTP. See HTTP (Hypertext Transfer Protocol) for mail, 748?750, 749 Indy (Internet Direct) project, 951 IndyDbSock example, 747, 747 IndySock1 example, 741?744, 744 INetXCustom, 859 InetXPageProducer, 858?859, 861?863, 861 InetXPageProducer editor, 863 infinite constants, 88 Infinity constant, 88 InflateRect function, 682 InFocus example, 176?178, 177 information hiding, 48 inheritance from existing types, 59?63, 60 form, 318?319 from base forms, 319?321, 319?320 polymorphic, 321?324, 322 in ModelMaker, 437?438 restricting, 447 type compatibility in, 62?63 inherited keyword, 65, 272, 320?321 InheritsFrom method, 67, 105 INI files, 331?332 initialization of COM objects, 464 constructors for, 54 of datasets, 690?691 initialization section, 473?474 Initialize method for automation servers, 474 in TNumber, 464 InitializeControls method, 936?937 InitializeMenu method, 936, 939?940 InitWidget method, 162 inline keyword, 325 inner transactions, 634?635 input, forms keyboard, 259?261, 260 mouse, 261?265 input focus handling, 176?178, 176?177 messages for, 374 Input Mask editor, 164 InputBox function, 289 InputQuery function, 289 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks InquireSoap interface, 897 InRange function, 89 Insert command for records, 520 Insert method, 128 insert operations, trigger firing from, 565 InsertComponent method, 118?119 InsertObjectDialog method, 481 InsertRecord method, 701 inside-out activation, 484 Install COM+ Object dialog box, 495?496 Install Into New Application page, 496 Installable Indexed Sequential Access Method (IISAM) drivers, 624 installing DLL wizards, 41 property editors, 391?392 instances, checking for, 307?310 InstanceSize method, 105 instancing in COM, 463 Integer type, 478 Integrated Development Environment. See IDE (Integrated Development Environment) Integrated Translation Environment (ITE), 368, 399 InterBase generators and triggers in, 565?566 history of, 562 IBConsole application, 562?564, 563?564 IBX. See InterBase Express (IBX) operation of, 561?562 real-world examples booking classes, 608?611, 610 case-insensitive searches, 602?603 free query forms, 613, 613 generators and IDs, 600?602, 601 locations and people, 603?605 lookup dialogs, 611?613 user interfaces, 605?608, 607 server-side programming in, 564?565 InterBase Express (IBX), 507, 591 administrative components in, 593 dataset components in, 592?593 example, 593?594 live queries in, 594?597, 598 monitoring, 598, 599 system data in, 599?600, 599 InterBase Objects program, 564 InterBase Workbench tool, 564 InterceptGUID property, 652 interface IDs (IIDs), 459 interface section, 400 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Interface Wizard, 432, 433 Interfaced Component Reference model, 21 interfaces, 48, 69?71 and base forms, 330, 333?334 for COM server, 461?463, 462, 465?466 for compound components, 354?356 of controls, 483 in packages, 420?424 user. See user interface InterfaceSupportsErrorInfo method, 458 InterlockedDecrement function, 458 InterlockedIncrement function, 458, 822 internal components in compound components, 349?350 internal instancing, 463 internal messages, 302, 372?374, 373 internal objects in Automation, 482?483, 483 InternalAddRecord method in TMdCustomDataSet, 699 in TMdDataSetOne, 701 InternalAfterOpen method in TMdCustomDataSet, 691?692 in TMdDirDataset, 707 InternalCancel method, 712 InternalClose method, 694 InternalDelete method, 699 InternalEdit method, 712 InternalFieldDefs method, 710?711 InternalFirst method, 697 InternalGotoBookmark method, 697 InternalHandleException method, 703 InternalInitFieldDefs method in TMdCustomDataSet, 692?694 in TMdDirDataset, 707?708 InternalInitRecord method, 699 InternalLast method, 698 InternalLoadCurrentRecord method in TMdDataSetStream, 700?701 in TMdListDataSet, 706 internally calculated fields, 513 InternalOpen method, 690?691 InternalPost method, 699, 701 InternalPreOpen method in TMdCustomDataSet, 691 in TMdListDataSet, 705 InternalRecordCount method in TMdCustomDataSet, 698?699 in TMdListDataSet, 706 InternalRethinkHotkey method, 182 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. InternalScriptName property, 774 InternalSetToRecord method, 697 Internet, actions for, 224 Internet Direct (Indy) components, 738, 741?744, 744 HTML. See HTML (Hypertext Markup Language) HTTP. See HTTP (Hypertext Transfer Protocol) for mail, 748?750, 749 Internet Direct (Indy) project, 951 Internet Express, 858 JavaScript support in, 859?864, 861, 863 XMLBroker component in, 858 Internet page, 7, 788 Internet programming, 737 HTML. See HTML (Hypertext Markup Language) HTTP. See HTTP (Hypertext Transfer Protocol) for mail, 748?750, 749 with sockets. See socket programming XML. See XML Internet Server API (ISAPI), 769?770 InternetCloseHandle function, 755 InternetOpen function, 755 InternetOpenURL function, 755 InternetReadFile function, 755 Interop services, 908 interposer classes, 332?333 IntfColSel unit, 421?422 IntfFormPack package, 421?422 IntfFormPack2 package, 421 IntfPack example, 421 IntfPack package, 421 INTO clause in SELECT, 628 InTransaction property, 589 IntraWeb library, 809?810 architectures in, 815 for Web applications, 810?815, 812 building, 815?818, 817 databases, 825?832, 827?828, 830, 832 layout, 824?825, 825 multipage, 818?821, 819 sessions management, 821?823, 823 with WebBroker, 823?824 IntraWeb page, 810 IntToStr function, 85 INumber interface, 465 invalid areas, 266 Invalidate method, 266?267 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks InvalidateRect function, 267 InvalidateRegion function, 267 Invoke method, 468?469 IObjectContext interface, 497 IP addresses, 739 IPictureDisp interface, 478 IProduceContent interface, 772 IProperty interface, 388 is operator, 67?68 ISAPI (Internet Server API), 769?770 IsCallerInRole method, 497 IsConsole variable, 84 IsCursorOpen method, 695 IsDefaultPropertyValue function, 148 IsEqualGUID function, 87 IsInfinite function, 88 IsInTransaction method, 497 IsLibrary variable, 84 IsMultiThread variable, 84 IsNan function, 88 IsNull method, 703 isolation levels in transactions, 590 IsSecurityEnabled method, 497 IStrings interface, 478 IsUniDirectional function, 572 ISupportErrorInfo interface, 458 IsZero function, 89 ITE (Integrated Translation Environment), 368, 399 ItemHeight property, 187 ItemIndex property, 250 in ListBox, 167 for radio group components, 259 ItemProps property, 171 Items property in ActionBars, 246 for fonts, 343 for images, 189 in ListBox, 167 in TBookMarkStr, 542 in TList, 133 in TreeView, 194 Items string list, 169 ItemsEx property, 169 IUnknown interface, 69, 84, 457?458 class factories in, 460 GUIDs in, 458?460, 459 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. IVBSAXContentHandler interface, 851 IVBSAXErrorHandler interface, 851 IW Component Park, 810 IWAppFormCreate method, 818, 827 IWButton component, 811 IWChart component, 810 IWClientGrid example, 831?832, 832 IWClientSideDataSet component, 831 IWClientSideDataSetDBLink component, 831 IWCSLabel component, 831 IWCSNavigator component, 831 IWDataModulePool component, 810 IWDialogs component, 810 IWDynamicChart component, 831 IWDynGrid component, 831 IWEdit component, 811 IWGranPrimo component, 810 IWGridDemo example, 828?830, 828, 830 IWLayoutMgrHTML component, 824 IWListbox component, 811 IWModuleController component, 823 IWOpenSource component, 810 IWPageProducer component, 823 IWScrollData example, 826?827, 827 IWServerControllerBaseNewSession method, 822 IWSession example, 821?823, 823 IWSimpleApp example, 811?815, 812 IWTranslator component, 810 IWTree example, 816?818, 817 IWTwoForms example, 818?821, 819 IXMLDocument interface, 839, 848 IXMLDocumentAccess interface, 836 IXMLNode interface, 839 IXMLNodeCollection interface, 839 IXMLNodeList interface, 839 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Index J JavaScript in Internet Express, 859?864, 861, 863 for WebSnap, 791 JavaScript language, 814 JEDI (Joint Endeavor of Delphi Innovators), 952 Jet engine, 624 for Excel, 625?626, 626 for importing and exporting, 628?629 for Paradox, 624?625, 625 for text files, 626?628 JIT (Just in Time) compiler, 907?908 joins, 636?637 Joint Endeavor of Delphi Innovators (JEDI), 952 JPEG file format, 784 JpegImage component, 783?784 JScript, 791 Just in Time (JIT) compiler, 907?908 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Index K KeepRowTogether property, 731 keyboard for form input, 259?261, 260 messages for, 377 KeyField property, 519 KeyOptions property, 172 KeyPreview property, 259 keys in associative lists, 132?133 in database design, 558?560 in keyset cursors, 631 keyset cursors, 631 Kind property, 286 KPreview example, 259?260, 260 Kylix, CLX in, 110 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Index L LabelDoubleClick method, 285?286 LabeledEdit component, 163 LabelPosition property, 163 LabelSpacing property, 163 Language Exceptions page, 74 large documents with XML, 869?873, 871 LargeImages property, 189 LargeXML example, 869?871, 871 LastSession property, 246 late binding abstract methods in, 66?67 for message handlers, 66 overriding and redefining methods in, 64?65 and polymorphism, 63?64, 64 virtual vs. dynamic methods in, 65?66 layout for Web applications, 824?825, 825 Layout Manager, 825, 825 LayoutChanged method, 684?685 least-recently used menu items, 245?247, 245 Left property for components, 18 for forms, 268 in TControl, 159 Lesser General Public License (LGPL), 949 LessThanValue constant, 89 LGPL (Lesser General Public License), 949 LIB file, 401 LibComp example, 153?154 $LIBPREFIX directive, 407 libraries ActiveX, 34, 460?461 for controls dual, 151?155, 152 visual, 155?156, 156 DataSnap, 649 for Delphi for .NET Preview, 934?940, 940 DLL. See DLLs (dynamic link libraries) extending, 337?340 in IDE, 5 IntraWeb. See IntraWeb library names for, 407?408 type, 468?470 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. library path setting, 347 library statement, 403 LibSpeed example, 155 $LIBSUFFIX directive, 407 $LIBVERSION directive, 407 LIC files, 36 licenses for ActiveX controls, 488 for author tools, 949 for Qt libraries, 150 line breaks in text files, 85 Lines class, 379 Lines string list, 164 Lines toolbar in Rave, 718 LineStart method, 147 LinkedActionLists property, 247 linking, 480 to definitions, 13 dynamic vs. static, 397?398 to Web database details, 827?830, 828, 830 Linux compatibility functions for, 88 libraries for, 155?156, 156 list actions, 224, 248?250, 249 list-based data-aware controls, 517?518, 518 list boxes, 167, 186?188 list components. See lists and list components List Template Wizard, 945 ListActions example, 248?250, 249 ListBox component, 167 ListBoxForm form, 378?379 ListCli example, 478 ListControl property, 249 ListDate example, 132 ListDemo example, 129?131, 130 ListDialDemo example, 381, 381 ListDialog component, 393?395, 394 listening socket connections, 740 lists and list components, 128?131, 130 CheckBoxList, 169 ComboBox, 168 ComboBoxEx and ColorBox, 169 as datasets, 705?706 hashed associative, 132?133 ListBox, 167 ListView and TreeView, 169?170 type-safe, 133?135 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks ValueListEditor, 170?172, 170 ListServ example, 478 ListSource property, 519 ListTest example, 387 ListView component, 169?170, 188?193, 191 ListView Item Editor, 189, 191 literals in input masks, 164 live queries in IBX, 594?597, 598 LIVE_SERVER_AT_DESIGN_TIME directive, 477 loadable views, 16?18, 17?18 LoadBalanced property, 667 LoadDynaPackage method, 423 LoadFile method, 322 LoadFromFile method in datasets, 510?511, 645 in TreeView, 194 in TStringList and TStrings, 128 LoadFromStream method in TBlobField, 139 in TStream, 137 loading packages, 419?420 LoadLibrary function, 408 LoadPackage function, 419 LoadParamsOnConnect property, 572 local domain names, 739 local tables for ClientDataSet connections for, 509?510, 510 defining, 511?512, 512 LocalConnection component, 653 localhosts in IP addresses, 739 Localizable property, 368 Locate method, 514 LocateFileService component, 788, 798 locating files, 798 records, 514?515 locations ADO cursor, 629?630 in InterBase example, 603?605 Locked property, 481 locking control position, 19 records, 587 in ADO, 635?636, 639?641 in client/server programming, 557 recursive, 86 LockType property, 635, 638 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks Log Changes property, 515 LogException method, 75?76 logging for ClientDataSet, 515 errors, 75?76, 76 logical identifiers, 559 logical keys, 558 logical operators, 513 logical three-tier architecture, 648 LoginForm adapter, 795 LoginFormAdapter component, 807 LoginPrompt property, 572 logins in WebSnap, 807?808 lookup controls, 519?520, 519 lookup dialogs, 611?613 lookup fields, 533?534, 534 ltBatchOptimistic value, 635, 638 ltOptimistic value, 635 ltPessimistic value, 635 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Index M $M+ compiler directive, 114 macros for ModelMaker, 445?446 shortcut keys for, 16 mail, 748?750, 749 Mail Merge Editor, 729 MailMergeItems property, 729 Main Form option, 41 main forms in MDI applications, 316?317, 316 Main window, looking for, 307?308 MainForm object, 301 MainForm property, 277, 297 MainInstance variable, 84 maintained aggregates, 550 maintenance releases of packages, 417 major releases of packages, 417 MakeObjectInstance method, 317 MakeSplash method, 290?292 MakeXmlAttribute function, 884?885 MakeXmlStr function, 884 managed code, 905, 908?909 manifest files for themes, 220?221 manifests, 906 ManualDock method, 235 ManualFloat method, 235 many-to-many relations, 557?558 mapping object-relational, 559 in XML, 854?857, 854, 856?857, 886?887, 887 Mapping page, 854 MapTable example, 856?857, 857 MapViewOfFile function, 413?414 markers in XML, 834?835 markup languages, 833 marshaling in Automation, 467 in COM, 457 MaskEdit component, 163?164 MastDet example, 552?553, 553 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. . Thanks master/detail relations in ClientDataSet, 552?553, 553 in DataSnap, 664?665, 665 in Rave reports, 730?731, 731 in WebSnap, 803?805, 805 MasterAdapter property, 803 MasterDataView property, 731 MasterFields property, 552 Mastering Delphi Com+ Test example, 496 mastering.gdb database, 600 MasterKey property, 731 Math unit, 88?90, 90 MaxRecords property, 858 MaxRows property, 762 MaxSessions property, 805 MaxValue property, 658 MBParade example, 289 MDAC (Microsoft Data Access Components), 616?617 MdComEvents library, 498 MdDbGrid component, 683, 683 MdDesPk package, 392, 395 MdEdit1 example, 229?230 MdEdit2 example, 232?236, 232, 236 MdEdit3 example, 247?248 MDI (Multiple Document Interface) applications, 310 child forms and merging menus in, 315?316, 315 frame and child windows in, 311?315, 313 main forms in, 316?317, 316 style property for, 254 subclassing client windows in, 317?318 MDI window actions, 224 MDIChildCount property, 312 MDIChildren property, 312, 316 MdiDemo example, 313?315, 313 MdiMulti example, 315?316, 315 MdiMulti Demo4 example, 316?317, 316 MdListBoxForm class, 378?379 MdListDialog class, 381 MdPack package, 347?348 MdWArrowImpl1 example, 488 Mediator pattern, 449 members, converting and moving, 447 Memo component, 723 Memo controls, 836 memo fields in Rave, 729 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks MemoRich component, 164?165 memory allocation routines for, 84 DLLs in, 411?414, 415 garbage collection for, 911?916 for methods, 115 for objects, 58?59 for screen, 265?266 for strings, 58 units for, 95?96 memory leaks, 56 memory management records, 334?335 memory manager, 334?336 memory-mapped files, sharing data with, 413?414, 415 Memory Snap tool, 948?949 Menu Designer, 174, 174 menu.html file, 793 menus, 173 accelerator keys for, 181?182 in control Bars, 234 images on, 185 items on least-recently used, 245?247, 245 owner-draw, 185?186, 186 Menu Designer for, 174, 174 merging in MDI applications, 315?316, 315 in OLE, 481 new, 7 pop-up, 174?176 in ToolBar, 216?217 MergeChangesLog method, 515 merging menus in MDI applications, 315?316, 315 in OLE, 481 message boxes, 289 $MESSAGE directive, 44 message directive, 66 message keyword, 369 message-response methods, 369 message spy program, 33 MessageBox method, 289 MessageDlg function, 289 MessageDlgPos function, 289 messages and message handlers compiler, 31?32 internal, 372?373, 373 late binding for, 66 mail, 748?750, 749 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks overriding, 368?372 queues for, 302 in sequence diagrams, 433 for triggering events, 124 user-defined, 309?310 in Windows, 303?304 in windows controls, 373?378 metadata in CLI, 904 in dbExpress, 578?579, 579 in Jet, 628 Metafile component, 724 Method Implementation Code Editor, 441?442, 442 method pointers for events, 125?126 MethodAddress method, 115 MethodName method, 115 methods abstract, 66?67 for ActiveX controls, 484 characteristics of, 46?47 code completion for, 14?15 in DataSnap, 663?664 in Delphi for .NET Preview, 925 messages for, 376 names for, 46 overloaded, 404 overriding and redefining, 64?65, 70 virtual, 70 in COM server, 466?467 vs. dynamic, 65?66 MGA (Multi-Generational Architecture), 561 Microsoft Access databases, 624 Microsoft Data Access Components (MDAC), 616?617 Microsoft Database Engine (MSDE), 617 Microsoft Indexing Service, 618 Microsoft Intermediate Language (MSIL). See CIL (Common Intermediate Language) Microsoft.Jet driver, 617 Microsoft libraries, 934?940, 940 Microsoft Shared Source CLI, 905 Microsoft Transaction Server (MTS), 494 Microsoft Word with Automation, 479 DLLs for, 411 MIDAS (Middle-tier Distributed Application Services), 649 Midas library for ClientDataSet, 510?511 MidasLib unit, 511, 569 MilliSecondOfMonth function, 91 mind-map diagrams, 435 Minimize method, 269 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. MiniSize program, 82?83 MinSize property, 180?181 MinValue property, 658 mirroring in Rave, 732?733 MltGrid example, 543, 543 modal forms, 410?411 modal windows, 280 ModalResult property, 285, 379 modeless dialog boxes, 280, 285?287, 285 ModelMaker, 429?430 class diagrams in, 431?432, 432?433 coding features of, 435 Delphi integration with, 436?437 Difference view, 442?443, 443 Event Types view, 443 managing, 438?439, 439 Method Implementation Code Editor, 441?442, 442 refactoring, 446?447 templates for, 450?452, 450 Unit Code Editor, 439?441 common diagram elements in, 435?436, 436 design patterns in, 447?450 documentation in, 444?445, 444 features in, 452 inheritance in, 437?438 internal model in, 430 macros for, 445?446 non-UML diagrams in, 435 sequence diagrams in, 433?434, 433 use case diagrams in, 434 Modified method in TPropertyPage, 490 in TSoundProperty, 390 Modified property, 313 ModifyAccess property, 808 ModuleIsPackage variable, 424 modules data modules, 535, 648 for COM+, 497 for WebSnap, 798?799 System unit support for, 84 Modules object, 793?794 monitor resolution, 299 monitoring dbExpress connections, 576?577, 577 IBX, 598, 599 Mono project, 905?906 mouse input dragging and drawing, 262?265, 265 for forms, 261?262 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks mouse messages, 374 mouse-related virtual keys, 262 MouseCoord method, 544 MouseOne example, 262?265, 265 MoveBy method, 536 movement in datasets, 536?537, 695?698, 696 bookmarks for, 537?538 editing columns, 539?540 totals of columns, 537, 537 MoveTo method, 195, 212 moving classes, 446 components, 18 members, 447 MS-XML processor, 865 MSCorEE.dll file, 908 MSDAORA driver, 617 MSDAOSP driver, 617 MSDASQL driver, 617 MSDE (Microsoft Database Engine), 617 MSIL (Microsoft Intermediate Language). See CIL (Common Intermediate Language) MSOLAP driver, 617 MSXML DOM, 871?872 MSXML library, 850?851 MSXML parser, 644 MSXML SDK, 838 MTS (Microsoft Transaction Server), 494 Multi-Generational Architecture (MGA), 561 multi-read synchronizer, 86 multi-threaded apartment model, 463 multicast events, 926?927 MulticastDelegate class, 910?911, 927 Multiline Palette Manager, 947 multipage Web applications, 818?821, 819 Multiple Document Interface (MDI) applications, 310 child forms and merging menus in, 315?316, 315 frame and child windows in, 311?315, 313 main forms in, 316?317, 316 style property for, 254 subclassing client windows in, 317?318 multiple frames without pages, 328?330, 329 multiple instancing, 463 multiple-page forms, 202 image viewer in, 207?210, 207 PageControl and TabSheet for, 202?207, 204?205 for user interface wizard, 210?213, 211 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. multiple pages, WebSnap, 789?791, 790 multiple selections DBGrid for, 542?543, 543 in ListBox, 167 MultipleTransactionsSupported property, 590 multipurpose WebModule, 774?776 MultiSect property, 167 multitasking, 302, 304 multithreading, 304?307 class for, 86 with socket connections, 738 multitier databases. See DataSnap Multitier page, 653 MultiWin example, 281?282 mutexes (mutual exclusion objects), 308 MyBase file, 508. See also ClientDataSet component MyBase1 example, 509?510, 510 MyBase2 example, 511?513, 512 MySQL drivers, 567 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks Index N name directive, 402 name mangling, 401?402 name-value pairs for lists, 129 names and Name property accessing properties by, 115?117, 117 for action objects, 222 in C++, 401?402 for components, 339 components without, 122 for domains, 739 for fields, 360 for fonts, 21 for functions, 360 for methods, 46, 115 in ModelMaker code, 446 for projects and library, 407?408 for properties, 360 in TComponent, 121 in TField, 527 for units, 44 namespaces in .NET architecture, 906 for units, 922?924 namespaces clause, 923 NameValues example, 170?171, 170 NameValueSeparator property, 129 native formats in ClientDataSet, 511 date time, 709 native look-and-feel in library selection, 155 navigating datasets, 536?537, 695?698, 696 bookmarks for, 537?538 editing columns, 539?540 totals of columns, 537, 537 NegInfinity constant, 88 nested markers, 834 nested transactions, 634?635 nested try blocks, 72 nested types, 926 .NET architecture, 500?502, 502, 899 assemblies in, 906?907 CIL, 907?911 CLI in, 903?904 CLR in, 905?906 Delphi for .NET Preview. See Delphi for .NET Preview . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. deployment and versioning in, 916?917, 917 garbage collection in, 911?916 .NET Framework, 900 NetClassInfo example, 932?933, 933 NetCLX, 110, 112 NetEuroConv example, 933 NetImport example, 500?502, 502 NetLibrary library, 500?502 NetLibSpeed example, 933 NetNumberClass unit, 501 Netscape Server API (NSAPI), 769?770 Neutral threading model, 463 New Component dialog box, 341, 341 New Field dialog box, 531, 531, 534 New Form option, 41 New Items dialog box, 39?40, 40 for ActiveX controls, 489 for COM+, 494 for DataSnap, 653 for form inheritance, 319?320, 319 for IntraWeb, 810 for Web services, 877, 889 for WebBroker, 770 for WebSnap, 787 for XML Data Binding Wizard, 847 New Project option, 41 New Transactional Object dialog box, 495, 495 New Web Server Application dialog box, 770, 773, 781 New WebSnap Application dialog box, 787, 787 New WebSnap Page Module dialog box, 789, 790 NewButtonClick method, 301 NewDate example, 59?60, 60 NewGuid example, 459?460, 459 NewInstance class, 335 NewItem function, 174 NewLine function, 174 NewMenu function, 174 NewPopupMenu function, 174 NewSubMenu function, 174 NewValue property, 641 NewWinProcedure method, 318 nil value for forms, 282 with Free, 55, 58?59 NoAction object, 227 NodeIndentStr property, 842 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. nodes in TreeView, 197?198, 199 in XSLT, 864?865 NodeType property, 840 NonAware example, 545?547, 545 nonblocking socket connections, 738 nonvisual components, 111, 378?381, 381 nonwindowed controls, 158 normalization rules, 558 Notebook component, 202 Notification method for data-aware controls, 673 in TComponent, 301?302 in TMdPersonalData, 354 in TMdViewer, 355?356 notifications messages for, 374 in windows controls, 376?377 NotifyDataLinks method, 670 NoTitle example, 258?259, 258 NSAPI (Netscape Server API), 769?770 null values with field events, 535?536, 536 NullAsStringValue variable, 94 NullDates example, 535?536, 536 NullEqualityRule variable, 94 NullMagnitudeRule variable, 94 NullStrictConvert variable, 94 Numeric edit box creating, 368?370 with thousands separators, 370?371 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks Index O OBJ files, 36 ObjAddRef method, 458 ObjAuto unit, 148 ObjClass property, 710 ObjDataSetDemo example, 713, 713 Object Debugger, 948 object identifiers (OIDs) in database design, 558?560 in Interbase, 600?602, 601 Object Inspector, 19?21 for components, 351?352, 352 drop-down fonts in, 21 Object TreeView in, 22?23 property categories in, 21?22 Object Inspector Font Wizard, 945 object linking, 480 Object Linking and Embedding (OLE), 456?457 object-oriented programming (OOP), 43, 64 and modeling. See ModelMaker for reusable components, 483 object reference model, 55?56, 55 assigning objects in, 56?58, 56 memory for objects in, 58?59 object-relational mapping, 559 Object Repository, 39?41, 40 Object TreeView, 22?23 ObjectBinaryToText method, 140 ObjectPropertiesDialog method, 482 objects assigning, 56?58, 56 in Automation, 476?477, 482?483, 483 code completion for, 14?15 for COM server, 461?463, 462 in CTS, 909?910 datasets of, 710?713, 713 in DataSnap, 667 in Delphi, 44?48 field, 527?528, 528 memory for, 58?59 scope of, 476?477 ObjectTextToBinary method, 140 ObjQueryInterface method, 458 ObjRelease method, 458 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . OBJREPOS subdirectory, 41 ObjsLeft example, 335?336 Observer pattern, 449 octets in IP addresses, 739 OCX (OLE Controls), 456, 483 OCX files, 36 ODBC (Open Database Connectivity), 615, 644 ODList example, 187?188 ODMenu example, 185?186, 186 Office programs with Automation, 478?479 oh.exe tool, 33 OIDs (object identifiers) in database design, 558?560 in Interbase, 600?602, 601 OLAP (Online Analytical Processing), 617 OldCreateOrder property, 153, 279 OldValue property, 641?642 OLE (Object Linking and Embedding), 456?457 OLE Automation. See Automation OLE container messages, 376 OLE Controls (OCX), 456, 483 OLE DB Provider, 617?618 OLE DB Provider Development Toolkit, 618 OLE DB Provider For Indexing Service, 617 OLE DB Provider For Internet Publishing, 617 OLE DB Provider For OLAP, 617 OLE DB providers, 616?617 OLE Insert Object dialog box, 480?481 OleCont example, 482, 482 OleContainer component, 480?482, 482 OnAction event, 771?772 OnActionExecute event, 228, 296 OnActionUpdate event, 296 OnActivate event, 278, 296, 298 OnActiveFormChange event, 299?300 OnAdvancedDrawItem event, 186 OnArrowDblClick event, 364?365 OnBeforeDispatchPage event, 790 OnBeforeExecuteAction event, 797 OnBeforePageDispatch event, 794 OnCalcFields event, 531, 585 OnCanResize event, 270 OnCanViewPage event, 808 OnChange event This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. in TabControl, 208 in TDate, 126 in TMdArrow, 363 OnClick event, 125, 261 OnClose event, 278?279, 300 OnCloseQuery event, 278?279 OnCloseUp event, 168 OnColumnClick event, 191 OnCommand event, 742 OnCommandGet event, 757, 765 OnConstrainedResize event, 270 OnContextMenu event, 175 OnContextPopup event, 176 OnCreate event, 277?279, 299 OnCreateNodesClass event, 197 OnDataChange event, 546 OnDeactivate event, 296, 298 OnDeleteError event, 553 OnDestroy event, 279, 301 OnDockDrop event, 236 OnDockOver event, 235?236 OnDoubleClick event, 285 OnDragDrop event, 98 for docking, 234 for TreeView, 195 OnDragOver event, 98 for docking, 234 for TreeView, 195 OnDrawColumnCell event, 540?541 OnDrawItem event, 185 OnDrawTab event, 209 OnDropDown event, 168 one-to-many relations, 557 one-to-one relations, 557 OneCopy example, 308?310 OnEditButtonClick event, 533 OnEditError event, 553 OnEndDock event, 234, 236 OnEnter event, 177?178 OnException event, 75, 296, 553 OnExecute event in ActionFont, 313 in ActionLink, 223?224 for actions, 228, 228 OnExecuteAction, 223 OnExit event, 177?178 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. OnFind event, 288 OnFindIncludeFile event, 798 OnFindStream event, 798 OnFindTemplateFile event, 798 OnFormatCell event, 763 OnGetData event, 668 OnGetDataSetProperties event, 667 OnGetItem event, 249 OnGetItemCount event, 249 OnGetResponse event, 864 OnGetText event, 535, 541, 549 OnGetValue event, 794, 797 OnHelp event, 257, 296 OnHint event, 217, 296 OnHTMLTag event, 760 OnIdle event, 215, 296, 304 OnItemSelected event, 250 OnKeyPress event, 163, 259 Online Analytical Processing (OLAP), 617 OnLogTrace event, 576 OnMeasureItem event, 185, 187 OnMessage event, 296 OnMinimize event, 296 OnMouseDown event, 261 OnMouseMove event, 261?262 OnMouseUp event, 261 OnMouseWheel event, 261 OnMouseWheelDown event, 261 OnMouseWheelUp event, 261 OnMove event, 181 OnNewRecord event, 547 OnPageAccessDenied event, 808 OnPaint event, 265?266, 274 OnPostError event, 553 OnReceivingData event, 893 OnReconcileError event, 587, 651, 659?660 OnRecordChangeComplete event, 641 OnRecordSetCreate event, 622 OnReplace event, 288 OnResize event, 269?271 OnRestore event, 296 OnScroll event, 271 OnSetText event, 535, 541 OnShortCut event, 296 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks OnShow event, 278 OnShowHint event, 183, 296 OnStartDock event, 234 OnStateChange event, 525, 546 OnStatusTextChange event, 486 OnTag event, 760 in PageProducer, 779 in WebSnap, 791 OnTimer event, 492 OnTitleChange event, 486 OnTitleClick event, 830 OnTrace event, 576 OnUpdate event in ActionCount, 227 in ActionFont, 313 and actions, 224, 229 in MDI applications, 314 OnUpdateData event, 660 OnUpdateError event, 553, 641, 660 OnValidate event, 535 OnWillChangeRecord event, 641 OOP (object-oriented programming), 43, 64 and modeling. See ModelMaker for reusable components, 483 OOP Form Wizard, 945 opaque strings, 538 Open Database Connectivity (ODBC), 615, 644 open-source projects, 951?952 Open Tools API, 452 Open XML project, 951 OpenDialog component, 287 OpenHelp tool, 33 opening datasets, 690?694 opening markers in XML, 834?835 openItemClick method, 937, 939?940 OpenPictureDialog component, 288 OpenSchema method, 622?623, 623 OpenTools API, 388 OpenXML DOM, 838 Operator property, 734 optimistic locking, 587 in ADO, 639?641 in client/server programming, 557 options, components for, 165?166 Options property in DataSetProvider, 658 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks in DBGrid, 516 Oracle drivers, 567 orthogonal lines in ModelMaker, 452 out-of-process servers, 457 outer transactions, 634?635 OutLabel property, 353 Output Options dialog box, 720, 720 overload directive, 404 overload keyword, 46, 65 overloaded constructors, 54?55 overloaded methods, 46, 404 override keyword, 64 overriding Finalize, 911?912 message handlers, 368?372 methods in late binding, 64?65 virtual, 70 owner components, 58 owner-draw controls, 184?185 list box of colors, 186?188 menu items, 185?186, 186 messages for, 377 Owner property, 119?120 OwnerDraw property, 185, 209 ownership in TComponent, 117?120, 120 OwnHandle property, 162 OwnsObjects property, 131 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks Index P P/Invoke (Platform Invocation Service), 904 pa attributes, 388 ~PA files, 37 Package Collection Editor tool, 33 Package Editor, 345, 345, 347?348, 349, 417, 417 PackageInfo pointer type, 84 packages, 415?416 for components, 337?339 for Fonts combo box, 344?347, 345?346 forms in, 417?419, 417 interfaces in, 420?424 loading at run time, 419?420 and program size, 30?31 structure of, 424?427, 425 System unit support for, 84 versioning in, 416?417 Packages page, 346 PackAuto package, 477 PacketRecords property, 575, 584 packets with ClientDataSet, 584 in DataSnap, 651?652, 667?668 PackInfo example, 425?427, 425 PackWithForm package, 418, 420 Page mode in IntraWeb, 815 page numbers in Rave, 724 Page object, 793 PageControl component, 119, 202?207, 204?205 actions for, 224 docking to, 239?241, 241 in XML, 836 PageControl property, 206 PagedAdapter component, 794 PageDesigner page, 717 PageDispatcher component, 787, 794, 808 PageHead component, 774 PageNumInit component in Rave, 724 PageProducer component, 759?761, 774, 779, 788 pages frames with, 326?328, 327 frames without, 328?330, 329 Web, ActiveX controls in, 492?493, 493 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks Pages example, 202?207, 204?205 Pages list, 793 PageScroller component, 172?173 PageSize property, 799 PageTail component, 774?775 Paint method, 358, 361?363, 362 painting DBGrids, 540?542, 542 in windows, 265?267 Panel component, 119 Panels property, 382 Paradox, Jet engine for, 624?625, 625 ParamByName method, 581 ParamCount global variable, 84 parameters code, 15 for DLLs, 399 for mouse events, 262 in overloaded methods, 46 in stored procedures, 565 parametric queries in DataSnap, 663, 663 in dbExpress, 579?581, 580?581 Params property in queries, 663 in SQLConnection, 572 in SQLDataSet, 580?581 in XMLBroker, 858 ParamStr global variable, 84 Parent property, 158?159 ParentColor property, 160 ParentFont property, 160 ParentXxx properties, 374 ParQuery example, 580?581, 581 parsers, MSXML, 644 parseURL method, 851 PAS files, 36 Pascal language, 38, 44 passing XML documents, 884?886 PasswordChar property, 163 Paste Link operation, 480 PasteSpecialClick event, 481 PasteSpecialDialog method, 481 pasting components, 24?25 patch files, 415 path delimiter functions, 87 PathInfo property, 863 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. patterns in ModelMaker, 447?450 PCE.exe tool, 33 PChar type, 405?406 PE (Portable Executable) format, 904, 908 Peek method, 131 people in InterBase example, 603?605 performance in InterBase, 561 Performance Monitor for connections, 644 permissions in WebSnap, 808 Persisted Recordset provider, 618 persistency in ADO recordsets, 644?645 in Arrow component properties, 362?364, 364 class for, 113 in streaming, 140?142, 141 Personal edition, 4 pessimistic locking in ADO, 635?636 PEVerify utility, 909 physical keys, 558?559 PickList property, 516 PixelsPerInch property, 275?276 plain component packages, 338 plain forms, 252?253, 253 Platform Invocation Service (P/Invoke), 904 platform-specific symbols, 156 platforms for databases, 567?569 playing compound objects, 480 PlaySound function, 64, 372, 391 PMdRecInfo pointer type, 696 po options, 666?667 pointers for bookmarks, 696 in Delphi for .NET Preview, 920 in object reference model, 55, 55 for procedures, 409?410 PoliForm example, 322?324, 322 PolyAnimals example, 64, 64 polymorphic forms, 321?324, 322 polymorphism, 63?66, 64 abstract methods in, 66?67 in interfaces, 70 pooling connection, 643?644 object, 667 Pop method, 131 pop-up menus, 173?176 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. POP3 (Post Office Protocol, version 3), 740 PopulateTypes method, 937?938 Popup method, 175 PopupActionBarEx component, 242 PopupMenu property, 174?175 portability of database engines, 506 in library selection, 155 of text DFM files, 19 Portable Executable (PE) format, 904, 908 PortableDragTree example, 196?197 porting programs, 247?248 ports in socket programming, 739?740 Pos function, 93 PosEx function, 93 position and Position property of controls, 159, 163 of Form Designer components, 18 of forms, 255, 268?269 of mouse, 262 of scroll bars, 271 in TStream, 136 Post command, 520 POST method, 778 Post Office Protocol, version 3 (POP3), 740 PostMessage method, 66, 303?304, 310 predefined items actions, 224?225 dialog boxes, 287?289, 288 preemptive multitasking, 302 Preferences page for AutoSave feature, 11 for compiler, 30 for docking, 6 prefixes for functions, 360 for names, 121 pressed-down state, 173 Preview compiler, 900 Preview pages, HTML, 788 previewing in Rave, 719, 719 primary keys, 558?560 printing in dbExpress, 581?584 PrintOutDataSet method, 582?583 PrioritySchedule property, 246 private specifier, 48?50, 925 ProcessMessages function, 303?304 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Producer object, 793 Producer property, 772, 776, 863 ProducerContent property, 772 Professional Studio edition, 4 program flow in exceptions, 72?73 program statement, 922 programmability, client/server programming for, 557 ProgressBar component, 172, 671?673, 673 Project JEDI, 952 Project Manager, 26?28, 27, 723 Project Options dialog box, 28 for applications, 296 for Automation, 477 for forms, 277, 278, 280 for messages, 31, 31 for ModelMaker documentation, 445 for packages, 346, 346 Project toolbar in Rave, 718 Project Tree panel, 717 project-wide to-do items, 9 ProjectFile property, 719 projects, 26?28, 27 compiling and building, 30?32 exploring, 32, 32 names for, 407?408 options for, 28?30 prologues in XML, 835 PropCom example, 466 properties accessing by name, 115?117, 117 for ActiveX controls, 489?491, 490 categories in Object Inspector, 21?22 registering, 366?367, 367 code completion for, 14?15 collections for, 381?385, 383 in CTS, 909?910 in Delphi for .NET Preview, 925?926 editors installing, 391?392 for sound, 388?391, 390?391 writing, 388 encapsulation with, 50?52, 51 events as, 126?128 for forms, 53?54, 53 names for, 360 in Object Inspector, 20?21 Properties dialog box, 20 Property Editor dialog box, 438?439, 439 property keyword, 53 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks Property panel, 717 protected specifier, 48?50, 60?62, 925 protection, client/server programming for, 557 Protection example, 61?62 protocols for DataSnap, 650?651 in socket programming, 740 provider options in DataSnap, 666?667 ProviderFlags property, 658 ProviderName property, 655 proxy forms, 114 PtInRegion function, 365 public deployment, 916 public specifier, 48?50, 52 published keyword, 52, 114?115 Publisher example, 499?500 publishing subcomponents, 350?352, 352 WSDL, 881?883, 881 pull-down menus, 173 purely abstract classes, 69 Push method, 131 PWideChar type, 460 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Index Q QBIcons example, 257 QDynaForm example, 252 QLibComp example, 153?154, 156, 156 QLibSpeed example, 155 QMbParade example, 289 QMouseOne example, 262?263 QMultiWin example, 281?282 QRefList example, 192?193 QRefList2 example, 283 QRegion class, 366 QScale example, 275?276 QStdCtrls unit, 152 Qt library, 150 queries live, 594?597, 598 parametric, 663, 663 WebBroker technology for, 777?781, 780 Query component, 507 query forms, 613, 613 QueryFields property, 777?778 QueryInterface method for as casts, 465 in IUnknown, 457?458 QueryTableProducer component, 759, 777, 779 queues, 132, 302 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks Index R radio items on menus, 173 RadioButton component, 165?166 RadioGroup component, 166 RadioItem property, 173, 230 raise keyword, 71 raising exceptions, 71 RandomFrom function, 89 RandomRange function, 89 Range property, 270, 272?273 ranges, components for, 172?173 Rave, 715?716 calculations in, 733?734 components of, 722?723 basic, 723?725 data access, 725?726, 725 data-aware, 728?730, 729 regions and bands, 726?728, 727 data connections in, 721?722, 722 design environment in, 716?719, 716 master/detail reports in, 730?731, 731 mirroring in, 732?733 rendering formats for, 720?721, 720 RVProject component in, 719?720, 719 scripts for, 731?732, 732 RaveDatabase component, 726 RaveDetails example, 730?732, 731?732 RaveDirectDataView component, 726 RaveDriverDataView component, 726 RaveLookupSecurity component, 726 RaveProject component, 723 RaveSimpleSecurity component, 726 RaveSingle example, 721?722, 722 RC files, 37 RDSConnection component, 508, 619 re-raising exceptions, 71 read clauses, 50, 52, 465 Read method, 143 read-only ProgressBars, 671?673, 673 read-only properties in Object Inspector, 20 setting, 52 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. read-write TrackBar, 674?677, 677 ReadBool method, 332 ReadBuffer method, 137 ReadComponent method, 136 ReadComponentRes method, 140 ReadInteger method, 332 ReadString method, 332 Real48 type, 920 ReallocMem function, 921 rebuild.bat file, 900 Rebuild Wizard, 946 RecNo property, 537 Reconc unit, 588 Reconcile Error Dialog unit, 588, 588 ReconcileProducer property, 860 ReconcileProvider property, 863 record buffers, 698?703 record viewer component, 678?683, 682 RecordChanged method, 679 RecordCount property, 537, 560, 631?632 recording macros, shortcut keys for, 16 records in Delphi for .NET Preview, 920?921 editing, 520 locating, 514?515 locking, 587 in ADO, 635?636, 639?641 in client/server programming, 557 recursive, 86 status of, 585, 585 recordsets in ADO clone, 633 disconnected, 642?643 persistent, 644?645 recursive locks, 86 redefining methods, 64?65 refactoring ModelMaker code, 446?447 reference-counting techniques, 476 references, class, 76?78, 78 referential integrity, 559 ReflectionForm class, 935 Reflector tool, 901 RefList example, 189?193, 191 RefList2 example, 283?285, 284 Refresh in Model option, 438 Refresh method, 266, 660 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. refreshing data, 660?662, 661 screen, 266?267, 660 RefreshRecords method, 660?661 regasm (Framework Assembly Registration Utility), 501 region components, 726?728, 727 Register ActiveX Server command, 488 Register method for component editors, 395 for components, 342, 357 for packages, 345 for property categories, 366?367 for property editors, 391 RegisterActions method, 387 RegisterClass method, 330 RegisterColorSelect method, 421 registering ActiveX libraries, 34, 488 Automation servers, 473?474 component editors, 395 components, 342 conversion rates, 99?101 property categories, 366?367, 367 RegisterPooled method, 667 RegisterPropertyInCategory function, 366?367 Registry for automation servers, 473?474 cleaning up, 33 for COM servers, 464 for connection pooling, 644 for GUIDs, 458?459 for hot-track activation, 24 and INI files, 331?332 for shared component templates, 26 for sound properties, 389?390 status information in, 39 RegSvr32.exe program, 464 relational databases, 560 relations in database design, 557?558 master/detail. See master/detail relations relationships in diagrams, 435 Release method, 292, 820 _Release method, 71, 457 ReleaseCapture function, 265 Remote Data Module Wizard, 654, 654 RemoteServer component, 649 RemoteServer property, 655 Remove method in Delphi for .NET Preview, 926?927 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. for lists, 128 RemoveComponent method, 119 removing captions, 258 form fields, 121?122 renaming in ModelMaker code, 446 rendering formats for Rave, 720?721, 720 Repaint method, 266?267 RepaintRequest method, 363 reparenting classes, 446 Repeatable Read transaction isolation mode, 561, 590 replicable data-aware controls, 674 ReplyNormal property, 741 Report Library node, 717 reporting in dbExpress, 581?584 dynamic database, 776?777 in Rave. See Rave request methods in WebBroker, 778 Request object, 793 Request property, 771 Requires a New Transaction option, 495 Requires a Transaction option, 494 requires keyword, 346 requires lists, 345?346 RES files, 37 reserved characters in XML, 834 resize cursors, 255 ResizeStyle property, 181 resolution of monitors, 299 resolvers, 660 ResolveToDataSet property, 658, 660 Resource Explorer tool, 34 Resource Workshop tool, 34 resources and resource files binding into executables, 30 in COM+, 494 DLLs for, 399 Windows, 27?28 resourcestring keyword, 85 Response object, 793 Response property, 771 Restore method, 269 Result pages, HTML, 788 Resume method, 752 Resync method, 642 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks RethinkHotkeys method, 182 RethinkLines method, 182 return values in stored procedures, 565 reusability design patterns for, 448?449 object-oriented programming for, 64, 483 Revert to Inherited command, 319 RGB color, 160?161 RGB function, 160?161 RichBar example, 214?215, 214, 217?219, 218 RichEdit actions, 224 RichEdit component, 164?165 RichEditSelectionChange method, 214?215, 229 right mouse button, 261 robustness diagrams, 435 Roeder, Lutz, 901 role-based security, 494 Rollback action, 596 Rollback method, 589 RollbackRetaining command, 597 RollbackTrans method, 634 rolling back transactions, 589, 634?635 Rotor project, 905?906 Round function, 89?90 rounding in currency conversions, 101?102 numbers, 89?90, 90 Rounding example, 90, 90 RoundTo function, 89?90 Row property, 167 RowAttributes property, 763 RowCurrentColor property, 826?827 RowHeights property, 683 RowHeightsChanged method, 683 RowLayout property, 167 RowLimit property, 826 RPS files, 37 RTL (run-time library) package, 81, 83, 110?112, 110 converting data, 96?102, 98, 101 file management, 102?104, 103?104 TObject, 104?108, 106, 108 units of. See units RTTI (run-time type information) for casting, 67?69 for SOAP, 878 Run method, 296 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks run-only component packages, 338 Run Parameters dialog box, 42, 773 run time calling DLLs at, 408?410 loading packages at, 419?420 run-time library for Delphi for .NET Preview, 930?931 run-time library (RTL) package, 81, 83, 110?112, 110 converting data, 96?102, 98, 101 file management, 102?104, 103?104 TObject, 104?108, 106, 108 units of. See units run-time packages, 30?31, 338 run-time only properties, 52 run-time type information (RTTI) for casting, 67?69 for SOAP, 878 RunningTotal property, 730 RunProp example, 116?117, 117 RvCustomConnection component, 721 RvDataSetConnection component, 721 RvNDR Writer component, 720 RVProject component, 719?720, 719 RvQueryConnection component, 721 RvRenderHTML component, 721 RvRenderPDF component, 720 RvRenderPreview component, 720 RvRenderPrinter component, 720 RvRenderRTF component, 721 RvRenderText component, 721 RvSystem Writer component, 720 RvTableConnection component, 721 RWBlocks example, 601, 605?613, 607, 610 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register . it. Thanks Index S safe code, 908?909 safecall calling convention, 471, 664 SafeLoadLibrary function, 408 SameValue function, 89 sample1embedded.xml file, 865?866 SampProv driver, 617 Save Code Template dialog box, 451 Save method in MDI applications, 314 SaveDialog component, 288 SavePictureDialog component, 288 SavePoint property, 515 SaveStatusForm unit, 331, 333 SaveToFile method, 128, 510?511, 645 SaveToStream method in TBlobField, 139 in TStream, 137 saving application status information, 331?332 compiler options, 28?29 desktop settings, 5?6 DFM files, 19 docking status, 238 SAX (Simple API for XML), 850?853, 853, 872?873 SaxDemo1 example, 850?853, 853, 872 scalability and cursor location, 630 Scale example, 275?276 ScaleBy method, 275?276 Scaled property, 275?276 scaling forms, 274?277 schema information in ADO, 622?623, 623 in Jet, 628 in XML, 849?850 SCHEMA.INI file, 627 SchemaObject parameter, 578 SchemaPattern parameter, 578 SchemaTest example, 579, 579 SchemaType parameter, 578 ScktSrvr.exe application, 650 scope in Automation, 476?477 screen This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . refreshing, 266?267, 660 size of, 299 Screen example, 299?302, 300 Screen object, 299?302, 300 ScreenSnap property, 269 scripts for adapters, 797?798 for Rave, 731?732, 732 server-side, 791?793, 792 Scroll1 example, 271?272, 272 Scroll2 example, 273?274, 273 ScrollBar component, 172 ScrollBox component, 173 scrolling forms, 270?271 automatic, 272?273 coordinates in, 273?274, 273 example, 271?272, 272 messages for, 377 SDI (Single Document Interface), 310 sealed keyword, 924?925 search actions, 224 search application for HTTP, 751?754 search engines, 785?786, 786 search path setting, 347 search results, 9?10 search utility, 33 searches, case-insensitive, 602?603 searching window lists, 308?309 second-level message handlers, 369 secondary forms, 280 adding, 280 creating, 281?282 SecondaryShortCut property, 222 SecondOfWeek function, 91 Section component, 723?724 security client/server programming for, 557 in COM+, 494, 496 in Web pages, 493 SelAttributes property, 164 SelCount property, 167 SELECT statement, 628?629 SelectDirectory function, 103 Selected property, 167 SelectedColor property, 419 SelectedRows property, 542 selecting components This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks in Form Designer, 18 referenced by properties, 20 SelectNextPage method, 204 Self keyword, 46?47 self pointer, 70, 125 SelItem property, 379 semicolons (;) for connection strings, 620 in SELECT, 628 Sender object, 228 sending data database requests, 547?549, 548 to Excel tables, 479 mail, 748 over socket connections, 744?747, 747 to Word, 479 SendList program, 748, 749 SendMessage function, 304 SendResponse method, 784 SendStream method, 784 SendToDb example, 548?549, 548 separators for toolbars, 213 sequences diagrams for, 433?434, 433 in Oracle, 565 server constraints, 657?658 server-side cursors, 629, 636 server-side programming, 564?565 server-side scripts, 791?793, 792 server-side support components for DataSnap, 653 server socket connections, 740 ServerAddress property, 745 ServerGUID property, 655 ServerName property, 655 servers Automation, 470, 470 code for, 472?473 in components, 477?478, 477 registering, 473?474 type-library editor for, 470?472, 471 COM. See COM (Component Object Model) service providers, 618 Services file, 740 Session component, 793 SessionCount property, 246 sessions in Web applications, 821?823, 823 in WebSnap, 805?806, 807 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. SessionService component, 805?806 Set methods in TAXForm1, 491 set operations on lists, 128 Set_Value method, 473 SetAbort method, 497 SetBookmarkData method, 696?697 SetBookmarkFlag method, 696 SetBounds method in TControl, 159 in TMdArrow, 361 in TMdRecordView, 680 SetCapture function, 264 SetChangeFormFont method, 344 SetComplete method, 497 SetData method, 414, 702 SetDataField method in TMdDbProgress, 672?673 in TMdDbTrack, 676 SetDataSource method in TMdDbProgress, 672 in TMdDbTrack, 676 SetDirection method, 359?360 SetFieldData method in TMdDataSetOne, 702?703 in TMdDirDataset, 706 SetFirstName method, 353 SetForegroundWindow function, 307, 309 SetLabel method, 354 SetLines method, 379?380 SetLinesPerRow method, 684 SetMemoryManager function, 84, 334 SetMoreData method, 384 SetOleFont method, 478 SetOleStrings function, 478 SetOptionalParameter method, 668 SetPen method, 363 SetPropValue method, 419 SetRecNo method, 698 SetRoundMode function, 90 SetSchemaInfo method, 578?579, 579 SetShareData method, 414 SetSubComponent method, 351, 357?358 SetText method, 356 SetTextLineBreakStyle function, 85 setTimeout function, 823 Settings page, 836 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. SetValue method in TDate, 51 in TSoundProperty, 390 SetViewer method, 356 SetWindowLong function, 298, 317 SetWindowOrgEx function, 274 SetYear method, 51 SharedConnection component, 653 ShareMem unit, 95?96, 405?406, 409 sharing data with memory-mapped files, 413?414, 415 ShellExecute function, 212, 750 shift-state modifiers, 262 shortcut keys, 16 ShortCut property, 222 Show Compiler Progress option, 30 Show Component Captions setting, 19 Show method, 280, 286, 820 ShowApp example, 297?298 ShowColumnHeaders property, 191 ShowException method, 75?76 ShowForm method, 606 ShowFrame method, 329 ShowHints property, 183 ShowInfoProc function, 426?427 Showing property, 159 ShowMainForm property, 297 ShowMessage function, 289, 403 ShowMessageFmt method, 289 ShowMessagePos method, 289 ShowModal method, 280, 282, 285, 411 ShowSender method, 106 ShowStatus method, 751, 754 ShowStringForm method, 252 ShowTotal method, 305?306 Sign function, 89 signals in Qt, 162 Simple API for XML (SAX), 850?853, 853, 872?873 Simple Mail Transfer Protocol (SMTP), 740 Simple Object Access Protocol (SOAP), 876, 889?892 Simple Security Controller option, 726 SimpleDataSet component, 573?574, 576 SimpleMemTest unit, 335?336 SimpleObjectBroker component, 667 SimplePanel property, 217 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks SimpleRoundTo function, 90 SimpleText property, 217, 751 Single Document Interface (SDI), 310 single-instance secondary forms, 281?282 single instancing, 463 single page access rights, 808 single-threaded Apartment model, 463 Single threading model, 463 Single type, 478 size components, 19 controls, 159 executables, 82?83 fonts, 276?277 forms, 269 screen, 299 Size property, 136 sLineBreak constant, 85 SmallImages property, 189 SmallInt type, 478 Smith-Ferrier, Guy, 615 SMTP (Simple Mail Transfer Protocol), 740 SMTP component, 748 SN SDK, 916 Snap To Grid option, 18 SnapBuffer property, 269 snapping to screen, 269 SOAP (Simple Object Access Protocol), 651, 876, 889? 892 SOAP-based solutions, 651 SOAP headers, debugging, 887?888, 888 Soap Server Data Module, 889 SoapConnection component, 889 SoapDataClient example, 891 SoapDataServer example, 890 SoapEmployee example, 886?887, 887 SoapEmployeeIntf unit, 883 SOAPServerIID property, 891 socket programming, 737?739 connections in, 740 for database data, 744?747, 747 domain names in, 739 high-level protocols in, 740 Indy components in, 741?744, 744 IP addresses in, 739 ports in, 739?740 SocketConnection component, 652 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. sort by directive, 573 SortFieldNames property, 573 sorting in ListView, 191 SortType property, 191 Sound button, 371?372 sound properties editor, 388?392, 390?391 SoundDown property, 388 soundex algorithm, 91?92 SoundUp property, 388 source code files, 27?28, 38?39 Source Doc Generation page, 445 Source Doc Import page, 445 Source Options page, 10, 15 special characters in XML, 834 special keys, messages for, 376 speed in Automation, 476 in library selection, 155 Splash example, 290, 292 splash screens, 289?292, 290 Splash1 example, 290?291 Splash2 example, 291?292 Split1 example, 180, 180 Split2 example, 181 SplitH example, 181 SplitLong method, 786 Splitter component, 180 splitting forms, 180?181, 180 SQL Links drivers, 507 SQL Monitor tool, 33 SQLClientDataSet component, 574 SQLConnection component, 569?572, 571, 575, 589 SQLDataSet component, 573, 803 SqlMon.exe tool, 33 SQLMonitor component, 574, 576?577, 577 SQLOLEDB driver, 617 SQLTimeStampToStr function, 574 stacks, 131?132, 398 Standalone mode in IntraWeb, 815 Starkey, Jim, 561?562 startDocument event, 850, 852 startElement event, 850, 852, 872 StartID property, 830 StartTransaction method, 589?590 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. state diagrams, 434 state of windows, 268?269 State property in CheckBoxList, 169 in datasets, 524?525, 701 state-setter commands, 173 StateImages property, 189 static binding, 63 static cursors, 630?631 static linking, 397?398 static members, 925?926 static methods, 70 StaticListAction component, 248?249 StaticSynchronize method, 305 Statistics page, 773 status of ClientDataSet records, 585, 585 of datasets, 524?525 status bars, 217?219, 218, 718?719 StatusBar component, 217 StatusFilter property, 586 stdcall calling convention for DLLs, 399 for Web services, 880 stdcall directive, 402 StdConvs unit, 91, 96 StdCtrls unit, 152 StdVCL library, 478 Stop on Delphi Exceptions options, 74 store and paint approach, 266 stored directive, 344 stored procedures, 564?565 StoreDefs property, 511 StoredProc component, 507 StoredProcName property, 573 StoreRAV property, 719 Str function, 83 StrDemo example, 92 StreamDSDemo example, 703?704, 704 streaming, 135 classes for, 137?138 compressing, 145?146, 145 custom, 142?145 TReader and TWriter, 139?140 TStream, 135?137 vs. code generation, 113?114 files, 138?139 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks persistency in, 140?142, 141 string lists in Automation, 478 for combo boxes, 169 for CSS, 797 for memo lines, 164 for properties, 52 StringFromGuid2 function, 459 StringReplace method, 512 strings comparisons with, 91?92 conversions with, 86?87, 187?188 in Delphi for .NET Preview, 920?921 exporting from DLLs, 404?406 for lists, 128?129 memory for, 58 opaque, 538 unit for, 91?93 URL, 752 in XML, 837 StringToColor function, 188 StringToFloatSkipping method, 370?371 StringToGUID function, 459 StringValuesList component, 794 StripParamQuotes property, 760 strong name assemblies, 916 StrToBool function, 86 StrUtils unit, 91?93 stub routines, 70 style sheets, 764?765, 797, 859 StyleRule property, 797, 859 styles and Style property in Application, 219 for CLX, 219?220, 220 in ColorBox, 169 in ComboBox, 168 for forms, 254 borders, 254?256, 254 windows, 257?259, 258 in InetXPageProducer, 859 for list boxes, 187 in ModelMaker, 452 in TMdFontCombo, 343 in TToolButton, 213 Styles string list, 797 StylesDemo program, 219?220, 220 StylesFile property, 797, 859 subclassing, 317?318 subcomponents, publishing, 350?352, 352 SubMenuImages property, 174 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Support function, 87 SupportCallbacks property, 652 SupportedBrowsers property, 814 Supports function, 424 Supports transactions option, 495 surrogate keys, 559 symbols code completion for, 15 defining, 156 in diagrams, 435 synchronization classes, 86 Synchronize method in TFindWebThread, 751 in TThread, 305?306 SyncObjs unit, 148 Syntax Helper option, 488 syntax of XML, 834?835 SysConst unit, 85?86 SysInit unit, 84?85 system colors, 160 system data in IBX, 599?600, 599 system-level interfaces, 615 system tables, 578 System unit, 84?85 SysUtils unit, 85?88, 102?104, 103?104 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Index T tab actions, 224 TabbedNotebook component, 202 TabBmp object, 210 TabControl component, 202 for image viewer, 207?210, 207 for pages, 328?329, 329 table bookmarks, 538 Table component, 507 TableAttributes property, 763 TableName property in datasets, 573, 704 in TADOTable, 624 tables constraints on, 657?658 editing columns in, 539?540 events for, 658?659 in HTML, 762?764, 763 system, 578 totals of columns in, 537, 537 virtual method tables, 66, 70, 466 TabOrder property, 176 TAboutBox class, 290 tabs in editor, 11 Tabs menu, 24 TabSet component, 202 TabSheet components, 202?207, 204?205 TabStop property, 176 TabVisible property, 205, 210 TAction class, 222, 385 TActionBar collection, 244 TActionClient class, 244 TActiveXControl class, 458, 488 TActiveXControlFactory class, 460 TADTField class, 529 Tag property, 124 TAggregateField class, 529 TagParams list, 761 tags in XML, 833 TAlignment class, 230 TAnimal class, 62?64, 67 TApplication class, 295?296 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. TAppServerOne class, 654 TargetList function, 386?387 TArrayField class, 529 TAutoIncField class, 529 TAutoObject class, 458 TAutoObjectFactory class, 460 TAXForm1 class, 491?492 TBasicAction class, 222 TBCDField class, 529 TBinaryField class, 529 TBitBtn class, 184, 373 TBitmap class, 208 TBits class, 147 TBlobField class, 139, 529 TBlobStream class, 138 TBookmark class, 538 TBookmarkList class, 542 TBookmarkStr class, 542?543 TBooleanField class, 529 TBrush class, 358 TBucketList class, 132 TButton class, 152, 173 TBytesField class, 529 TCanTest class, 384 TCanvas class, 150, 262?263 TCGIApplication class, 771 TCharProperty class, 388 TCheckConstraint class, 657 TClass class, 77 TClassFinder class, 147 TClassList class, 131 TClipboard class, 208 TCollection class, 131, 147 TCollectionItem class, 131, 147, 382 TColor class, 160?161 TComObject class, 457?458, 464 TComObjectFactory class, 460, 462 TComponent class, 110?111, 110, 117, 340 in Delphi for .NET Preview, 931?932 form fields in hiding, 122?123 removing, 121?122 Name property in, 121 ownership in, 117?120, 120 Tag property in, 124 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. TComponentEditor class, 393 TComponentList class, 131 TCompressStream class, 145 TConnectionAdmin class, 579 TContainedAction class, 222 TControl class, 158 activation and visibility, 159 colors, 160?161 fonts, 159?160 Parent property, 158?159 size and position, 159 TCoolBand class, 231 TCoolBar component, 231 TCP/IP (Transmission Control Protocol/Internet Protocol), 652, 737?739 TCP/IP sockets, 651 TCP ports, 739?740 TcpClient class, 737?738 TcpServer class, 737?738 TCriticalSection class, 305 TCurrencyField class, 529 TCustomAction class, 222 TCustomActionToolBar class, 247?248 TCustomADODataSet, 618 TCustomConnection class, 569 TCustomControl class, 158, 487 TCustomDockForm class, 234 TCustomEdit class, 369 TCustomForm class, 251?252 TCustomGrid class, 679 TCustomLabel class, 350 TCustomMemoryStream class, 137 TCustomSQLDataSet class, 572 TCustomVariantType class, 94 TCustomWebDispatcher class, 771 TDataLink class, 669?670 TDataModule class, 147, 535, 653 TDataSaxHandler class, 872?873 TDataSet class, 520?524, 536, 552, 592, 687 TDataSetField class, 529 TDatasetProvider class, 658 TDate class, 51, 51 TDateField class, 529 TDateForm class, 56?58 TDateListI class, 134?135 TDateListW class, 134?135 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks TDateTime class, 49?50 in DateUtils unit, 91 in Delphi for .NET Preview, 921 in System unit, 84 TDateTimeField class, 529 TDBGHack class, 544 TDecompressStream class, 145 TDump.exe tool, 33 TeamSource tool, 33 Telnet ports, 740 temperature conversions, 96 templates code, 15, 450?452, 450 in Component Palette, 25?26, 26 HTML, 788 in Object Repository, 40?41 in UDDI, 895 TEncodedStream class, 142?143 TEnumProperty class, 388 TerminateAndRedirect method, 820 TestCom example, 464?465 testing COM server, 464?466 datasets, 703?704, 704 debugger for, 774 TestStreamFormat method, 140 TEvent class, 305 text for case diagrams, 434 DFM files stored as, 19 in Rave, 723 text-based data-aware controls, 516 Text component, 723 text files Jet engine for, 626?628 line breaks in, 85 Text IISAM, 626?627 text-input components Edit, 163 LabeledEdit, 163 MaskEdit, 163?164 MemoRich and RichEdit, 164?165 TextViewer, 165, 165 Text property in ComboBox, 168 in DOM, 844 in Edit, 162 in MemoRich, 164 for panels, 217 TextBrowser control, 756 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks TextHeight attribute, 187 TextViewer component, 165, 165 TField class, 525?527, 641?642 TFieldDataLink class, 670?671 TFileData class, 707 TFiler class, 139, 147 TFileRec class, 85 TFileStream class, 137 TFindWebThread class, 752?754 TFirstServer class, 473, 477 TFloatField class, 527, 529 TFMTBCDField class, 529 TForm class, 251?252, 333 for border icons, 256?257, 257 for form style, 254 borders, 254?256, 254 windows, 257?259, 258 for plain forms, 252?253, 253 TFormBitmap class, 331, 333?334 TFormBorderStyle class, 256 TFormClass class, 77 TFormScrollBar class, 270 TFormSimpleColor class, 422 TFrameClass class, 329?330 TFrameList class, 324?325 TGraphicControl class, 158, 340, 359, 487 TGraphicField class, 530 TGUID class, 458?459 TGuidField class, 530 THandleStream class, 137 THashedStringList class, 133 themes, 220?221, 222 thick frame border style, 255 thin clients, 649 ThinCli1 example, 656 ThinCli2 example, 659, 659 ThinPlus example, 662?665, 663, 665 THintInfo structure, 183 THome class, 788?789 thousands separators, 370?371, 533 ThousandSeparator character, 533 threading methods in COM, 463 threads, 84, 304?307 threadvar variables, 822 three-tier architecture, 648 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. tiDirtyRead value, 590 TIDispatchField class, 530 TidThreadSafeInteger class, 822 Tile method, 312 TileMode property, 312 time native formats for, 709 unit for, 91 Timer class, 350?351 Timer property, 351 timers for messages, 302 in Web applications, 823 XClock, 492?493, 493 TimeStamp field, 574 timing, 476 TInformSubscriber class, 498?499 TIniFile class, 331?332 TIntegerField class, 530 TIntegerProperty class, 388 TInterfacedField class, 530 TInterfacedObject class, 70, 84, 457 TInterfacedPersistent class, 147 TInterfaceList class, 147 TInvokableClass class, 880 tiReadCommitted value, 590 tiRepeatableRead value, 590 TISAPIRequest class, 771 TISAPIResponse class, 771 TItemProp class, 171 Title property, 379 titles for applications, 297 TIWServerController class, 822 TJpegImage class, 783 TLargeIntField class, 530 TLB (type library) file, 37, 470 TLibCli example, 474?475 TlibdemoLib_TLB file, 477 tlibimp utility, 501 TList class, 128?131, 130, 133 TListControlAction class, 385 TListItems class, 189 TMdActiveButton class, 372?373 TMdArrow class, 359?360, 363?365 TMdClock class, 350?351 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. TMdCustomDataSet class, 687?689 TMdCustomListAction class, 385?386 TMdDataSetStream class, 689?690 TMdDbGrid class, 684 TMdDbProgress class, 671?672 TMdDbTrack class, 675 TMdDirDataset class, 706 TMdFontCombo class, 341?344 TMdListBoxDialog class, 379 TMdListCompEditor class, 393?395 TMdListCopyAction class, 386 TMdListCutAction class, 386 TMdListDataSet class, 705 TMdListPasteAction class, 386 TMdMyColleciton class, 382?383 TMdMyItem class, 382 TMdNumEdit class, 369 TMdObjDataSet class, 710 TMdPersonalData class, 352?354 TMdRecInfo class, 695?696 TMdRecordLink class, 678 TMdRecordView class, 679 TMdSoundButton class, 371?372, 392 TMdThousandEdit class, 370?371 TMdViewer class, 355?356 TMdWArrowX class, 488 TMemoField class, 530 TMemoryManager class, 84, 334?335 TMemoryStream class, 137?138 TMethod class, 115, 125 TMultiReadExclusiveWriteSynchronizer class, 86 TMySaxHandler class, 851?852 TMySimpleSaxHandler class, 852 TNewDate class, 59?60 TNotifyEvent type, 364 TNumber class, 462, 464 TNumericField class, 530 to-do lists, 7?9, 8 TObject class, 54, 84, 104?108, 106, 108 TObjectBucketList class, 132 TObjectField class, 530 TObjectHelper class, 930 TObjectList class, 131?133 TObjectQueue class, 132 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. TObjectStack class, 131?132 TODO comments, 7?9 TODO files, 37 TOleStream class, 138 toolbars and ToolBar control, 213, 230?231 actions with, 224, 229?230 captions for, 236 ControlBar, 231?234, 232 CoolBar, 230?231 docking in, 235?239, 236 hints in, 182?184, 184, 218, 218, 236 menus and combo boxes in, 216?217 in Rave, 718 RichBar example, 214?215, 214 Tools API, 388 Tooltip symbol insight feature, 12?13 tooltips, 182?184, 184 expression evaluation, 16 hints, 19 Top property for components, 18 for forms, 268 in TControl, 159 Total example, 537, 537 totals of columns, 537, 537 in Rave, 729?730 TOwnedCollection class, 147 TParser class, 147 TPen class, 358 TPersistent class, 110, 112?113 for Arrow component, 362?364, 364 property access in, 115?117, 117 published keyword for, 114?115 TPoint structure, 93 TPromptQueryButton class, 859 TPropertyEditor class, 388 TPropertyPage class, 490 TPropertyPage1 class, 490 TQueue class, 132 TrackBar component, 172, 674?677, 677 tracking forms, 299?302, 300 TrackMode property, 815 training classes, 608?611, 610 transactional data modules, 497 TransactionLevel property, 591 transactions actions for, 596 in ADO, 634?636 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. in client/server programming, 589?591, 591 in COM+, 494 InterBase for, 561 TransactionsSupported property, 590 TranSample example, 591, 591 transformations XML, 854?857, 854, 856?857, 886?887, 887 XSL, 868?869 TransformNode method, 866, 868 TransformProvider component, 855, 856 translations, BabelFish, 876?879, 877, 879 Transmission Control Protocol/Internet Protocol (TCP/ IP), 652, 737?739 transparent color in forms, 267, 267 TransparentColor property, 267 TransparentColorValue property, 267 TReader class, 139?140, 147 TRecall class, 147 TReconcileAction class, 588 TReconcileErrorForm dialog box, 641 TRect structure, 93 trees in XML, 835 TreeView, 22?23 TreeView component, 169?170, 193?197, 194 custom nodes in, 197?198, 199 for XML documents, 839?841, 840 TreeView Items property editor, 193 TReferenceField class, 530 TRegIniFile class, 332 TRegistry class, 332 TRegSvr.exe example, 464 TRegSvr.exe tool, 34 TRemoteDataModule class, 654 TResourceStream class, 137 triangle symbol in Band Style Editor, 728 triggered events, 124 triggers in Interbase 6, 565?566 trigonometric functions, 89 Trunc function, 921 try blocks, 71?73 TryEncodeDate function, 87 TryEncodeTime function, 87 TryFinally example, 72?73 TryStrToCurr function, 87 TryStrToDate function, 87 TryStrToFloat function, 87 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. TSaveStatusForm class, 331, 334 TSchemaInfo class, 622 TScreen class, 299 TScrollingWidget class, 252 TScrollingWinControl class, 252 TSetProperty class, 388 TSingleEvent class, 305 TSmallIntField class, 530 TSmallPoint class, 93 TSOAPAttachment class, 893 TSoapDataModule class, 890 TSoapTestDm class, 890 TSoundProperty class, 389 TSQLConnection class, 569 TSQLDataSet component, 572, 578 TSQLTimeStampField class, 530, 574 TStack class, 131?132 TStream class, 135?137 TStringField class, 530 TStringHash class, 133 TStringList class, 128?129, 148 TStringProperty class, 388 TStrings class, 128?129 TStringStream class, 137 TTags class, 761 TTextRec class, 85 TThread class, 147, 305 TThreadList class, 147 TTimeField class, 530 TToolButton class, 173, 213 TTransactionDesc type, 590 TTreeItems class, 197 TTreeNode class, 195 TTypedComObject class, 458 TTypedComObjectFactory class, 460 tuples, 560 Turbo Grep tool, 33 Turbo Register Server tool, 34 TUserSession class, 821?822, 825?826 TVarBytesField class, 530 TVarData record class, 84 TVariantField class, 530 TVariantManager class, 84 TViewerForm class, 322?323 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks TWebAppPageModule class, 787 TWebAppPageModuleFactory class, 807 TWebBrowser class, 485 TWebContext class, 806 TWebPageModuleFactory class, 807 TWebRequest class, 771, 775 TWebResponse class, 771 TWideStringField class, 530 TWidgetControl class, 158, 161?162, 251 TWinControl class, 158, 161, 251, 340 TWindowArrange class, 312 TWindowCascade class, 312 TWindowClose class, 312 TWindowMinimizeAll class, 312 TWindowTileHorizontal class, 312 TWindowTileVertical class, 312 TWinSocketStream class, 138 TWordField class, 530 TWriter class, 139?140, 147 TXActAttributes class, 635 type libraries in Automation, 468?470 editors for, 470?472, 471 type library (TLB) file, 37, 470 Type Library Importer, 501 Type Library page, 471 type-safe containers and lists, 133?135 type-safe down-casting, 67?69 typed parameters, 565 TypeInfo unit, 116?117 types checking, 458 COM, 478 in Delphi for .NET Preview, 920, 926 in inheritance, 62?63 Types unit, 93 TypesList method, 882 TypInfo unit, 148 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Index U UDDI (Universal Description, Discovery, and Integration) specification, 894?898, 896 UDDIBrow.ini file, 895 UddiInquiry example, 895?898, 896 UDL files, 37 UML diagrams, 429?430 class, 431?432, 432?433 common elements in, 435?436, 436 sequence, 433?434, 433 use case, 434 UndoLastChange method, 514 Unicode character sets, 835 unidirectional cursors, 560?561, 566?567 UniPrint example, 582?584 Unit Code Editor, 439?441 unit dependency diagrams, 435 units code editors for, 439?441 in dbExpress, 568?569 in inheritance, 60?61 names for, 44 namespaces for, 922?924 in Project Explorer, 32 in RTL, 81?82 COM-related, 96 ConvUtils and StdConvs, 91 DateUtils, 91 DelphiMM and ShareMem, 95?96 Math, 88?90, 90 StrUtils, 91?93 SysConst, 85?88 System and SysInit, 84?85 SysUtils, 85?88, 102?104, 103?104 Types, 93 Variants and VarUtils, 94?95, 94 in VCL and CLX, 157 Universal Description, Discovery, and Integration (UDDI) specification, 894?898, 896 UnloadPackage function, 419?420 unmanaged code, 905 unsafe casts, 44 unsafe code, 44, 909 unsafe types, 44, 920 Update Criteria property, 640 Update method This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. in painting, 266 in TMdMyColleciton, 383 update regions, 267 UpdateBatch method, 638 UpdateClock method, 352 UpdateData method, 677 UpdateLabel method, 353 UpdateList method, 135 UpdateMode property, 640 UpdateOleObject method, 490 UpdateRegistry method in DataSnap, 667 in TRemoteDataModule, 654 updates in ADO, 615 batch, 638?642 conflicts in, 641?642 joins, 636?637 in ClientDataSet, 584?589, 585?586, 588 in DataSnap example, 659?662 in dbExpress, 576?578 DLLs, 416 triggers fired by, 565 UpdatesPending property, 638 UpdateStatus method, 585, 638 UpdateTarget method in TAction, 385 in TMdCustomListAction, 385?386 UpDown component, 172 uppercase names, converting to, 602?603 upsizing applications, 556 URL strings, 752 URLs in IntraWeb, 814?815 in WinInet, 755 UsageCount property, 246 use cases, diagrams for, 434 UseCol example, 411 UseDockManager property, 235, 240 UseFrame property, 826 UseMem example, 413?414, 415 user-defined window messages, 309?310 user interface ActionList component for, 222?224, 223 example, 225?228, 226, 228 predefined actions in, 224?225 with toolbars, 229?230 ActionManager architecture, 241?250, 243?245, 249 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. CLX styles, 219?220, 220 docking support, 234?241, 236 in InterBase, 605?608, 607 multiple-page forms. See multiple-page forms themes, 220?221, 222 toolbars, 213?219, 230?234, 232 for wizard, 210?213, 211 user logins, 807?808 user-related adapters, 794 uses statement for controls, 154 in Delphi for .NET Preview, 923?924 for external symbols, 15 in implementation section, 256 UseSOAPAdapter property, 891 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks Index V validation in XML, 849?850 Value property, 525 ValueChecked property, 517 ValueFromIndex property, 129 ValueListEditor component, 170?172, 170 ValueUnchecked property, 517 VarArrayCreate function, 514 VarArrayOf function, 514 VarComplexCreate functions, 95 varEmpty type, 477 variables code completion for, 14?15 pointers to, 55, 55 variant records, 921 Variant type, 468, 478 custom, 94?95, 94 System unit support for, 84 Variants unit, 94?95, 94 varNull type, 477 VarSQLTimeStampCreate function, 574 VarUtils unit, 94?95, 94 VBX standard, 483 VCL (Visual Components Library), 110?112, 110 VCL controls converting, 156?158 for Delphi for .NET Preview, 931?933, 933 dual libraries support for, 151?155, 152 visual libraries for, 155?156, 156 vs. VisualCLX, 149?158, 152 VCL.DCP file, 408 VCL Hierarchy Wizard, 946?947 VCL package, 83 VCL70.BPL file, 408 VclToClx tool, 158, 947?948 verbs in compound documents, 480 in IComponentEditor, 393 version tags in DCU files, 416 versions dbExpress, 568?569 DLL, 399 in InterBase, 561 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. in .NET architecture, 916?917, 917 in packages, 416?417 TeamSource control system, 33 VertScrollBar property, 270 ViewAccess property, 808 ViewGrid example, 682, 682 views, loadable, 16?18, 17?18 virtual action items, 250 virtual destructors, 55 virtual fields, 50 virtual functions, 64?65 virtual keys, 262 virtual keyword, 64?65 virtual method tables (VMTs), 66, 70, 466 virtual methods, 398 in COM server, 466?467 vs. dynamic, 65?66 in interfaces, 70 VirtualListAction component, 248?249 VirtualListAction1GetItem method, 250 visibility and Visible property for actions, 222 for controls, 159 in Delphi for .NET Preview, 925 for fields, 658 for inherited forms, 321 for scroll bars, 270 for secondary forms, 280 in TControl, 159 in TField, 528 VisibleButtons property, 516 VisibleRowCount property, 685 Visitor pattern, 449 Visual Basic controls, 483 Visual Components Library (VCL), 110?112, 110 visual editing, 484 visual form inheritance, 318?319 from base forms, 319?321, 319?320 polymorphic, 321?324, 322 visual libraries, 155?156, 156 visual styles in ModelMaker, 452 VisualCLX controls, 110?111 converting, 156?158 dual libraries support for, 151?155, 152 vs. VCL, 149?158, 152 visual libraries for, 155?156, 156 VMTs (virtual method tables), 66, 70, 466 Voice method, 63?64 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. vtables, 66, 70, 466 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Index W W3C (World Wide Web Consortium) for HTML, 759 for XML, 833 WaitForSingleObject function, 308 $WARN directive, 44 warnings, compiler, 31?32, 44 Watch List, 42 Web and Web pages. See also Internet programming actions for, 224 ActiveX controls in, 492?493, 493 hit counter for, 782?785 search engines for, 785?786, 786 services for, 875?876 attachments, 892?893, 894 BabelFish translations, 876?879, 877, 879 currency conversion, 880?882, 881, 883 database data, 883?887, 887 debugging SOAP headers, 887?888, 888 existing classes as, 888?889 SOAP and WSDL, 876 UDDI, 894?898, 896 WebSnap for. See WebSnap application Web App Debugger tool, 33, 772?774, 774, 887?889, 888 Web Services Description Language (WSDL), 876, 881?883, 881 Web Services page, 889 WebAppComponents component, 787 WebAppDbg.exe tool, 33, 772?774, 774 WebApplication class, 817 WebBroker technology, 770?772 with Apache, 781?872 debugging in, 772?774, 774 for dynamic database reporting, 776?777, 777 with IntraWeb, 823?824 for multipurpose WebModule, 774?776 for queries and forms, 777?781, 780 Web hit counter, 782?785 Web searches, 785?786, 786 WebBrowser control, 485?486, 486 WebConnection component, 652 WebContext object, 806 WebDemo example, 485?486, 486 WebDispatch property, 858 WebDispatcher component, 771?772 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks WebFind example, 751?754, 755 WebModules, 770?772 WebRequestHandler object, 773 WebSearcher example, 785?786, 786 WebSnap application, 786?789, 787 for adapters, 794?798, 796 for databases, 798 data editing, 801?803, 802 data module for, 798?799 DataSetAdapter for, 799?801, 800 master/detail in, 803?805, 805 with IntraWeb, 823?824 logins in, 807?808 for multiple pages, 789?791, 790 permissions in, 808 for server-side scripts, 791?793, 792 sessions in, 805?806, 807 XSLT with, 866?868, 866 WebSnap page, 787 well-formed XML, 835 What's this? Help, 256 wheel events, 261 White Pages in UDDI, 894 white space in XML, 834 wide string support, 87 WideCompareStr function, 87 WideCompareText function, 87 WideFormat function, 87 WideLowerCase function, 87 WideSameStr function, 87 WideSameText function, 87 WideString type, 87, 459?460, 478 WideUpperCase function, 87 Width property for components, 18 for forms, 268?269 in Splitter, 180 in TControl, 159 in TMdArrow, 359 WINAPI modifier, 401 window lists, searching, 308?309 window procedures, 161 WindowMenu property, 311 WindowProc property, 161 windows, 161 controls in, 158, 368 message handlers in, 368?373, 373 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. messages in, 373?378 notifications in, 376?377 overriding message handlers in, 371?372 for forms, 257?259, 258 painting in, 265?267 Windows Interactive SQL (WISQL), 562 Windows menu, 7 Windows operating system background processing and multitasking in, 304 common dialogs, 287?288, 288 events in, 302?303 messages in, 303?304, 309?310, 374 resource files from, 28 themes in, 220?221, 222 WindowState property, 268?269 WindowsXP.res file, 220 WinInet API, 754?756 WinShoes component, 739 WinSight tool, 33, 303 WinVersion example, 85?86 WISQL (Windows Interactive SQL), 562 WithinPastDays function, 91 wizards DLL, 41 user interface for, 210?213, 211 WizardUI example, 210?213, 211 wm_Char message, 368 wm_Command message, 376 wm_EraseBkgnd message, 317 wm_HScroll message, 272 wm_LButtonDblClk message, 365 wm_LButtonDown message, 371 wm_LButtonUp message, 371 wm_NCCalcSize message, 269 wm_NCHitTest message, 258, 269 wm_NCLButtonDown message, 269 wm_NCPaint message, 269 wm_Size message, 270 wm_User message, 66, 301 WMHScroll method, 272 WNDCLASS, 307 WndProc method, 161, 317 Word with Automation, 479 DLLs for, 411 WordBool type, 478 WORDCALL.TXT file, 411 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. WordCont example, 482?483, 483 World Wide Web. See Internet programming; IntraWeb library; Web and Web pages World Wide Web Consortium (W3C) for HTML, 759 for XML, 833 Wrapper pattern, 449 wrapper properties, 350 wrappers for ActiveX controls, 485 for XML, 838 write clauses, 50, 52, 465 Write method, 143 write-only properties, 52 WriteBool method, 332 WriteBuffer method, 137 WriteComponent method, 136, 140, 142 WriteComponentRes method, 140 WriteInteger method, 332 WriteString method, 332 ws constants, 269 Ws.exe tool, 33, 303 WSDL (Web Services Description Language), 876, 881?883, 881 WSDLHTMLPublish component, 880 WSnap1 example, 791?793 WSnap2 example, 792?793, 792, 795?796, 796 WSnapMD example, 803?805, 805 WSnapTable example, 798?803, 800, 802 WWW (World Wide Web). See Internet programming; IntraWeb library; Web and Web pages This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Index X Xalan processor, 865 XArrow example, 489 XClock control, 492?493, 493 Xerces DOM, 838 XFM files, 152?154 XForm1 example, 492 XLSReadWrite component, 625 XML, 833?834 core syntax of, 834?835 data binding interfaces in, 846?850, 847 for DataSnap, 653 document management in, 838?846, 840, 843, 846 file format for, 644?646 and Internet Express, 858?864, 861, 863 large documents with, 869?873, 871 mapping with transformations, 854?857, 854, 856? 857, 886?887, 887 passing documents in, 884?886 SAX API for, 850?853, 853 well-formed, 835 working with, 836?837, 837 and XSLT, 864?869, 866 XML-based formats in ClientDataSet, 511, 512 XML Data Binding Wizard, 846?849, 847 XML Mapper tool, 33, 854?857, 854, 856?857, 886?887, 887 XML Schema Validator (XSV), 850 XMLBroker component, 858 XMLData property, 511, 866 Xmldb.js file, 859 XmlDemo example, 927 Xmldisp.js file, 859 XMLDocument component, 836, 838, 842, 848 xmlDom component, 868 Xmldom.js file, 859 XmlDomTree example, 839?841, 840 XmlEditOne example, 836?837, 837 Xmlerrdisp.js file, 859 XmlInterface example, 848 XMLIntf unit, 839 XmlIntfDefinition unit, 848 XmlMapper.exe tool, 33 XMLMapping example, 855?857, 856 This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks XmlShow.js file, 859 XMLTransform component, 855, 857 XMLTransformClient component, 855 XMLTransformProvider component, 855 XPath technology, 864?865 XpManifest component, 221 XSL transformations, 868?869 XslCust example, 866?868, 866 XslDom component, 868 XslEmbed project, 865 XSLPageProducer component, 866 XSLT (Extensible Stylesheet Language), 864 examples, 865?866 with WebSnap, 866?868, 866 XPath in, 864?865 XSV (XML Schema Validator), 850 Xt processor, 865 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks Index Y Yellow Pages in UDDI, 895 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks Index Z z-order, 312 ZCompress example, 145?146, 145 zero-configuration thin-client architecture, 649 ZLib utility, 145?146, 145 Zoom toolbar in Rave, 718 . This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . List of Figures Chapter 1: Delphi 7 and Its IDE Figure 1.1: A form and a data module in the Delphi 7 IDE Figure 1.2: The Preferences page of the Environment Options dialog box Figure 1.3: The Edit To-Do Item window can be used to modify a to-do item, an operation you can also do directly in the source code. Figure 1.4: The multiple languages supported by the Delphi IDE can be associated with various file extensions in the Source Options page of the Editor Properties dialog box. Figure 1.5: You can configure the Code Explorer in the Environment Options dialog box. Figure 1.6: The Diagram view shows relationships among components (and even allows you to set them up). Figure 1.7: The Print Options for the Diagram view Figure 1.8: The Frames1 example demon-strates the use of frames. The frame (on the left) and its instance inside a form (on the right) are kept in synch. Figure 1.9: Delphi's multitarget Project Manager Figure 1.10: The new Compiler Messages page of the Project Options dialog box Figure 1.11: The Project Browser Figure 1.12: The first page of the New Items dialog box, generally known as the Object Repository Chapter 2: The Delphi Programming Language Figure 2.1: The output of the CreateComps example, which creates Button components at run time Figure 2.2: The DateProp example's form Figure 2.3: Two forms of the FormProp example at run time Figure 2.4: A representation of the structure of an object in memory, with a variable referring to it Figure 2.5: A representation of the operation of assigning an object reference to another object. This is different from copying the actual content of an object to another. Figure 2.6: The output of the NewDate program, with the name of the month and of the day depending on Windows regional settings Figure 2.7: The output of the PolyAnimals example Figure 2.8: The ErrorLog example and the log it produces Figure 2.9: An example of the output of the ClassRef example Chapter 3: The Run-Time Library Figure 3.1: The Rounding example, demon-strated banker's rounding and arithmetic rounding Figure 3.2: The form of the VariantComp example at design time This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Figure 3.3: The ConvDemo example at run time Figure 3.4: The output of the EuroConv unit, showing the use of Delphi's conversion engine with a custom measurement unit Figure 3.5: An example of the output of the FilesList application Figure 3.6: The dialog box of the SelectDirectory procedure, displayed by the FilesList application Figure 3.7: The output of the IfSender example Figure 3.8: The output of the ClassInfo example Chapter 4: Core Library Classes Figure 4.1: A graphical representation of the main groups of VCL components Figure 4.2: The output of the RunProp example, which accesses properties by name at run time Figure 4.3: In the ChangeOwner example, clicking the Change button moves the Button1 component to the second form. Figure 4.4: The list of dates shown by the ListDemo example Figure 4.5: The textual description of a form component, displayed inside itself by the FormToText example Figure 4.6: The ZCompress example can compress a file using the ZLib library. Chapter 5: Visual Controls Figure 5.1: A comparison of the first three pages of the Component Palette for a CXL-based application (above) and a VCL-based application (below) Figure 5.2: An application written with CLX can be directly recompiled under Linux with Kylix (displayed in the background). Figure 5.3: The HtmlEdit example at run time: When you add new HTML text to the memo, you get an immediate preview. Figure 5.4: The NameValues example uses the ValueListEditor component, which shows the name/value or key/ value pairs of a string list, also visible in a plain memo. Figure 5.5: Delphi's Menu Designer in action Figure 5.6: The Edit Tab Order dialog box Figure 5.7: The InFocus example at run time Figure 5.8: The controls of the Anchors example move and stretch automatically as the user changes the size of the form. No code is needed to move the controls, only proper use of the Anchors property. Figure 5.9: The Split1 example's splitter component determines the minimum size for each control on the form, even those not adjacent to the splitter. Figure 5.10: The ListBox control of the CustHint example shows a different hint, depending on which list item the mouse is over. Figure 5.11: The owner-draw menu of the ODMenu example Figure 5.12: Different examples of the output of a ListView compo-nent in the RefList program, obtained by changing the ViewStyle property and adding the check boxes This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Figure 5.13: The DragTree example after loading the data and expanding the branches Figure 5.14: The CustomNodes example has a tree view with node objects based on different custom classes, thanks to the OnCreateNodes-Class event. Chapter 6: Building the User Interface Figure 6.1: The first sheet of the PageControl of the Pages example, with its shortcut menu Figure 6.2: The second page of the example can be used to size and position the tabs. Here you can see the tabs on the left of the page control. Figure 6.3: The interface of the bitmap viewer in the BmpViewer example. Notice the owner-draw tabs. Figure 6.4: The first page of the WizardUI example at design time Figure 6.5: The RichBar example's toolbar. Notice the drop-down menu. Figure 6.6: The StatusBar of the RichBar example displays a more detailed description than the fly-by hint. Figure 6.7: The StylesDemo program, a Win-dows application that currently has an unusual Motif layout Figure 6.8: The Pages example uses the current Windows XP theme, as it includes a manifest file (compare the figure with 6.1) Figure 6.9: The ActionList component editor, with a list of predefined actions you can use Figure 6.10: The ActionList editor of the Actions example Figure 6.11: The Actions example, with a detailed description of the Sender of an Action object's OnExecute event Figure 6.12: The MdEdit2 example at run time, while a user is rearranging the toolbars in the control bar Figure 6.13: The MdEdit2 example allows you to dock the toolbars (but not the menu) at the top or bottom of the form or to leave them floating. Figure 6.14: The DockTest example with three controls docked in the main form Figure 6.15: The main form of the DockPage example after a form has been docked to the page control on the left. Figure 6.16: The three pages of the ActionManager editor dialog box Figure 6.17: Using the CustomizeDlg component, you can let a user customize the toolbars and the menu of an appli-cation by dragging items from the dialog box or moving them around in the action bars. Figure 6.18: The ActionManager disables least-recently used menu items that you can still see by selecting the menu extension command. Figure 6.19: The ListActions application has a toolbar hosting a static list and a virtual list. Chapter 7: Working with Forms Figure 7.1: The dynamic form generated by the DynaForm example is completely created at run time, with no design-time support. Figure 7.2: Sample forms with the various border styles, created by the Borders example Figure 7.3: The BIcons example. By selecting the Help border icon and clicking the button, you get the help displayed in the figure. Figure 7.4: The NoTitle example has no real caption but a fake one made with a label. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Figure 7.5: The KPreview program at design time Figure 7.6: During a dragging operation, the MouseOne example uses a dotted line to indicate the final area of a rectangle. Figure 7.7: The output of the ColorKeyHole, showing the effect of the new TransparentColor and AlphaBlend properties and the Animate-Window API Figure 7.8: The output of the Scroll1 example Figure 7.9: The lines to draw on the virtual surface of the form Figure 7.10: The Forms page of the Delphi Project Options dialog box Figure 7.11: The dialog box of the RefList2 example used in edit mode. Notice the ComboBoxEx graphical component in use. Figure 7.12: The three forms (a main form and two dialog boxes) of the DlgApply example at run time Figure 7.13: The Font selection dialog box with an Apply button Figure 7.14: The main form of the Splash example, with the splash screen (this is the Splash2 version) Chapter 8: The Architecture of Delphi Applications Figure 8.1: The ActivApp example shows whether the application is active and which of the application's forms is active. Figure 8.2: The output of the Screen example with some secondary forms Figure 8.3: The MdiDemo program uses a series of predefined Delphi actions connected to a menu and a toolbar. Figure 8.4: The output of the MdiMulti example, with a child window that displays circles Figure 8.5: The menu bar of the MdiMulti application changes automatically to reflect the currently selected child window, as you can see by comparing the menu bar with that of Figure 8.4. Figure 8.6: The New Items dialog box allows you to create an inherited form. Figure 8.7: The two forms of the VFI example at run time Figure 8.8: The base-class form and the two inherited forms of the PoliForm example at design time Figure 8.9: A frame and two instances of it at design time, in the Frames2 example Figure 8.10: Each page of the FramePag example contains a frame, thus separating the code of this complex form into more manageable chunks. Figure 8.11: The first page of the FrameTab example at run time. The frame inside the tab is created at run time. Chapter 9: Writing Delphi Components Figure 9.1: The Package Editor Figure 9.2: The Project Options for packages Figure 9.3: The Contains section of the Package Editor shows both the units that are included in the package and the component resource files. Figure 9.4: The Object Inspector can automatically expand sub-components, showing their properties, as in the case of the Timer property of the TMdClock component. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks Figure 9.5: A component referencing an external label at design time Figure 9.6: The output of the Arrow component Figure 9.7: The output of the Arrow component with a thick pen and a special hatch brush Figure 9.8: The Arrow component defines a custom property category, Arrow, as you can see in the Object Inspector. Notice that properties can be visible in multiple section, such as the Filled property in this case. Figure 9.9: An example of the use of the ActiveButton component Figure 9.10: The ListDialDemo example shows the dialog box encapsulated in the ListDial component. Figure 9.11: The collection editor, with the Object TreeView and the Object Inspector for the collection item Figure 9.12: The list of sounds provides a hint for the user, who can also type in the property value or double-click to activate the editor (shown later, in Figure 9.13). Figure 9.13: The Sound Property Editor's form displays a list of available sounds and lets you load a file and hear the selected sound. Figure 9.14: The custom menu items added by the component editor of the ListDialog component Chapter 10: Libraries and Packages Figure 10.1: The output of the CallCpp example when you have clicked each of the buttons Figure 10.2: The output of the CallFrst example, which calls the DLL you've built in Delphi Figure 10.3: The Application page of the Project Options dialog box now has a Library Name section. Figure 10.4: If you run two copies of the UseMem program, you'll see that the global data in its DLL is not shared. Figure 10.5: The structure of the package hosting a form in Delphi's Package Editor Figure 10.6: The output of the PackInfo example, with details of the packages it uses Chapter 11: Modeling and OOP Programming (with ModelMaker) Figure 11.1: A class diagram in ModelMaker Figure 11.2: A class diagram with interfaces, classes, and interface delegation Figure 11.3: ModelMaker's Interface Wizard Figure 11.4: A sequence diagram for an event handler of the NewDate example Figure 11.5: The organizational possibilities of the Diagrams view Figure 11.6: The Property Editor dialog Figure 11.7: ModelMaker with the Implementation tab active Figure 11.8: ModelMaker's Difference view Figure 11.9: The Documentation tab of a Class Symbol Figure 11.10: ModelMaker's Code Template Parameters dialog box Chapter 12: From COM to COM+ This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Figure 12.1: An example of the GUIDs generated by the NewGuid example. Values depend on my computer and the time I run this program. Figure 12.2: The COM Object Wizard Figure 12.3: The Word document is being created and composed by the WordTest Delphi application. Figure 12.4: The type-library editor, showing the details of an interface Figure 12.5: Delphi's Type Library Import dialog box. Figure 12.6: The second toolbar of the OleCont example (above) is replaced by the server's toolbar (below). Figure 12.7: The WordCont example shows how to use Automation with an embedded object. Figure 12.8: The WebDemo program after choosing a page that's well known by Delphi developers Figure 12.9: The XArrow ActiveX control and its property page, hosted by the Delphi environment Figure 12.10: The XClock control in the sample HTML page Figure 12.11: The New Trans-actional Object dialog box, used to create a COM+ object Figure 12.12: The newly installed COM+ component in a custom COM+ application (as shown by Microsoft's Com-ponent Services tool) Figure 12.13: A COM+ event with two subscriptions in the Component Services management console Figure 12.14: The NetImport program uses a .NET object to sum numbers. Chapter 13: Delphi's Database Architecture Figure 13.1: A sample local table active at design time in the Delphi IDE Figure 13.2: The XML display of a CDS file in the MyBase2 example. The table structure is defined by the program, which creates a file for the dataset on its first execution. Figure 13.3: The data-aware controls of the DbAware example at design time in Delphi Figure 13.4: The output of the CustLookup example, with the DBLookupCombo-Box showing multiple fields in its drop-down list Figure 13.5: The Fields Editor with the Add Fields dialog box Figure 13.6: The output of the FieldAcc example after the Center and Format buttons have been clicked Figure 13.7: The definition of a calculated field in the Calc example Figure 13.8: The output of the Calc example. Notice the Population Density calculated column and the ellipsis button displayed when you edit it. Figure 13.9: The output of the FieldLookup example, with the drop-down list inside the grid displaying values taken from another database table Figure 13.10: By handling the OnGetText and On-SetText events of a date field, the NullDates example displays specific output for null values. Figure 13.11: The output of the Total program, showing the total salaries of the employees Figure 13.12: The DrawData program displays a grid that includes the text of a memo field and the ubiqui-tous Borland fish. Figure 13.13: The MltGrid example has a DBGrid control that allows the selection of multiple rows. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Figure 13.14: The output of the NonAware example in Browse mode.The program manu-ally fetches the data every time the current record changes. Figure 13.15: In the SendToDb example, you can use a combo box to select the record you want to see. Figure 13.16: The CdsCalcs example demon-strates that by writing a little code, you can have the DBGrid control visually show the grouping defined in the ClientDataSet. Figure 13.17: The bottom portion of a ClientDataSet's Fields Editor displays aggregate fields. Figure 13.18: The MastDet example at run time Chapter 14: Client/Server with dbExpress Figure 14.1: IBConsole lets you manage, from a single computer, InterBase databases hosted by multiple servers. Figure 14.2: IBConsole can open separate windows to show you the details of each entity—in this case, a table. Figure 14.3: IBConsole's Interactive SQL window lets you try in advance the queries you plan to include in your Delphi programs. Figure 14.4: The dbExpress Connection Editor with the dbExpress Drivers Settings dialog box Figure 14.5: The CommandText Editor used by the SQLDataSet com-ponent for queries Figure 14.6: A sample log obtained by the SQLMonitor in the DbxSingle example Figure 14.7: The SchemaTest example allows you to see a database's tables and the columns of a given table. Figure 14.8: Editing a query component's collection of parameters Figure 14.9: The ParQuery example at run time Figure 14.10: The CdsDelta program displays the status of each record of a ClientDataSet. Figure 14.11: The CdsDelta example allows you to see the temporary update requests stored in the Delta property of the ClientDataSet. Figure 14.12: The Reconcile Error dialog provided by Delphi in the Object Repository and used by the CdsDelta example Figure 14.13: The form of the TranSample application at design time. The radio buttons let you set different transaction isolation levels. Figure 14.14: The output of the IbxUpdSql example Figure 14.15: The output of the IbxMon example, based on the IBMonitor component Figure 14.16: The server informa-tion displayed by the IbxMon application Figure 14.17: The editor for the GeneratorField property of the IBX datasets Figure 14.18: A form showing companies, office locations, and people (part of the RWBlocks example) Figure 14.19: The RWBlocks example form for class registrations Figure 14.20: The free query form of the RWBlocks example is intended for power users. Chapter 15: Working with ADO Figure 15.1: Delphi's connection string editor This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Figure 15.2: The first page of Microsoft's connec-tion string editor Figure 15.3: The OpenSchema example retrieves the primary keys of the database tables. Figure 15.4: Setting extended properties Figure 15.5: ABCCompany.xls in Delphi—a small tribute to Douglas Adams Figure 15.6: The form of the DataClone example, with two copies of a dataset (the original and a clone) Chapter 16: Multitier DataSnap Applications Figure 16.1: The Remote Data Module Wizard Figure 16.2: When you activate a ClientDataSet component con-nected to a remote data module at design time, the data from the server becomes visible as usual. Figure 16.3: The error message displayed by the ThinCli2 example when the employee ID is too large Figure 16.4: The form of the ClientRefresh example, which automatically refreshes the active record and allows more extensive updates by clicking the buttons Figure 16.5: The secondary form of the ThinPlus example, showing the data of a parametric query Figure 16.6: The ThinPlus example shows how a dataset field can either be displayed in a grid in a floating window or extracted by a ClientDataSet and displayed in a second form. You'll generally do one of the two things, not both! Chapter 17: Writing Database Components Figure 17.1: The data-aware ProgressBar in action in the DbProgr example Figure 17.2: The DbTrack example's track bars let you enter data in a database table. The check box and buttons test the enabled status of the components. Figure 17.3: The ViewGrid example demon-strates the output of the RecordView component, using Borland's sample BioLife database table. Figure 17.4: An example of the MdDbGrid component at design time. Notice the output of the graphics and memo fields. Figure 17.5: The structure of each buffer of the custom dataset, along with the various local fields referring to its subportions Figure 17.6: The form of the StreamDSDemo example. The custom dataset has been activated, so you can already see the data at design time. Figure 17.7: The output of the DirDemo example, which uses an unusual dataset that shows directory data Figure 17.8: The ObjDataSet-Demo example showcases a dataset mapped to objects using RTTI. Chapter 18: Reporting with Rave Figure 18.1: The Rave Designer with a simple report Figure 18.2: The Rave Report Preview window for a report Figure 18.3: After executing a Rave project, a user can choose the output format or rendering engine. Figure 18.4: The RaveSingle report (generated with the help of a wizard) at design time This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Figure 18.5: The Rave Designer's Data Text Editor Figure 18.6: The master/detail report. The Band Style Editor appears in front of it. Figure 18.7: The bold text in the report is determined at run time by a script. Chapter 19: Internet Programming: Sockets and Indy Figure 19.1: The client program of the IndySock1 example Figure 19.2: The client and server programs of the data-base socket example (IndyDbSock) Figure 19.3: The SendList pro-gram at design time Figure 19.4: The WebFind application can be used to search for a list of sites on the Google search engine. Figure 19.5: The output of the BrowseFast text-only browser Figure 19.6: The page displayed by connecting a browser to the custom HttpServ program Figure 19.7: The output of the HtmlProd example, a simple demonstra-tion of the Page-Producer component, when the user clicks the Demo Page button Figure 19.8: The output of the HtmlProd example for the Print Line button Figure 19.9: The editor of the DataSetTable-Producer compo-nent's Columns property provides you with a preview of the final HTML table (if the data-base table is active). Chapter 20: Web Programming with WebBroker and WebSnap Figure 20.1: The output of the CgiDate application, as seen in a browser Figure 20.2: A list of applications registered with the Web App Debugger is displayed when you hook to its home page. Figure 20.3: The output corresponding to the table path of the BrokDemo example, which produces an HTML table with internal hyperlinks Figure 20.4: The form action of the CustQueP example produces an HTML form with a selection component dynamically updated to reflect the current status of the database. Figure 20.5: The WebSearch program shows the result of multiple searches done on Google. Figure 20.6: The options offered by the New Web-Snap Application dialog box include the type of server and a button that lets you select the core appli-cation components. Figure 20.7: The New WebSnap Page Module dialog box Figure 20.8: The WSnap2 example features a plain script and a custom menu stored in an include file. Figure 20.9: The Web Surface Designer for the inout page of the WSnap2 example, at design time Figure 20.10: The page shown by the WSnapTable example at startup includes the initial portion of a paged table. Figure 20.11: The formview page shown by the WSnapTable example at design time, in the Web Surface Designer (or AdapterPageProducer editor) Figure 20.12: The WSnapMD example shows a master/detail structure and has some customized output. Figure 20.13: Two instances of the browser operate on two different sessions of the same WebSnap application. This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . Chapter 21: Web Programming with IntraWeb Figure 21.1: The IWSimpleApp program in a browser Figure 21.2: The controller form of a stand-alone IntraWeb application Figure 21.3: The IWTree example features a menu, a tree view, and the dynamic creation of a memo component. Figure 21.4: The IWTwoForms example uses an IWGrid component, embedded text, and IWURL components. Figure 21.5: The IWSession application has both session-specific and global counters, as you can see by running two sessions in two different browsers (or even in the same browser). Figure 21.6: IntraWeb's HTML Layout Editor is a full-blown visual HTML editor. Figure 21.7: The data-aware grid of the IWScrollData example Figure 21.8: The main form of the IWGridDemo example uses a framed grid with hyperlinks to the secondary form. Figure 21.9: The secondary form of the IWGridDemo example allows a user to edit the data and navigate through records. Figure 21.10: The grid of the IWClientGrid example supports custom sorting and filtering without re-fetching the data on the web server. Chapter 22: Using XML Technologies Figure 22.1: The XmlEditOne example allows you to enter XML text in a memo, indicating errors as you type, and shows the result in the embedded browser. Figure 22.2: The XmlDomTree example can open a generic XML document and show it inside a TreeView common control. Figure 22.3: The DomCreate example can generate various types of XML documents using a DOM. Figure 22.4: The XML generated to describe the form of the DomCreate program. Notice (in the tree and in the memo text) that properties of class types are further expanded. Figure 22.5: Delphi's XML Data Binding Wizard can examine the structure of a document or a schema (or another document definition) to create a set of interfaces for simplified and direct access to the DOM data. Figure 22.6: The log produced by reading an XML document with the SAX in the Sax-Demo1 example Figure 22.7: The XML Mapper shows the two sides of a transformation to define a mapping between them (with the rules indicated in the central portion). Figure 22.8: The XmlMapping example uses a TransformProvider component to make a complex XML document available for editing within multiple ClientData-Set components. Figure 22.9: The MapTable example generates an XML document from a database table using a custom transformation file. Figure 22.10: The InetXPage-Producer editor allows you to build complex HTML forms visually, similarly to the AdapterPageProducer. Figure 22.11: The IeFirst application sends the browser some HTML components, an XML document, and the JavaScript code to show the data in the visual components. Figure 22.12: The result of an XSLT transformation generated (even at design time) by the XSLPageProducer component in the XslCust example This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Figure 22.13: The LargeXml example in action Chapter 23: Web Services and SOAP Figure 23.1: The WSDL Import Wizard in action Figure 23.2: An example of a translation from English to German obtained by Alta-Vista's BabelFish via a web service Figure 23.3: The description of the Convert-Service web service provided by Delphi components Figure 23.4: The ConvertCaller client of the Convert-Service web service shows how few German marks you used to get for so many Italian liras, before the euro changed everything. Figure 23.5: The client program of the SoapEmployee web service example Figure 23.6: The HTTP log of the Web App Debugger includes the low-level SOAP request. Figure 23.7: The FishClient example receives a binary ClientDataSet within a SOAP attachment. Figure 23.8: The UDDI Browser embedded in the Delphi IDE Figure 23.9: The UddiInquiry example features a limited UDDI browser. Chapter 24: The Microsoft .NET Architecture from the Delphi Perspective Figure 24.1: The HelloWorld demo as seen in ILDASM Figure 24.2: The ILDASM output for the DestructorTest example Figure 24.3: The ILDASM IL window for the Destroy destructor Figure 24.4: .NET's Global Assembly Cache as see in Windows Explorer Chapter 25: Delphi for .NET Preview: The Language and the RTL Figure 25.1: The NetClassInfo example shows the base classes of a given component. Figure 25.2: The CLRReflection example, with an assembly loaded Figure 25.3: The aspbase.aspx example in a browser Figure 25.4: The output of the aspui.aspx example, after typing in the edit box and clicking the button This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. List of Tables Chapter 1: Delphi 7 and Its IDE Table 1.1: Delphi Project File Extensions Table 1.2: Selected Delphi IDE Customization File Extensions Chapter 5: Visual Controls Table 5.1: Names of Equivalent VCL and CLX Units Chapter 13: Delphi's Database Architecture Table 13.1: The Dataset Fields in the DbAware Example Table 13.2: The Subclasses of TField Chapter 15: Working with ADO Table 15.1: OLE DB Providers Included with MDAC Table 15.2: dbGo Components This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks . List of Listings Chapter 3: The Run-Time Library Listing 3.1: The definition of the TObject class (in the System RTL unit) Chapter 4: Core Library Classes Listing 4.1: The Definition of the TPersistent Class, from the Classes Unit Listing 4.2: The Public Portion of the Definition of the TStream Class Chapter 5: Visual Controls Listing 5.1: An XFM File (Left) and an Equivalent DFM File (Right) Chapter 6: Building the User Interface Listing 6.1: Key Portions of the DFM of the Pages Example Listing 6.2: A Sample Manifest File (pages.exe.manifest) Listing 6.3: The Actions of the Actions Example Chapter 8: The Architecture of Delphi Applications Listing 8.1: A Simple Unit for Testing Memory Leaks, from the ObjsLeft Example Chapter 9: Writing Delphi Components Listing 9.1: Code of the TMdFontCombo Class, Generated by the Component Wizard Listing 9.2: A Component that Refers to an External Component Using an Interface Listing 9.3: The Classes for a Collection and Its Items Chapter 10: Libraries and Packages Listing 10.1: The IntfColSel Unit of the IntfPack Package Chapter 13: Delphi's Database Architecture Listing 13.1: The DFM File of the MyBase1 Sample Program Listing 13.2: The Public Interface of the TDataSet Class (Excerpted) Chapter 14: Client/Server with dbExpress Listing 14.1: The Core Method of the UniPrint Example This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Chapter 16: Multitier DataSnap Applications Listing 16.1: The Definition of the IAppServer Interface Chapter 17: Writing Database Components Listing 17.1: The DrawCell Method of the Custom RecordView Component Listing 17.2: The Declaration of TMdCustomDataSet and TMdDataSetStream Listing 17.3: The Contrib.INI File for the Demo Application Listing 17.4: The InternalInitFieldDefs Method of the Stream-Based Dataset Listing 17.5: The Complete Definition of the TMdObjDataSet Class Chapter 19: Internet Programming: Sockets and Indy Listing 19.1: The TFindWebThread Class (of the WebFind Program) Chapter 20: Web Programming with WebBroker and WebSnap Listing 20.1: The menu.html File Included in Each Page of the WSnap2 Example Listing 20.2: AdapterPageProducer Settings for the WSnapTable Main Page Listing 20.3: AdapterPageProducer Settings for the formview Page Chapter 21: Web Programming with IntraWeb Listing 21.1: Properties of the IWDBGrid in the IWGridDemo Example Chapter 22: Using XML Technologies Listing 22.1: The Sample XML Document Used by Examples in this Chapter Chapter 24: The Microsoft .NET Architecture from the Delphi Perspective Listing 24.1: The Project of the DestructorTest Example Listing 24.2: The Unit of the DestructorTest Example Chapter 25: Delphi for .NET Preview: The Language and the RTL Listing 25.1: The ReflectionUnit Unit of the CLRReflection Example This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks List of Sidebars Chapter 1: Delphi 7 and Its IDE Drop-Down Fonts in the Object Inspector The Empty Project Template Installing New DLL Wizards Chapter 2: The Delphi Programming Language Accessing Protected Data of Other Classes (or, the "Protected Hack") Debugging and Exceptions Chapter 3: The Run-Time Library Executable Size under the Microscope Simple Dragging in Delphi Chapter 4: Core Library Classes Object Streaming versus Code Generation Accessing Published Fields and Methods Writing a Custom Stream Class Chapter 5: Visual Controls From Qt to CLX Chapter 6: Building the User Interface A Really Cool Toolbar Chapter 7: Working with Forms Using Windows without a Mouse Chapter 8: The Architecture of Delphi Applications Forms in Pages INI Files and the Registry in Delphi Chapter 9: Writing Delphi Components This document was created by an unregistered ChmMagic, please go to http://www.bisenter.com to register it. Thanks. Installing the Components Created in This Chapter Building Compound Components with Frames Property-Naming Conventions Chapter 11: Modeling and OOP Programming (with ModelMaker) Where's the VCL? Inheritance and Importing Code in ModelMaker Design Patterns 101 Chapter 12: From COM to COM+ COM Instancing and Threading Models Interfaces, Variants, and Dispatch Interfaces: Testing the Speed Difference Chapter 13: Delphi's Database Architecture A Data Module for Data-Access Components Chapter 14: Client/Server with dbExpress OIDs to the Extreme A Short History of InterBase The TimeStamp Field Type Chapter 17: Writing Database Components Replicable Data-Aware Controls Chapter 19: Internet Programming: Sockets and Indy Internet Direct (Indy) Open Source Components Chapter 24: The Microsoft .NET Architecture from the Delphi Perspective Issues with Overriding Finalize Recommend Documentswww.bundlecg.com www.bundlecg.com www.bundlecg.com www.bundlecg.com www.bundlecg.com www.bundlecg.com www.bundlecg.com www.bundlecg.com www.bundlecg.com www.bundlecg.com www.bundlecg.com www.bundlecg.com www.bundlecg.com www.bundlecg.com www.bundlecg
Sign In |