Рейтинговые книги
Читем онлайн Советы по Delphi. Версия 1.4.3 от 1.1.2001 - Валентин Озеров

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 85 86 87 88 89 90 91 92 93 ... 123

interface

uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

type TForm1 = class(TForm)

 Button1: TButton;

 procedure Button1Click(Sender: TObject);

private

 { Private declarations }

public

 { Public declarations }

 procedure myClick(Sender: TObject);

end;

var Form1: TForm1;

const i : integer = 0;

implementation

{$R *.DFM}

procedure TForm1.myClick(Sender: TObject);

begin

 with Sender as TButton do Self.Caption := ClassName + ' ' + Name;

end;

procedure TForm1.Button1Click(Sender: TObject);

begin

 with TButton.Create(self) do begin

  Left := 20;

  Top := 30 + i;

  Width := 120;

  Height := 40;

  Name := 'ThisButton' + IntToStr(i);

  Caption := 'There' + IntToStr(i);

  OnClick := MyClick; { процедура, определенная где-то еще }

  Parent := Form1;

 end; {end with}

 inc(i, 40);

end; {end button1.click}

end.

Решение для динамически создаваемых компонентов

Delphi 1

Предупреждение:

Если вы просто хотите во время выполнения приложения создавать компоненты необходимого вам типа, ознакомьтесь с файлом delphidocVB2Delph.wri и следуйте его рекомендациям, лучшего способа изучения этой темы пока не существует. Данный совет повествует об использовании в Delphi RTTI.

Во-первых, в вашем приложении необходимо зарегистрировать все классы, экземпляры которых вы собираетесь в каком-то месте кода создавать. Сделать это можно с помощью функций RegisterClass(), RegisterClasses() и RegisterClassAlias().

Пример:

procedure TForm1.FormCreate(Sender: TObject);

begin

 RegisterClasses([TButton, TEdit, TMemo, TLabel]);

end;

Это может навести вас на мысль об ограничениях, но Delphi строгий язык. Если вы хотите истинно динамическое создание объектов в слаботипизированной среде позднего связывания, используйте динамический язык типа Smalltalk. У меня есть подозрение, что Delphi использует этот механизм регистрации для регистрации всех компонентов в DCL при его запуске, позволяя этим самым создавать любой компонент во время разработки.

Создание компонентов. Используйте функцию FindClass() для получения ссылки на класс компонента, который вы хотите создать, и вызывайте его метод Create. Легко, не правда ли? В примере у меня имеется приведение типа SomeComponent к TControl, после чего я уже могу установить свойство parent (я могу делать это, поскольку я знаю, что все зарегистрированные мною классы являются потомками TControl). Для того, чтобы визуальный компонент появился на форме, вам необходимо установить свойство parent.

Пример:

procedure TForm1.CreateClick(Sender: TObject);

begin

 SomeComponent:= TComponentClass(FindClass(ClassName.Text)).Create(Self);

 (SomeComponent as TControl).Parent := Self;

end;

Теперь, когда вы имеете созданный компонент, как установить его свойства без использования самого большого блока case во вселенной? Очень просто: для получения информации о свойстве из структуры run-time type information (RTTI) используется функция GetPropInfo(), после чего для установления значений используется набор функций SetXXXXProp(). (Примечание: эти функции не задокументированы в файлах помощи Delphi. OO-программисты, как я понимаю, пользуются примерами из чужого кода и не изобретают свой велосипед.) У каждой функции SetXXXXProp() имеется функция-сателлит GetXXXXProp(), позволяющая узнать значения свойств объекта.

Пример:

procedure TForm1.SetPropertyClick(Sender: TObject);

var

 PropType: PTypeInfo;

 PropInfo: PPropInfo;

begin

 PropInfo := GetPropInfo(SomeComponent.ClassInfo, PropertyName.Text);

 PropType := PropInfo^.PropType;

 case PropType^.Kind of

 tkInteger:

  SetOrdProp(SomeComponent, PropInfo, StrToInt(PropertyValue.Text));

 tkChar:

  SetOrdProp(SomeComponent, PropInfo, Ord(PropertyValue.Text[1]));

 tkEnumeration:

  SetOrdProp(SomeComponent, PropInfo, GetEnumValue(PropType, PropertyValue.Text));

 tkFloat:

  SetFloatProp(SomeComponent, PropInfo, StrToFloat(PropertyValue.Text));

 tkString:

  SetStrProp(SomeComponent, PropInfo, PropertyValue.Text);

 end;

end;

Вы также можете установить значения свойств Set, Class и Method, но это будет немного сложнее. Немного позже я объясню как это можно сделать.

Это все. Вы проведете время с большой пользой, изучая исходный код VCL, и удивляясь, когда вы все там увидите собственными глазами.

Это прекрасный способ, но он имеет потенциал для массового злоупотребления. Необходимо понимание других путей достижения этой цели и выбор соответствующей техники при создании своих проектов в Delphi. 

Как правильно создавать органы управления в runtime?

Nomadic советует:

Примерно таким образом (Описываем метод-обработчик события OnClick формы):

{ Example }

procedure TForm1.OnClick(ASender: TObject);

var btnTemp: TButton;

begin

 { Creating }

 btnTemp := TButton.Create(Self);

 { You can use 'with btnTemp do' operator below }

 { Inserting to Form }

 btnTemp.Parent := Self;

 { Initialization }

 btnTemp.Caption := 'I''m glad to see You';

 btnTemp.SetBounds(20, 20, 80, 20);

 { You must define this event handler named 'OnBtnTempClick' }

 btnTemp.OnClick := OnBtnTempClick;

 { Ready to show }

 btnTemp.Visible := true;

 { Done. }

end

Как создать клон (копию, достаточно близкую к оригиналу) произвольного компонента?

Nomadic советует:

{ Здесь процедyра CreateClone, которая креатит компоненту ОЧЕНЬ ПОХОЖУЮ на входную. С такими же значениями свойств. Присваивается все, кроме методов. }

function CreateClone(Src: TComponent): TComponent;

var F: TStream;

begin

 F := nil;

 try

  F := TMemoryStream.Create;

  F.WriteComponent(Src);

  RegisterClass(TComponentClass(Src.ClassType));

  F.Position := 0;

  Result := F.ReadComponent(nil);

 finally

  F.Free;

 end;

end;

Как заставить произвольный компонент реагировать на изменения в TDataSource?

Nomadic советует:

TFieldDataLink. За D2 не скажу, а в D1 в Help'е его нет, реализован в DELPHISOURCEVCLDBTABLES.PAS.

type TMyForm = class(TForm)

 {…}

 Table1: TTable;

 DataSource1: TDataSource;

private

 FDL : TFieldDataLink;

 procedure RecChange(Sender: TObject);

public

 {...}

end;

procedure TMyForm.FormCreate(Sender: TObject);

begin

 FDL:=TFieldDataLink.Create;

 FDL.OnDataChange := RecChange;

 FDL.DataSource := DataSource1;

 FDL.FieldName := 'MyFieldName';

end;

procedure TTabEditDlg.FormDestroy(Sender: TObject);

begin

 FDL.Free;

end;

procedure TTabEditDlg.MasterChange(Sender: TObject);

begin

 {… тут реагируй на изменения …}

end;

За отслеживание различных событий, происходящих с TDataSource, в иерархии VCL отвечает класс TDataLink. TFieldDataLink – наследник, который выполняет маскирование событий, не относящихся к конкретному столбцу набора данных.

Если надо отслеживать изменения в любом столбце набора, используйте TDataLink. Если необходимо отслеживать события для некоторого подмножества строк набора данных, посмотрите на реализацию TGridDataLink

Доступ к другим компонентам из базового

Delphi 1 

Список-свойство Components[] существует во всех потомках TComponent и используется для хранения ссылок на все собственные компоненты. При вызове «mycomponent := TSomeComponent.Create(aComponent)», ссылка на mycomponent помещается в список aComponent Components[]. В большинстве случаев, в методе Create в качестве владельца компонентов определена форма, и ссылки на компоненты помещаются в список Components[] самой формы.

Метод FindComponent() (упомянутый где-то еще) только производит поиск компонентов в текущем списке Components[]. Если объект, который вы хотите найти, принадлежит другому компоненту, вы должны просканировать его список компонентов.

В зависимости от того, как вы создаете свою базу и другие компоненты, вы можете осуществить рекурсивный алгоритм поиска, который стартует в верхней части дерева собственника набора компонентов (вероятно, формы), спускаясь вниз и проходя по списку Components[] каждого вновь найденного компонента, пока желаемый объект не будет найден.

1 ... 85 86 87 88 89 90 91 92 93 ... 123
На этой странице вы можете бесплатно читать книгу Советы по Delphi. Версия 1.4.3 от 1.1.2001 - Валентин Озеров бесплатно.

Оставить комментарий