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

📄 ch20.htm

📁 好书《C++ Builder高级编程技术》
💻 HTM
📖 第 1 页 / 共 5 页
字号:
{

  void __fastcall Register()

  {

    TComponentClass classes[1] = {__classid(TWidget)};

    RegisterClasses(classes, 0);

  }

}



TWidget 
*ReadWidgetFromStream(AnsiString StreamName)

{

  Widgets::Register();

  TFileStream *Stream = new TFileStream(StreamName, fmOpenRead);

  TWidget *Widget = (TWidget *)Stream->ReadComponent(NULL);

  delete Stream;

  return Widget;

}


</FONT></PRE>
<P>This code first registers the <TT>TWidget</TT> type with the system. This is necessary
because the VCL needs to know what type of object you want to stream. Of course,
when working with components that are placed on the Component 
Palette, you can be
sure the system has already registered the object for you. However, if you did not
drop a component on a form but created it by hand, you might have to register the
component before you can stream it.</P>
<P>The <TT>Register</TT> 
method needs to appear in its own namespace because there
will be many register functions in a typical application--at least one for each component.
Most of the time this function will be called automatically by the compiler, and
it is a bit unusual 
for you to have to call it explicitly.</P>
<P>Notice that the compiler will automatically construct an object for you if you
pass in <TT>NULL</TT> when calling <TT>ReadComponent</TT>:</P>
<PRE><FONT COLOR="#0066FF">TWidget *Widget = (TWidget 
*)Stream-&gt;ReadComponent(NULL);

</FONT></PRE>
<P>Alternatively, you can create the component yourself and then pass it to <TT>ReadComponent</TT>
so that its properties will be lifted from the stream.</P>
<P>In the last few pages, you had a good 
look at the Widget2 program. There are several
additional traits of properties that should be explored, however, before moving on
to the colorful warehouse simulation found in the next chapter.
<H3><A NAME="Heading23"></A><FONT COLOR="#000077">More on 
Properties</FONT></H3>
<P>BCB provides support for five different types of properties:

<UL>
	<LI>Simple properties are declared to be integers, characters, or strings.
	<P>
	<LI>Enumerated properties are declared to be of some enumerated type. When 
shown
	in the Object Inspector, you can view them with a drop-down list.
	<P>
	<LI>Set properties are declared to be of type <TT>Set</TT>. <TT>BorderIcons</TT>
	from <TT>TForm</TT> is an example of this type of property. You can choose only one
	
enumerated value at a time, but you can combine several values in a property of type
	<TT>Set</TT>.
	<P>
	<LI>Object properties are declared to be of some object type, such as the <TT>Items</TT>
	property from the <TT>TListBox</TT> component, which is 
declared to be of type <TT>TStrings</TT>.
	<P>
	<LI>Array properties are like standard arrays, but you can index on any type, even
	a string. The classic example of this kind of property is the <TT>Strings</TT> property
	in a <TT>TStringList</TT>.

</UL>

<P>The PropertyTest program (in Listing 20.6) gives an example of each of the five
types of properties. It also gives the <TT>TStringList</TT> object a fairly decent
workout. The program itself is only minimally useful outside the range of a 
purely
academic setting such as this book.<BR>
<BR>
<A NAME="Heading24"></A><FONT COLOR="#000077"><B>Listing 20.6. The main unit for
the PropertyTest program.</B></FONT></P>
<PRE><FONT COLOR="#0066FF">///////////////////////////////////////

// 
Main.cpp

// Learning about properties

// Copyright (c) 1997 by Charlie Calvert

//

#include &lt;vcl\vcl.h&gt;

#pragma hdrstop

#include &quot;Main.h&quot;

#include &quot;propertyobject1.h&quot;

#pragma resource &quot;*.dfm&quot;

TForm2 *Form2;


//--------------------------------------------------------------------------

__fastcall TForm2::TForm2(TComponent* Owner)

: TForm(Owner)

{

}

//--------------------------------------------------------------------------

void __fastcall 
TForm2::bCreateObjectsClick(TObject *Sender)

{

  TMyProps *M;

  char Ch;

  int i;

  M = new TMyProps(this);

  M-&gt;Parent = this;

  M-&gt;SimpleProp = 25;

  M-&gt;EnumProp = teEnum;

  M-&gt;SetProp = TSetProp() &lt;&lt; teEnum &lt;&lt; 
teSet;

  M-&gt;StrArrayProp[&quot;Jones&quot;] = &quot;Sam, Mary&quot;;

  M-&gt;StrArrayProp[&quot;Doe&quot;] = &quot;John, Johanna&quot;;

  ListBox1-&gt;Items-&gt;Add(M-&gt;StrArrayProp[&quot;Doe&quot;]);

  
ListBox1-&gt;Items-&gt;Add(M-&gt;StrArrayProp[&quot;Jones&quot;]);

  for (i = 0; i &lt; M-&gt;ObjectProp-&gt;Count; i++)

    ListBox2-&gt;Items-&gt;Add(M-&gt;ArrayProp[i]);

  Ch = M-&gt;Default1;

  ListBox1-&gt;Items-&gt;Add(Ch);

}




</FONT></PRE>
<P><A NAME="Heading25"></A><FONT COLOR="#000077"><B>Listing 20.7. The header file
for the PropertyObject unit.</B></FONT></P>
<PRE><FONT COLOR="#0066FF">///////////////////////////////////////

// PropertyObject.h

// Learning about 
properties

// Copyright (c) 1997 by Charlie Calvert

//

#ifndef PropertyObject1H

#define PropertyObject1H

enum TEnumType {teSimple, teEnum, teSet, teObject, teArray};

typedef Set&lt;TEnumType, teSimple, teArray&gt; TSetProp;

  class TCouple: 
public TObject

  {

  public:

    AnsiString Husband;

    AnsiString Wife;

    TCouple() {}

  };

  class TMyProps: public TCustomControl

  {

  private:

    int FSimple;

    TEnumType FEnumType;

    TSetProp FSetProp;

    TStringList 
*FObjectProp;

    char FDefault1;

    AnsiString __fastcall GetArray(int Index);

    AnsiString __fastcall GetStrArray(AnsiString S);

    void SetStrArray(AnsiString Index, AnsiString S);

  protected:

    void virtual __fastcall Paint();

  
public:

    virtual __fastcall TMyProps(TComponent *AOwner);

    virtual __fastcall ~TMyProps();

    __property AnsiString ArrayProp[int i]={read=GetArray};

    __property AnsiString StrArrayProp[AnsiString i]=

      
{read=GetStrArray,write=SetStrArray};

  __published:

    __property int SimpleProp={read=FSimple, write=FSimple};

    __property TEnumType EnumProp={read=FEnumType, write=FEnumType};

    __property TSetProp SetProp={read=FSetProp, write=FSetProp};

    
__property TStringList *ObjectProp={read=FObjectProp, write=FObjectProp};

    __property char Default1={read=FDefault1, write=FDefault1, default= `1'};

  };

#endif



</FONT></PRE>
<P><A NAME="Heading26"></A><FONT COLOR="#000077"><B>Listing 20.8. 
The source for
the PropertyTest unit shows how to work with properties.</B></FONT></P>
<PRE><FONT COLOR="#0066FF">///////////////////////////////////////

// PropertyObject.cpp

// Learning about properties

// Copyright (c) 1997 by Charlie Calvert


//

#include &lt;vcl\vcl.h&gt;

#pragma hdrstop

#include &quot;PropertyObject1.h&quot;

#include &quot;codebox.h&quot;

__fastcall TMyProps::TMyProps(TComponent *AOwner)

 :TCustomControl(AOwner)

{

  Width = 100;

  Height = 100;

  Left = 
(((TForm*)(AOwner))-&gt;ClientWidth / 2) - (Width / 2);

  Top = (((TForm*)(AOwner))-&gt;ClientHeight / 2) - (Height / 2);

  FObjectProp = new TStringList();

  Default1 = `1';

};

__fastcall TMyProps::~TMyProps()

{

  int i;

  for (i = 0; i &lt; 
FObjectProp-&gt;Count; i++)

  {

    FObjectProp-&gt;Objects[i]-&gt;Free();

  }

  FObjectProp-&gt;Free();

}

void __fastcall TMyProps::Paint()

{

  Canvas-&gt;Brush-&gt;Color = clBlue;

  TCustomControl::Paint();

  Canvas-&gt;Rectangle(0, 0, 
Width, Height);

  Canvas-&gt;TextOut(1, 1, &quot;FSimple: &quot; + IntToStr(FSimple));

  Canvas-&gt;TextOut(1, Canvas-&gt;TextHeight(&quot;Blaise&quot;), GetArray(0));

  Canvas-&gt;TextOut(1, Canvas-&gt;TextHeight(&quot;Blaise&quot;) * 2, 
FObjectProp-&gt;Strings[1]);

};

AnsiString __fastcall TMyProps::GetArray(int Index)

{

  return FObjectProp-&gt;Strings[Index];

}

AnsiString __fastcall TMyProps::GetStrArray(AnsiString S)

{

  TCouple *Couple;

  Couple = 
(TCouple*)(FObjectProp-&gt;Objects[FObjectProp-&gt;IndexOf(S)]);

  return Couple-&gt;Husband + &quot;, &quot; + Couple-&gt;Wife;

}

AnsiString GetHusband(AnsiString S)

{

  return StripLastToken(S, `,');

}

AnsiString GetWife(AnsiString S)

{

  
return StripFirstToken(S, `,');

}

void TMyProps::SetStrArray(AnsiString Index, AnsiString S)

{

  TCouple *Couple;

  Couple = new TCouple();

  Couple-&gt;Husband = GetHusband(S);

  Couple-&gt;Wife = GetWife(S);

  
FObjectProp-&gt;AddObject(Index, Couple);

}

</FONT></PRE>
<P>The structure of the PropertyTest program is simple. There is a main form with
a button on it. If you click the button, you instantiate an object of type <TT>TMyObject</TT>,
as shown in 
Figure 20.3.<BR>
<BR>
<A NAME="Heading27"></A><A HREF="20ebu03.jpg" tppabs="http://pbs.mcp.com/ebooks/0672310228/art/20/20ebu03.jpg">FIGURE 20.3.</A><FONT COLOR="#000077">
</FONT><I>The main form of the PropertyTest program.</I></P>
<P><TT>TMyObject</TT> has five properties, one for each of the major types 
of properties.
These properties have self-explanatory names:</P>
<PRE><FONT COLOR="#0066FF">__property int SimpleProp={read=FSimple, write=FSimple};

__property TEnumType EnumProp={read=FEnumType, write=FEnumType};

__property TSetProp 
SetProp={read=FSetProp, write=FSetProp};

__property TStringList *ObjectProp={read=FObjectProp, write=FObjectProp};

__property AnsiString ArrayProp[int i]={read=GetArray};

</FONT></PRE>
<P>Before exploring these properties, I should mention that 
<TT>TMyProps</TT> is
descended from the native VCL object called <TT>TCustomCo

⌨️ 快捷键说明

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