⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch20.htm

📁 delphi自学的好教材!特别适合刚刚起步学习delphi的人员!同样对使用者具有参考价值!
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<H3><A NAME="Heading4"></A>The Register Procedure</H3><P>Registering the component is necessary so that Delphi knows what components arein the component library and on what tab they should appear. A typical Register procedurelooks like this:</P><P><PRE>procedure Register;begin  RegisterComponents(`Samples', [TMyComponent]);end;</PRE><P>The Register procedure calls RegisterComponents to register the component. RegisterComponentstakes two parameters. The first parameter is the name of the Component palette pageon which the component will appear after it is installed; the second parameter isan array of components to be registered. If you were creating an entire library ofcomponents, you could register them all at one time by placing each component's classnamein the array. For example:</P><P><PRE>procedure Register;begin  RegisterComponents(`Essentials 1',     [TEsLabel, TEsScrollingMarquee, TEsCalendar,     TEsCalculator, TEsDateEdit, TEsNumberEdit, TEsMenuButton,     TEsColorComboBox, TEsTile, TEsGradient, TEsRollUp]);</PRE><PRE>end;</PRE><P>This Register procedure registers 11 components and places them on the Componentpalette tab called &quot;Essentials 1.&quot; Most of the time you will be dealingwith one component at a time, but you can certainly register more than one componentif you need to.</P><BLOCKQUOTE>	<P><HR><strong>NOTE:</strong> The Register procedure is also used to register component editors	and property editors. Component and property editors are special editors, usually	dialog boxes, that aid in modifying a component or a component's property at design	time. I won't discuss component and property editors in this book because they are	beyond the book's scope.<HR></BLOCKQUOTE><P>At this point the component doesn't do anything special, but before you go onwith the component's creation, I need to explain what makes up a component. Afterthat, you'll write the rest of the TFlashingLabel component. Keep the component thatyou just created (such as it is) open in the IDE because you'll need it a littlelater.</P><P><H2><A NAME="Heading5"></A>Component Properties and Methods</H2><P>A big part of writing components is writing the component's properties and methods.Events are also a big part of writing components, but let's talk first about propertiesand methods, and then I'll discuss events.</P><P><H3><A NAME="Heading6"></A>Properties</H3><P>You have been using properties a lot in your journey thus far; from a user's perspectiveyou know what properties are. Now you need to understand properties from a componentwriter's perspective. Before you write components, you need to understand what propertiesare--and what they are not.</P><P>Specifically, properties are not class data fields. It is natural to think ofproperties as data fields of the class to which they belong. After all, you treatproperties just like class data fields when you perform actions like this:</P><P>var</P><P><PRE>  W : Integer;begin  W := Width;  Height := W * 2;</PRE><P>But properties are not class data fields, and you must keep that in mind whenwriting components. Properties differ from class data fields in many ways but haveat least one feature in common with data fields: They have a specific data type.A property's type can be one of the integral data types (Integer, Word, Double, string,and so on), a class (TCanvas, TFont, and so on), or a record (TRect, for example).</P><P>What properties are, then, is a special type of object that meets the followingcriteria:</P><P><UL>	<LI>Properties have an underlying data field that is used to store the property's	value.	<P>	<LI>Properties can implement a write method.	<P>	<LI>Properties can implement a read method.	<P>	<LI>Properties can use direct access instead of read and write methods.	<P>	<LI>Properties can be read-only or write-only.	<P>	<LI>Properties can have a default value.	<P>	<LI>Properties can be published or non-published.</UL><PRE>For this to make more sense, let's take a look at these features of properties one at a time.</PRE><H4>Properties Have Underlying Class Data Fields</H4><P>Each property has an underlying class data field associated with it. It is thisdata field that holds the actual value associated with a property. Take a simpleassignment, for example:</P><P><PRE>Label.Caption := `Pat McGarry';</PRE><P>This statement assigns a string to the Caption property of a Label component.What happens behind the scenes is more than just a simple assignment, though. Becausea Caption property is of the string type, it has a string object as its underlyingdata field. When an assignment is made like this one, the underlying data field isgiven the value of the assigned string. Using an underlying data field is necessarybecause a property does not have the capability to store data on its own.</P><P>You can name the underlying data field anything you want, but tradition dictatesthat the data field associated with a property have the same name as the property,with the addition of a leading <I>F</I>. For example, the data field associated withthe Caption property is named FCaption.</P><BLOCKQUOTE>	<P><HR><strong>NOTE:</strong> This association between the property and its underlying data field	can be the source of much confusion when you start writing components. It's not that	it's difficult to understand; it's just that you might mix up the two when writing	code for the component. For example, you might accidentally write	<PRE>Left := 20;</PRE>	<PRE>when you mean to write</PRE>	<PRE>FLeft := 20;</PRE></BLOCKQUOTE><PRE></PRE><BLOCKQUOTE>	<P>This results in all sorts of interesting behavior in your component. You'll see	why when I discuss write methods in the next section.<HR></BLOCKQUOTE><P>The underlying data field is almost always declared as private. This is becauseyou want your users to modify the data field through the property or by calling amethod, but never directly. This way you are in control of the data field as muchas possible, which leads you to the next feature of properties.</P><P><H4>Properties Can Have Write Methods</H4><P>When you make an assignment to a property, many things can happen behind the scenes.Exactly what happens depends on the specific property. For example, this code lookssimple:</P><P><PRE>Left := 20;</PRE><P>But several things happen when this line is executed. First, the underlying datafield, FLeft, is changed to the new value. Next, the form (assuming this code wasexecuted from a form) is moved to the new left position using the Windows API functionMoveWindow. Finally, the form is repainted by calling Invalidate for the form.</P><P><PRE>How does all that happen? It happens through the Left property's write method. The write method is a method that is called any time the property is assigned a value. You can use the write method to do validation of the assigned value or to perform special processing.</PRE><P>You declare a property's write method when you declare the property. Here's anexample of a typical property declaration:</P><P><PRE>property FlashRate : Integer  read FFlashRate write SetFlashRate;</PRE><P>This declaration contains syntax that you haven't seen before because it is syntaxspecific to properties. First of all, notice that the property is declared with theproperty keyword and that the property type follows the property name. The secondline of code tells the compiler that the property is read directly from the FFlashRatedata field (I'll talk more about read methods in just a bit), and that the propertyuses a write method called SetFlashRate. You can name the write method anything youwant, but traditionally the write method has the same name as the property prependedwith the word <I>Set</I>.</P><P>When the property is written to (assigned a value), the write method associatedwith the property will be called automatically. The write method must be a procedureand must have one parameter. That parameter must be of the same type as the propertyitself. For example, the write method's declaration for the FlashRate property wouldbe</P><P><PRE>procedure SetFlashRate(AFlashRate : Integer);</PRE><P>The value passed to the write method is the value that was assigned to the property.So, given this line:</P><P><PRE>FlashingLabel.FlashRate := 1000;</PRE><P>You end up with the value of 1000 passed to the SetFlashRate function. What youdo with the value within the write method depends on a wide variety of factors. Ata minimum, you assign the value to the associated data field. In other words, thewrite method would look like this:</P><P>procedure TFlashingLabel.SetFlashRate(AFlashRate : Integer);</P><P><PRE>begin  FFlashRate := AFlashRate;  { Do some other stuff. } end;</PRE><BLOCKQUOTE>	<P><HR><strong>NOTE:</strong> The use of the leading <I>A</I> for the parameter name in a write	method is another Delphi tradition.<HR></BLOCKQUOTE><P>You will nearly always do something more than assign the value to the underlyingdata field. If you are only assigning the value to the data field associated withthe property, you don't need a write method for the property. I'll explain that injust a moment. First, let's look at read methods.</P><P><H4>Properties Can Have Read Methods</H4><P>The read method works exactly like the write method (aside from the obvious difference).When a property's value is read, the read method is executed and the value of theunderlying data field is returned.</P><P>The name of the read method is the property name preceded by <I>Get</I>. The readmethod takes no parameters and returns the property type. For example, if you wereto use a read method for the FlashRate property, it would be declared like this:</P><P><PRE>function GetFlashRate : Integer;</PRE><PRE>The read method might perform some processing and then return the value of the underlying data field, FFlashRate in this case. The reading of a property happens in many different ways. Sometimes it's the result of an assignment to a variable:</PRE><PRE>Rate := FlashingLabel.FlashRate;</PRE><P>At other times it is used within a statement:</P><P><PRE>case FlashingLabel.FlashRate of  1000 : SpeedUp;  { etc. } end;</PRE><P>Regardless of how the property is read, the read method is called each time aread takes place.</P><P>Notice that a couple of paragraphs ago I said <I>if</I> you are using a read method.Frequently you won't use a read method but instead will use direct access to retrievethe value of the data field associated with a property. Let's take a look at directaccess right now.</P><P><H4>Properties Can Use Direct Access</H4><P>You don't have to use read and write methods for your properties. If you are assigninga value to the underlying data field or reading the value of the underlying datafield, you can use direct access. The declaration for a property using direct accesslooks like this:</P><P>property FlashRate : Integer</P><P><PRE>  read FFlashRate write FFlashRate;</PRE><P>This snippet tells the compiler that the data field itself (FFlashRate) is usedfor both the read and the write specifiers rather than a read method or a write method.When the property is written to, the data field is changed and nothing more takesplace. When the property is read, the value of the underlying data field is returned.It's as simple as that.</P><BLOCKQUOTE>	<P><HR><strong>NOTE:</strong> It is common to use direct access when reading the property and to	use a write method for writing to the property. Take a look at this earlier example	of a property declaration:<HR></BLOCKQUOTE><PRE>property FlashRate : Integer  read FFlashRate write SetFlashRate;</PRE><BLOCKQUOTE>	<P><HR>The property uses direct access for reading, but it uses a write method for writing.	Writing to a property often produces side effects, as I explained in the previous	section. In fact, the capability to spawn side effects is one of the big strengths	of properties. To cause side effects when your property is written to, you use a	write method. Reading a property, on the other hand, is usually just a matter of	returning the value of the underlying data field. In that case, direct access makes	the most sense.<HR></BLOCKQUOTE><H3><A NAME="Heading7"></A>Properties Can Be Read-Only or Write-Only</H3><P>You can specify a property to be read-only or write-only. Making a property read-onlyis a useful feature (VCL has many read-only properties). For example, you might havea property that you want the user to be able to read but not modify. It could bethat modifying the property directly would have adverse effects on the component,so you need to protect against that.</P><P>Making a property read-only is easy, you simply omit the write specifier in theproperty's declaration:</P><P><PRE>property FlashRate : Integer  read FFlashRate;</PRE><P>If the user attempts to write to a property that is declared as read-only, heor she will get a compiler error that says &quot;Cannot assign to a read-only property&quot;.As you can see, making a property read-only is very simple.</P><P>You can make a property write-only by omitting the read specifier from the property'sdeclaration. It's difficult to imagine a use for a property that can be written tobut not read, but you certainly can write such a property, if necessary.</P><P><H4>Properties Can Have Default Values</H4><P>A <I>default value</I> is another useful feature of properties. You will noticethat when you place a component on a form, many properties that are displayed in

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -