📄 ch20.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"><HTML><HEAD><SCRIPT LANGUAGE="JavaScript"><!--function popUp(pPage) { var fullURL = document.location; var textURL = fullURL.toString(); var URLlen = textURL.length; var lenMinusPage = textURL.lastIndexOf("/"); lenMinusPage += 1; var fullPath = textURL.substring(0,lenMinusPage); popUpWin = window.open('','popWin','resizable=yes,scrollbars=no,width=525,height=394'); figDoc= popUpWin.document; zhtm= '<HTML><HEAD><TITLE>' + pPage + '</TITLE>'; zhtm += '</head>'; zhtm += '<BODY bgcolor="#FFFFFF">'; zhtm += '<IMG SRC="' + fullPath + pPage + '">'; zhtm += '<P><B>' + pPage + '</B>'; zhtm += '</BODY></HTML>'; window.popUpWin.document.write(zhtm); window.popUpWin.document.close(); // Johnny Jackson 4/28/98 }//--> </SCRIPT><link rel="stylesheet" href="/includes/stylesheets/ebooks.css"> <META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1"> <TITLE>Teach Yourself Borland Delphi 4 in 21 Days -- Ch 20 -- Creating Components</TITLE></HEAD><BODY TEXT="#000000" BGCOLOR="#FFFFFF"><CENTER><H1><IMG SRC="../button/sams.gif" WIDTH="171" HEIGHT="66" ALIGN="BOTTOM" BORDER="0"></H1><H1><BR>Teach Yourself Borland Delphi 4 in 21 Days</H1></CENTER><CENTER><P><A HREF="../ch19/ch19.htm"><IMG SRC="../button/previous.gif" WIDTH="128" HEIGHT="28"ALIGN="BOTTOM" ALT="Previous chapter" BORDER="0"></A><A HREF="../ch21/ch21.htm"><IMGSRC="../button/next.gif" WIDTH="128" HEIGHT="28" ALIGN="BOTTOM" ALT="Next chapter"BORDER="0"></A><A HREF="../index.htm"><IMG SRC="../button/contents.gif" WIDTH="128"HEIGHT="28" ALIGN="BOTTOM" ALT="Contents" BORDER="0"></A> <HR></CENTER><CENTER><H1>- 20 -</H1><H1>Creating Components</H1></CENTER><UL> <LI><A HREF="#Heading1">Creating a New Component</A> <LI><A HREF="#Heading2">The New Component Dialog Box</A> <UL> <LI><A HREF="#Heading3">Creating the FlashingLabel Component</A> <LI><A HREF="#Heading4">The Register Procedure</A> </UL> <LI><A HREF="#Heading5">Component Properties and Methods</A> <UL> <LI><A HREF="#Heading6">Properties</A> <LI><A HREF="#Heading7">Properties Can Be Read-Only or Write-Only</A> <LI><A HREF="#Heading8">Writing Methods for Components</A> </UL> <LI><A HREF="#Heading9">Adding Functionality to TFlashingLabel</A> <UL> <LI><A HREF="#Heading10">The Class Declaration</A> <LI><A HREF="#Heading11">The Published Section</A> <LI><A HREF="#Heading12">The Implementation Section</A> <LI><A HREF="#Heading13">The SetFlashRate Procedure</A> <LI><A HREF="#Heading14">The ComponentState Property</A> </UL> <LI><A HREF="#Heading15">Testing the Component</A> <LI><A HREF="#Heading16">Adding the Component to the Component Palette</A> <LI><A HREF="#Heading17">Adding a Custom Bitmap to the Component's Button</A> <LI><A HREF="#Heading18">Writing Events for Components</A> <UL> <LI><A HREF="#Heading19">Events Overview</A> <LI><A HREF="#Heading20">Declaring the Underlying Data Field</A> <LI><A HREF="#Heading21">Overriding Base Class Events</A> </UL> <LI><A HREF="#Heading22">Putting It All Together</A> <LI><A HREF="#Heading23">Summary</A> <LI><A HREF="#Heading24">Workshop</A> <UL> <LI><A HREF="#Heading25">Q&A</A> <LI><A HREF="#Heading26">Quiz</A> <LI><A HREF="#Heading27">Exercises</A> </UL></UL><P><HR SIZE="4"><CENTER><H1></H1></CENTER><P>Delphi provides a wide assortment of components to use in your applications. Thesecomponents cover the basic Windows controls as well as provide some specialty componentsnot inherent in Windows itself. Still, you might need to create a component of yourown to perform a task not provided by the pre-installed components. Writing a componentrequires these steps:</P><P><DL> <DT></DT> <DD><B>1. </B>Use the New Component dialog box to begin the creation process. <P> <DT></DT> <DD><B>2. </B>Add properties, methods, and events to the component's class. <P> <DT></DT> <DD><B>3. </B>Test the component. <P> <DT></DT> <DD><B>4. </B>Add the component to the Component palette. <P></DL><P>Today you learn how to create components. As with most of the more difficult conceptsin Delphi, it's not so bad after you've done it once or twice. You will learn thistechnique by building a component called TFlashingLabel. TFlashingLabel is a regularLabel component that flashes its text. By the time the day is done, you will knowwhat you need in order to create basic components.</P><P><H2><A NAME="Heading1"></A>Creating a New Component</H2><P>Writing components requires a higher level of programming expertise than you haveused up to this point. First, you have to create a class for your new component.The class needs to be designed so that some of its properties show up in the ObjectInspector, whereas others will be used only at runtime. In addition, you will almostcertainly have to write methods for your component. Some will be private to the component;others will be made public so that users of the component can access them. Finally,you might have to write events for the component. Obviously, there is some work involved.As great as Delphi's visual programming environment is, it won't help you here. Writingcomponents is pure programming.</P><P><H2><A NAME="Heading2"></A>The New Component Dialog Box</H2><P>The New Component dialog box gives you a head start on writing a component. Toaccess the New Component dialog box, choose File|New to display the Object Repositoryand then double-click the Component icon. Figure 20.1 shows the New Component dialogbox you see when creating a new component.</P><P><A HREF="javascript:popUp('28672001.gif')"><B>FIGURE 20.1.</B></A><B> </B><I>TheNew Component dialog box.</I></P><P>The Ancestor type field is used to specify an ancestor class for the new component.The classes of all installed components are listed in the Ancestor type combo box.When you create a new component, you should choose a base class that most closelymatches the type of component you want to create.</P><P>For example, the FlashingLabel component is just a label that flashes. In thatcase, the standard Label component has everything you need to get started, so youcould use a TCustomLabel for the ancestor class. If, on the other hand, you wantto create a component that creates Windows shortcuts, you would probably derive thecomponent from TComponent (the base class for all components) because there is noother VCL component that gives you a better base from which to work.</P><BLOCKQUOTE> <P><HR><strong>NOTE:</strong> Delphi provides several classes that you can use as base classes for new components. The names of these classes all start with TCustom. For example, the base class for a TLabel is TCustomLabel. You can derive from one of these classes whenever you create a new component. The custom classes already provide the properties you are most likely to need for that component type, but the properties are not published (<I>published</I> <I>properties</I> are the properties shown in the Object Inspector at design time). All you have to do to make the properties published is re-declare the base class's properties in the published section of your component's class declaration. This is important because after a property is published, it can't be unpublished. Starting with a custom class enables you to choose exactly the properties you want published.<HR></BLOCKQUOTE><P>When you derive a new component from an existing component, you are using theObject Pascal feature called <I>inheritance</I>. It's been a while since I talkedabout inheritance, so refer to Day 3, "Classes and Object-Oriented Programming,"if you need a refresher course. Inheriting from a component is, in effect, takingeverything that component has and adding some functionality of your own. The classyou are inheriting from is the base class, and the new class is the derived class.In the previous example, TCustomLabel would be the base class and TFlashingLabelwould be the derived class.</P><P>After you select an ancestor class, type the name of your new component's classin the Class Name field. The classname should begin with a <I>T</I> and should describethe function the class performs. The component you build today will have the nameTFlashingLabel (you'll begin creating the component soon). If you choose a classnamethat already exists in the component library, the New Component dialog box will tellyou so when you click the OK button. You will have to choose a unique classname beforeyou can continue.</P><P><BLOCKQUOTE> <P><HR><strong>NOTE:</strong> There's no reason that you have to begin the classname with <I>T</I>; it just happens to be customary for Borland classes. (The use of <I>T</I> in Borland classes is a Borland tradition that goes back to the early days of Turbo Pascal. It was used in Turbo Vision, OWL, and now in VCL.) Some people use <I>T</I> when deriving from a Borland class but not when creating their own classes. It's entirely up to you.<HR></BLOCKQUOTE><PRE></PRE><BLOCKQUOTE> <P><HR><strong>NOTE:</strong> Professional component writers learned long ago to be sure that their component classes have unique names. Imagine the problems if two component vendors both name a component TFancyLabel. At TurboPower where I work, our Async Professional components start with TApd, our Orpheus components start with TOr, Abbrevia components start with TAb, and so on. Although this doesn't guarantee that these component names won't clash with those of other vendors, it certainly goes a long way to prevent that from happening.<HR></BLOCKQUOTE><P>The Palette Page field enables you to specify the page on the Component palettewhere you want the component's icon to appear. (The component's icon won't actuallyappear on the Component palette until you install the design package containing thecomponent.) You can choose an existing tab on the Component palette, or you can typethe name of a new tab you want Delphi to create for this component.</P><P>The Unit file name field is used to specify the name of the file that will containthe component's source. Delphi automatically creates a unit filename based on thecomponent's name, but you can change the supplied filename if you want. The Searchpath field is used to specify the search path that Delphi should use when lookingfor component packages. You won't usually need to modify this field.</P><P>The Install button is used to install the new component directly into a package.You need not worry about that now, though, because you will use the default packagethat Delphi provides for miscellaneous components.</P><P><H3><A NAME="Heading3"></A>Creating the FlashingLabel Component</H3><P>You are now ready to perform the first steps in creating the TFlashingLabel component.As I said earlier, this component is a regular Label component that flashes its texton the screen. With that in mind, let's get started creating the component:</P><P><DL> <DT></DT> <DD><B>1. </B>Choose File|New to invoke the Object Repository. <P> <DT></DT> <DD><B>2. </B>Double-click the Component icon in the Object Repository. The New Component dialog box is displayed. <P> <DT></DT> <DD><B>3. </B>From the Ancestor type combo box, choose the TCustomLabel class as the base class. <P> <DT></DT> <DD><B>4. </B>Type TFlashingLabel in the Class Name field. <P> <DT></DT> <DD><B>5. </B>The Palette Page field contains Samples. Leave this field as is. The new component will be added to the Samples page of the Component palette when you install the component. <P> <DT></DT> <DD><B>6. </B>Click OK to close the New Component dialog box. The Code Editor appears and displays a new source code unit. <P> <DD><B>7. </B>Save the unit as FlashingLabel.pas.</DL><P>Listing 20.1 shows the source unit as it appears now.</P><P><H4>LISTING 20.1. FlashingLabel.pas.</H4><PRE>unit FlashingLabel;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type TFlashingLabel = class(TCustomLabel) private { Private declarations } protected { Protected declarations } public { Public declarations } published { Published declarations } end;procedure Register;implementationprocedure Register;begin RegisterComponents(`Samples', [TFlashingLabel]);end;end.</PRE><P>As you can see, the TFlashingLabel class is derived from TCustomLabel. The classdeclaration is empty except for the access keywords (private, public, protected,and published). You can fill in the blanks later after I've had a chance to go overwhat comprises a component.<PRE></PRE><P>As you can see, the New Component dialog box gives you a head start by fillingout some of the basic parts of the component's unit for you. You still have to dothe hard stuff, but at least the Register procedure is written and the class declarationis started. Let me sidetrack here and talk about the Register procedure.</P><P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -