📄 148.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 "Editing Panels". <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 <> Value then <br>
FText := Value; <br>
end; <br>
<br>
<br>
procedure TMyCollectionItem.SetMoreStuff(const Value: LongInt); <br>
begin <br>
if FMoreStuff <> 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 + -