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

📄 148.htm

📁 水木清华的BBS文章
💻 HTM
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://bbs.tsinghua.edu.cn"><font face="黑体"><big><big>水木清华★</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center">         Delphi编程                            (BM: strayli FlyingBoy)          </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p   align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="454"> <p align="center">[<a href="index.htm">回到开始</a>][<a href="7.htm">上一层</a>][<a href="149.htm">下一篇</a>]
<hr><p align="left"><small>发信人: strayli (stray), 信区: Delphi <br>

标  题: Implementing TCollection <br>

发信站: BBS 水木清华站 (Tue Sep 22 18:22:02 1998) <br>

  <br>

  This document is intended for those needing to descend from a class <br>

that manages an array of lightweight persistent objects of the same <br>

type.  The class that best accomplishes this is TCollection and <br>

TCollectionItem.  For example, TCollection is used to manage Panels <br>

in a TStatusBar, Columns in a TDBGrid, or Constraints in a TTable. <br>

  <br>

  This document begins with a discussion of the expected behavior of <br>

TCollection descendants, followed by a listing of the minimal steps <br>

necessary to implement a TCollection descendant, a listing of <br>

the component source, and finally some notes on design decisions <br>

and ideas for expansion of your TCollection descendant component. <br>

  <br>

  <br>

General Discussion <br>

------------------ <br>

  To become familiar with the default behavior of TCollection, try <br>

adding a TStatusBar component to a form, click the ellipses of the <br>

Panels property, press the Add button of the &quot;Editing Panels&quot;. <br>

This last step adds a TStatusPanel to the editor.  Click on <br>



on the TStatusPanel item in the editor and notice the change in <br>

the object inspector.  Instead of seeing TStatusBar now you will <br>

see StatusBar1.Panels[0] reflected in the Object Inspector. <br>

  <br>

  There are three major players involved with collections.  A <br>

collection item (TCollectionItem) descendant, a TCollection that <br>

manages the list of TCollectionItems, and a component that contains <br>

the TCollection as one of it's properties.  In our above example of <br>

TStatusBar, TStatusBar contains a descendant of TCollection called <br>

TPanels and TPanels manages a list of TCollectionItem descendants <br>

called TPanel.  Notice that each TCollectionItem contains one or <br>

more properties; for instance, TPanels contains Alignment, Bevel, <br>

Style, Text, and Width properties.  This list changes depending on <br>

the definition of your TCollectionItem descendant. <br>

  <br>

Creating a Minimal TCollection Implementation <br>

--------------------------------------------- <br>

In a new unit you must first define three new descendant classes <br>

from TCollectionItem, TCollection and a TComponent. <br>

  <br>

  TMyCollectionItem = class(TCollectionItem) <br>

  <br>

  <br>

  TMyCollection = class(TCollection) <br>

  <br>

  TMyComponent = class(TComponent) <br>

  <br>

  To make TMyCollectionItem functional, you need to define <br>

one or more properties to contain information to be tracked <br>

by the collection mechanism.  The example defines a Text and <br>

a MoreStuff integer property.  You will also need to override <br>

the GetDisplayName method to supply the string shown for each <br>

item in the collection property editor: <br>

  <br>

 TMyCollectionItem = class(TCollectionItem) <br>

  private <br>

    FText: string; <br>

    FMoreStuff: LongInt; <br>

    function GetDisplayName: string; override; <br>

    procedure SetText(const Value: string); <br>

    procedure SetMoreStuff(const Value: LongInt); <br>

  published <br>

    property Text: string read FText write SetText; <br>

    property MoreStuff: LongInt <br>

      read FMoreStuff write SetMoreStuff; <br>



  end; <br>

  <br>

  Next, define the TCollection descendant.  This class will <br>

keep track of the component the collection belongs to, <br>

override the GetOwner method to accomodate streaming, and <br>

manage an array of the previously defined TCollectionItem <br>

descendants. <br>

  You will need to define a new static constructor.  The parameter <br>

passed in this constructor is the reference to the component <br>

that contains the collection.  Also in the constructor you <br>

need to populate the ItemClass property with the class of your <br>

TCollection item descendant. Note: ItemClass returns the class <br>

(descended from TCollectionItem) to which the items in the <br>

collection belong. <br>

  <br>

 TMyCollection = class(TCollection) <br>

  private <br>

    FMyComponent: TMyComponent; <br>

    function GetItem(Index: Integer): TMyCollectionItem; <br>

    procedure SetItem(Index: Integer; Value: TMyCollectionItem); <br>

  protected <br>

    function GetOwner: TPersistent; override; <br>

    function GetOwner: TPersistent; override; <br>

  public <br>

    constructor Create(MyComponent: TMyComponent); <br>

    function Add: TMyCollectionItem; <br>

    property Items[Index: Integer]: TMyCollectionItem <br>

      read GetItem write SetItem; default; <br>

  end; <br>

  <br>

  Finally, define the component that will contain the collection. <br>

The component will contain a property descended from the <br>

TCollection type defined previously.  The TCollection property <br>

will need a private field, an access method to the private field, <br>

and storage allocated in the constructor and freed in the <br>

destructor. <br>

  <br>

Note: See The Developers Guide for more information on creating <br>

custom components. <br>

  <br>

  <br>

  TMyComponent = class(TComponent) <br>

  private <br>

    FItems: TMyCollection; <br>

    procedure SetItems(Value: TMyCollection); <br>



  public <br>

    constructor Create(AOwner: TComponent); override; <br>

    destructor Destroy; override; <br>

  published <br>

    property Items: TMyCollection <br>

      read FItems write SetItems; <br>

  end; <br>

  <br>

Complete Unit Listing <br>

--------------------- <br>

unit Collec1; <br>

  <br>

interface <br>

  <br>

//  Note: TCollection and TCollectionItem are defined in Classes.Pas. <br>

  <br>

uses Classes; <br>

  <br>

type <br>

  <br>

  TMyComponent = class; <br>

  <br>

  <br>

  TMyCollectionItem = class(TCollectionItem) <br>

  private <br>

    FText: string; <br>

    FMoreStuff: LongInt; <br>

    function GetDisplayName: string; override; <br>

    procedure SetText(const Value: string); <br>

    procedure SetMoreStuff(const Value: LongInt); <br>

  public <br>

  published <br>

    property Text: string read FText write SetText; <br>

    property MoreStuff: LongInt read FMoreStuff write SetMoreStuff; <br>

  end; <br>

  <br>

  TMyCollection = class(TCollection) <br>

  private <br>

    FMyComponent: TMyComponent; <br>

    function GetItem(Index: Integer): TMyCollectionItem; <br>

    procedure SetItem(Index: Integer; Value: TMyCollectionItem); <br>

  protected <br>

    function GetOwner: TPersistent; override; <br>

  public <br>

    constructor Create(MyComponent: TMyComponent); <br>



    function Add: TMyCollectionItem; <br>

    property Items[Index: Integer]: TMyCollectionItem <br>

      read GetItem write SetItem; default; <br>

  end; <br>

  <br>

  TMyComponent = class(TComponent) <br>

  private <br>

    FItems: TMyCollection; <br>

    procedure SetItems(Value: TMyCollection); <br>

  public <br>

    constructor Create(AOwner: TComponent); override; <br>

    destructor Destroy; override; <br>

  published <br>

    property Items: TMyCollection read FItems write SetItems; <br>

  end; <br>

  <br>

procedure Register; <br>

  <br>

implementation <br>

  <br>

procedure Register; <br>

begin <br>

begin <br>

  RegisterComponents('Sample', [TMyComponent]); <br>

end; <br>

  <br>

  <br>

{ TMyCollectionItem } <br>

  <br>

  <br>

// Note: Inherited default behavior of GetDisplayName is to <br>

// return the classname. <br>

  <br>

function TMyCollectionItem.GetDisplayName: string; <br>

begin <br>

  Result := Text; <br>

  if Result = '' then Result := inherited GetDisplayName; <br>

end; <br>

  <br>

procedure TMyCollectionItem.SetText(const Value: string); <br>

begin <br>

  if FText &lt;&gt; Value then <br>

    FText := Value; <br>

end; <br>

  <br>

  <br>

procedure TMyCollectionItem.SetMoreStuff(const Value: LongInt); <br>

begin <br>

  if FMoreStuff &lt;&gt; Value then <br>

    FMoreStuff:= Value; <br>

end; <br>

  <br>

  <br>

{ TMyCollection } <br>

  <br>

constructor TMyCollection.Create(MyComponent: TMyComponent); <br>

begin <br>

  inherited Create(TMyCollectionItem); <br>

  FMyComponent := MyComponent; <br>

end; <br>

  <br>

function TMyCollection.Add: TMyCollectionItem; <br>

begin <br>

  Result := TMyCollectionItem(inherited Add); <br>

end; <br>

  <br>

function TMyCollection.GetItem(Index: Integer): TMyCollectionItem; <br>

begin <br>

begin <br>

  Result := TMyCollectionItem(inherited GetItem(Index)); <br>

end; <br>

  <br>

procedure TMyCollection.SetItem(Index: Integer; <br>

        Value: TMyCollectionItem); <br>

begin <br>

  inherited SetItem(Index, Value); <br>

end; <br>

  <br>

// Note: You must override GetOwner in Delphi 3.x to get <br>

// correct streaming behavior. <br>

function TMyCollection.GetOwner: TPersistent; <br>

begin <br>

  Result := FMyComponent; <br>

end; <br>

  <br>

  <br>

{ TMyComponent } <br>

  <br>

constructor TMyComponent.Create(AOwner: TComponent); <br>

begin <br>

  inherited Create(AOwner); <br>



  FItems := TMyCollection.Create(Self); <br>

end; <br>

  <br>

destructor TMyComponent.Destroy; <br>

begin <br>

  FItems.Free; <br>

  inherited Destroy; <br>

end; <br>

  <br>

procedure TMyComponent.SetItems(Value: TMyCollection); <br>

begin <br>

  FItems.Assign(Value); <br>

end; <br>

  <br>

end. <br>

{--------------------------------------------------------------------} <br>

  <br>

  <br>

Notes <br>

----- <br>

  <br>

  In this minimal example we didn't override the Assign method for <br>

rride the Assign method for <br>

the TCollectionItem, but this method should have further support. <br>

Here's an example of how you might implement Assign in the above <br>

project: <br>

  <br>

procedure TMyCollectionItem.Assign(Source: TPersistent); <br>

begin <br>

  if Source is TMyCollectionItem then <br>

  begin <br>

    Text := TMyCollectionItem(Source).Text; <br>

    MoreStuff := TMyCollectionItem(Source).MoreStuff; <br>

    Exit; <br>

  end; <br>

  inherited Assign(Source); <br>

end; <br>

  <br>

  Also not included in the above project is the logic needed to <br>

notify the TCollection class when one of it's contained items has <br>

changed.  This could be particularly important in a visual control <br>

such as TStatusBar.  TCollection supplies a virtual Update method <br>

for handling this behavior.  See TStatusBar or THeaderControl <br>

in \source\vcl\commctrls.pas for further examples. <br>

  <br>

.pas for further examples. <br>

  <br>

-- <br>

※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 210.45.208.4] <br>

</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="7.htm">上一层</a>][<a href="149.htm">下一篇</a>]
<p align="center"><a href="http://cterm.163.net">欢迎访问Cterm主页</a></p>
</body>
</html>

⌨️ 快捷键说明

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