📄 ch22.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<META NAME="Author" Content="Steph Mineart">
<TITLE>Ch 22 -- Creating Descendants of Existing
Components</TITLE>
</HEAD>
<BODY BACKGROUND="bg1.gif" tppabs="http://pbs.mcp.com/ebooks/0672310228/buttonart/bg1.gif" BGCOLOR="#FFFFFF">
<P ALIGN="CENTER"><IMG SRC="sams.gif" tppabs="http://pbs.mcp.com/ebooks/0672310228/buttonart/sams.gif" WIDTH="75" HEIGHT="24" ALIGN="BOTTOM"
BORDER="0"><BR>
<BR>
<A HREF="index-3.htm" tppabs="http://pbs.mcp.com/ebooks/0672310228/index.htm"><IMG SRC="toc.gif" tppabs="http://pbs.mcp.com/ebooks/0672310228/buttonart/toc.gif" WIDTH="40"
HEIGHT="40" ALIGN="BOTTOM"
ALT="TOC" BORDER="0" NAME="toc4"></A><A HREF="ch21.htm" tppabs="http://pbs.mcp.com/ebooks/0672310228/ch21.htm"><IMG SRC="back-1.gif" tppabs="http://pbs.mcp.com/ebooks/0672310228/buttonart/back.gif"
WIDTH="40" HEIGHT="40" ALIGN="BOTTOM" ALT="BACK" BORDER="0" NAME="toc1"></A><A HREF="ch23.htm" tppabs="http://pbs.mcp.com/ebooks/0672310228/ch23.htm"><IMG
SRC="forward.gif" tppabs="http://pbs.mcp.com/ebooks/0672310228/buttonart/forward.gif" WIDTH="40"
HEIGHT="40" ALIGN="BOTTOM" ALT="FORWARD" BORDER="0"
NAME="toc2"></A></P>
<H2 ALIGN="CENTER"><FONT COLOR="#000077">Charlie Calvert's C++ Builder Unleashed</FONT></H2>
<P>
<H1 ALIGN="CENTER"><FONT COLOR="#000077">- 22 -<BR>
Creating Descendants of
Existing Components</FONT></H1>
<H2><FONT COLOR="#000077"><BR>
Overview</FONT></H2>
<P>This chapter and the next two cover building components. Component development
is one of the most important technologies in contemporary programming, and no C++
environment on the market makes them easier to use or to create than BCB.</P>
<P>You build three types of components in this chapter:
<UL>
<LI>Descendants that change default settings in existing components.
<P>
<LI>Descendants that add features
to existing components.
<P>
<LI>Tools built on top of abstract component base classes such as <TT>TWinControl</TT>,
<TT>TCustomControl</TT>, <TT>TComponent</TT>, and <TT>TGraphicControl</TT>. You make
descendants from these classes if you want to
build your own components from the
bottom up.
</UL>
<P>This chapter presents material on building visual components, Chapter 23 focuses
on building unique components that are polymorphic, and Chapter 24 explores building
nonvisual components.
Nonvisual components descend directly from <TT>TComponent</TT>
and appear on the form only at design time.</P>
<P>More specifically, the components built in this chapter fall into two categories:
<UL>
<LI>The first group is a set of <TT>TEdit</TT>,
<TT>TLabel</TT>, and <TT>TPanel</TT>
descendants that show how to change default colors, captions, and fonts. This section
of the chapter also covers building components that consist of several different
child components; that is, this section
shows how to group components together to
form new components. The specific example included with this book shows a panel that
comes with two radio buttons.
<P>
<LI>The second tool is a clock component that can be dropped on a form, and stopped
and started at will.
</UL>
<P>In Chapter 24, you will see a nonvisual control that knows how to iterate through
subdirectories. You can use it to build programs that search for files, delete all
files with a certain extension, and so on.</P>
<P>Besides components, this chapter also briefly covers two related topics: Property
editors are used to edit the properties of components. The classic examples are the
common dialogs that pop up when you edit the <TT>Color</TT> or <TT>Font</TT>
properties
that belong to most visible components. The drop-down lists and string-editing capabilities
found in the Object Inspector are also property editors.
<DL>
<DD>Component editors are associated not with a single property, but with an entire
component. An example is the Fields Editor used with the <TT>TTable</TT> and <TT>TQuery</TT>
components.
</DL>
<P>The property editors and component editors are related to a broader topic called
the Tools API. The Tools API consists of a series of
interfaces to the BCB IDE that
allows you to build experts, interfaces to version control systems, and similar utilities.
The API for property editors and component editors and the Tools API are defined
in files with names that end in <TT>INTF</TT>,
which stands for "Interface."
For example, the <TT>TPropertyEditor</TT> class is found in <TT>DSGNINTF.HPP</TT>.</P>
<P>Components, properties, and events, along with their associated component editors
and property editors are perhaps the
most important topics in BCB programming. In
many ways, this chapter and the next two are the keystones around which this entire
book has been designed.</P>
<P>The source for all the components created in this chapter is found in the <TT>Chap22</TT>
and <TT>Utils</TT> directories on the CD that accompanies this book. The source on
the CD compiles correctly, and all of these components work as described in this
chapter. Because of the default behavior of the C++ linker, you might have to run
a
program called BuildObjs before installing some of these components. This program
is in the <TT>Utils</TT> directory. A description of this program is in the readme
file on the CD. If you have any trouble with the code in this chapter, turn to the
readme!
<H2><FONT COLOR="#000077">Component Theory</FONT></H2>
<P>BCB components have three outstanding strengths:
<UL>
<LI>They are native components, built in BCB's language, without recourse to a complicated
API such as OLE. You therefore can
write, debug, and test your components using the
same rules you use in standard BCB programs. You don't need to learn a whole new
programming model, as you do when you write ActiveX controls. In short, writing a
BCB component is about 10 times
easier than writing an OCX or VBX component.
<P>
<LI>They are fully object-oriented, which means you can easily change or enhance
existing components by creating descendant objects.
<P>
<LI>They are small, fast, and light, and can be linked
directly into your executables.
Native BCB components are orders of magnitude smaller than most ActiveX controls,
and they link directly into your programs. In particular, a native BCB component
is just a particular kind of object, so it links into
your programs naturally, just
as any other object would, without any handwaving.
</UL>
<P>Few people would claim that VBXs aren't groundbreaking, that ActiveX controls
aren't going to be very important, or that OLE2 is not an enormously promising
architecture.
However, BCB components are relatively easy to create and come in a light, easy-to-use
package. You can create BCB components that do nearly anything, from serial communications
to database links to multimedia. These capabilities give
BCB a big advantage over
other tools that force you to use large, complex, and unwieldy component models.
<DL>
<DD>
<HR>
<FONT COLOR="#000077"><B>NOTE: </B></FONT>Most publicly available components cost
in the range of $50 to $150. Many of these
tools encapsulate functionality that might
cost tens of thousands of dollars to produce in-house. For example, a good communication
library might take a year to build. However, if a company can sell the library in
volume, it can afford to charge
$100 or $200 for the same product. That's a real
bargain. And most of these tools are easy to use. Building components is a great
way for relatively small third-party companies to make money, and buying components
is a great way to save time on big
projects. These ground-breaking tools are changing
everything about the way programs are constructed.
<HR>
</DL>
<P><BR>
BCB components are flexible tools easily built by anyone who knows OOP and the BCB
language. In this package, you have
explanations detailing all the prerequisite knowledge
that component builders need, from a description of BCB itself, through a description
of its language, and on to an overview of its implementation of OOP. From this foundation,
you can easily begin
building your own components.
<H2><FONT COLOR="#000077">Creating Descendants of an Existing Component</FONT></H2>
<P>In this section, you will see how to create a series of custom <TT>TEdit</TT>,
<TT>TPanel</TT>, and <TT>TLabel</TT> controls. The
changes made to the standard <TT>TEdit</TT>
and <TT>TLabel</TT> components involve tweaking their colors, as well as their fonts'
colors, names, sizes, and styles. The goal is to show how to create a suite of custom
controls that you can place on the
Component Palette and use for special effects,
or to define the look and feel of a certain set of applications belonging to a particular
department or company.</P>
<P>With projects like this, starting with one simple example is best, and then you
can
move on to more complex components. Listings 22.1 through 22.3 contain a sample
component and a program that allows you to test the new component before you place
it on the Component Palette. The component is stored in a module called
<TT>Unleash1</TT>.
The <TT>Unleash1</TT> source code is the first version of a unit that will be expanded
later in the chapter. Scan through it and check out its basic structure. Once it
is clear to you how to create and test the component, I will
briefly discuss how
to place it on the Component Palette.
<H4><FONT COLOR="#000077">Listing 22.1. The header file for a simple component descending
from TEdit.</FONT></H4>
<PRE><FONT COLOR="#0066FF">
///////////////////////////////////////
//
Unleash1.h
// Simple example of creating a component
// Copyright (c) 1997 by Charlie Calvert
//
#ifndef Unleash1H
#define Unleash1H
//--------------------------------------------------------------------------
#include <vcl\sysutils.hpp>
#include <vcl\controls.hpp>
#include <vcl\classes.hpp>
#include <vcl\forms.hpp>
#include <vcl\StdCtrls.hpp>
//--------------------------------------------------------------------------
class TSmallEdit : public TEdit
{
private:
protected:
public:
virtual __fastcall TSmallEdit(TComponent* Owner);
__published:
};
//--------------------------------------------------------------------------
</FONT></PRE>
<P><FONT COLOR="#0066FF"><TT>#endif</TT></FONT>
<H4><FONT
COLOR="#000077">Listing 22.2. The code for a simple component descending
from TEdit.</FONT></H4>
<PRE><FONT COLOR="#0066FF">
///////////////////////////////////////
// Unleash1.cpp
// Simple example of creating a component
// Copyright (c) 1997 by
Charlie Calvert
//
#include <vcl\vcl.h>
#pragma hdrstop
#include "Unleash1.h"
//--------------------------------------------------------------------------
static inline TSmallEdit *ValidCtrCheck()
{
return new
TSmallEdit(NULL);
}
//--------------------------------------------------------------------------
__fastcall TSmallEdit::TSmallEdit(TComponent* Owner)
: TEdit(Owner)
{
Color = clBlue;
Font->Color = clYellow;
Font->Name =
"Times New Roman";
Font->Size = 12;
Font->Style = TFontStyles() << fsBold << fsItalic;
}
//--------------------------------------------------------------------------
namespace Unleash1
{
void __fastcall
Register()
{
TComponentClass classes[1] = {__classid(TSmallEdit)};
RegisterComponents("Unleash", classes, 0);
}
}
</FONT></PRE>
<P><FONT
COLOR="#0066FF"><TT>//--------------------------------------------------------------------------</TT></FONT>
<H4><FONT COLOR="#000077">Listing 22.3. The main form for the TestUnleash1 program
serves as a test bed for the Unleash1 unit.</FONT></H4>
<PRE><FONT COLOR="#0066FF">
///////////////////////////////////////
// Main.cpp
// Simple example of creating a component
// Copyright (c) 1997 by Charlie Calvert
//
#include <vcl\vcl.h>
#pragma hdrstop
#include "Main.h"
#include "Unleash1.h"
#pragma link "unleash1"
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TSmallEdit *MyEdit = new TSmallEdit(this);
MyEdit->Parent = this;
MyEdit->Show();
</FONT></PRE>
<P><FONT COLOR="#0066FF"><TT>}</TT> <BR>
</FONT><BR>
This program is designed to test the <TT>TSmallEdit</TT> control before you add it
to the
Component Palette. The test program has a single button that responds to clicks.
If you click the program's button, the new component appears at the top left of the
form, as shown in Figure 22.1. Once again, the goal of the program is to make sure
the
new edit control is meeting your expectations before trying to compile it as
a component.</P>
<P><A HREF="22ebu01.jpg" tppabs="http://pbs.mcp.com/ebooks/0672310228/art/22/22ebu01.jpg">Figure 22.1.</A><I>At runtime, the <TT>TestUnleash1</TT>
main form features a <TT>TButton</TT> and a custom <TT>Edit</TT>
control called <TT>TSmallEdit</TT>.</I></P>
<P>You can easily create this unit, test it, and compile it as a component that's
merged in with the rest of the tools on the Component Palette. To start creating
the component, choose File | New and select
Component from the first page of the
Object Repository. The dialog shown in Figure 22.2 then appears.</P>
<P><A HREF="22ebu02.jpg" tppabs="http://pbs.mcp.com/ebooks/0672310228/art/22/22ebu02.jpg">Figure 22.2.</A><I>The Component Wizard dialog.</I></P>
<P>The Component Wizard is a simple code generator, of
the type that any reader of
this book who has made it this far should be able to write in an hour or two. It
simply asks you for the name of the component you want to create and to then select
its parent from a drop-down list. After you define the
type of tool you want to create,
you can select the page in the Component Palette where you want it to reside. You
should fill in the blanks with the following information:</P>
<PRE><FONT COLOR="#0066FF">Class Name: TSmallEdit
Ancestor type: TEdit
Palette Page: Unleash
</FONT></PRE>
<P>For your efforts, the Component Expert churns out the code in Listings 22.4 and
22.5, in which everything is boilerplate except for the first line of the class declaration,
the constructor, and the parameters
passed to the <TT>RegisterComponents</TT> method.
<H4><FONT COLOR="#000077">Listing 22.4. The header produced by the standard boilerplate
output of the Component Expert.</FONT></H4>
<PRE><FONT COLOR="#0066FF">
//--------------------------------------------------------------------------
#ifndef Unleash1H
#define Unleash1H
//--------------------------------------------------------------------------
#include <vcl\sysutils.hpp>
#include
<vcl\controls.hpp>
#include <vcl\classes.hpp>
#include <vcl\forms.hpp>
#include <vcl\StdCtrls.hpp>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -