Написать компонент для Delphi
Оформил: DeeCo
Кнопка-счетчик
Невидимый
компонент
Delphi среда в основе которой лежат компоненты. Идея заключается в том,
что бы не писать часто-используемый код самому, а воспользоваться
компонентом, который инкапсулирует этот код. Т.е. он отделяет интерфейсную
часть от части реализации.
Большенство пользователей Delphi пользуются (иногда весьма успешно)
компонентами, но еденици могут их создавать. Это вообщем правильно - на то
Дельфи...
Здесь мы рассмотрим написание двух компонентов: очень простого кнопки-счетчика
и чуть посложнее невидемый компонент который соберает информацию о
компьютере (основную конечно).
Здесь исходные тексты с подробными
коментариями.
Кнопка-счетчик
Этот простой компонент, только пример, но используя эти приемы можно
конструировать простые компоненты. Компонент представляет собой кнопку при
нажатии на которую счетчик увеличивается на 1.
unit MyUnit; //Сохраним наш файл под именем
myunit.pas
interface
uses WinTypes, WinProcs, Messages, SysUtils, Classes,
Controls, Forms, Graphics, Stdctrls;
type
{TMyButton - класс компонента который мы создаем,
его предком является TButton. Наш компонет наследует все его методы,
свойства и события.} TMyButton = class(TButton)
private
{Переменная контейнер для свойства Counter она
изменяется каждый раз как изменяется свойство counter} FCounter
: Integer;
protected
{Метод Click ,будет переопределен. именно он
вызывается каждый раз как пользователь щелкает мышкой по кнопке. Но
заметте, что он располагается в секции protect. Т.е. этот метод будет
доступен только внутри реализации TMyButton.} procedure Click; override;
public
published
{Именно это свойство будет доступно через инспектор
объектов. Там вы его можете изменить.} property Counter:
Integer read FCounter write FCounter;
end;
{Это служебная процедура для IDE Delphi. Она
регистрирует компонент в палитре компонентов.} procedure Register;
implementation
procedure Register;
begin
{Это служебная процедура для IDE Delphi. Она
регистрирует компонент в палитре компонентов.Standart-вкладка палитры
компонетовTMyButton-какой именно компонент мы регистрируем (в одном
модуле их может быть несколько.)} RegisterComponents('Standard',
[TMyButton]);
end;
procedure TMyButton.Click;
begin
{Выполним метод Click класса
предка.} inherited Click;
{Увеличим свойство Counter на еденицу, это
эквивалентно FCounter:=FCounter+1;} inc(FCounter);
{Отобразим это
изменение.} Caption := IntToStr(FCounter);
end;
end.
Следующий компонент невидимый. он инкапсулирует часть кода WinApi.
Предком компонента является TComponent. Добавлено три published
свойства:
property MachineName: string; // Имя машины
(оно вводится, как правило, при установке
windows)property UserName: string;
// Имя пользователя который в данный момент
работаетproperty WinSysDir: string;
// Имя папки windows где она хранит свои DLLки (обычно это
"c: \windows\system")
Хотя этот компонент и демонстрационный он вполне работоспособен и может
применяться в проектах. Преимущества использования здесь очевидны. Кроме
того, что все эти свойства предоставляют необходимую информацию о машине
их можно посмотреть в инспекторе объектов на стадии выполнения. Моменты
которые были риссмотреныв предыдущем примере здесь рассматриваться не
будут. Все места на которые следует обратить внимание будут выделены
цветом.
Невидимый компонент
unit SystemInfo;
interface
usesWindows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs, registry;
typeTSystemInfo =
class(TComponent)private
{Объявлены
переменные-контейнеры} FMachine, FUser, FWinSysDir: string;
protected
{Функции которые и "выясняют" все интересующие
нас параметры. Они нужны для удобства и наглядности, хотя без них
можно было обойтись.} function GetMachine
: string;
function GetUser: string;
function
GetWinSysDir: string;
public
{Переопределим конструктор Create. Нам нужно,
чтобы при создании компонента все параметры уже были выяснены и
занесены в переменные-контейнеры. служебное слово override означает, что этот конструктор (а по
существу это тот же метод) будет не переписан, только переопределен ну
если по русски, то переделан} constructor
Create(AOwner: TComponent); override;
published
{Определяем published свойства.property это просто ключевое слово после
которого следует имя свойства. Оно естественно должно быть уникальным.
После имени идет тип свойства. Тип свойства и тип
контейнера-переменной должен совпадать.read ключевое слово после которого следуе
переменная или функция (объявлять ее следует в private разделе) откуда свойство будет читать
значение.write свойство после которого следует
переменная-контейнер или процедура с единственным параметром. Она
будет вызываться всякий раз, когда кто-нибудь будет писать значение в
это свойство.
read и
write не обязательны, но хотябы один
должен присутствовать.} property MachineName: string
read FMachine write FMachine;
property
UserName: string read FUser write
FUser;
property WinSysDir: string read FWinSysDir
write FWinSysDir;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TSystemInfo]);
end;
constructor TSystemInfo.Create(AOwner:
TComponent);
begin
inherited; {Сначала выполним Create
предка}
{Занесем в переменные контейнеры значения имя
машины, пользователя и системную папку
windows} FMachine := GetMachine;
FUser := GetUser;
FWinSysDir := GetWinSysDir;
end;
function TSystemInfo.GetUser: string;
var
n: dword;
buf: pchar;
begin
n := 255;
buf := stralloc(n);
GetUserName(buf, n);
result := strpas(buf);
strdispose(buf);
end;
function TSystemInfo.GetMachine: string;
var
n: dword;
buf: pchar;
const
rkMachine =
'SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName';
rvMachine
= 'ComputerName';
begin
n := 255;
buf := stralloc(n);
GetComputerName(buf, n);
result := strpas(buf);
strdispose(buf);
with TRegistry.Create do
begin
rootkey := HKEY_LOCAL_MACHINE;
if OpenKey(rkMachine, false) then
beginif ValueExists(rvMachine)
thenresult := ReadString(rvMachine);
closekey;
end;
free;
end;
end;
function TSystemInfo.GetWinSysDir: string;
var
n: integer;
p: PChar;
begin
n := MAX_PATH;
p := stralloc(n);
getsystemdirectory(p, n);
Result := strpas(p);
end;
end.
|