![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Компонент не сохраняет свойства [D7, Win2k]
OlegPFR © (2005-11-22 19:26:00)В написании компонентов новичек, но надо же когда-то начинать...
Проблема в следующем: Создаю компонент TWizardFrame, созданный на основе
TFrame и содержащий в себе PageControl. В контектном меню выбираю "AddPage",
создается страница, которая в дизайнере ведет себя корректно, принимает
на себя другие компоненты (кнопки, чекбоксы, ...), НО при сохранении проекта
и его переоткрытии все исчезает - компонент TWizardFrame чистый.
Как сделать, чтобы добавленные в этот PageControl моего компонента
закладки TTabSheet сохранялись в DFM'е.
unit WizardFrame;
interface
uses
SysUtils, Classes, Controls, Forms, ExtCtrls, ComCtrls, JvExComCtrls,
JvComCtrls;
type
TWizardFrame = class(TFrame)
private
{ Private declarations }
FPageControl: TJvPageControl;
FOnMyEvent: TNotifyEvent;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
published
{ Published declarations }
property OnMyEvent: TNotifyEvent read FOnMyEvent write FOnMyEvent;
property PageControl: TJvPageControl read FPageControl write FPageControl;
end;
implementation
{$R *.dfm}
{ TWizardFrame }
constructor TWizardFrame.Create(AOwner: TComponent);
begin
inherited;
FPageControl := TJvPageControl.Create(Self);
FPageControl.Parent := Self;
FPageControl.Align := alClient;
FPageControl.Name := 'PageControl';
end;
end.
unit RegWizard;
interface
uses
SysUtils, Classes, Forms, ExtCtrls, ComCtrls,
WizardFrame;
procedure Register;
implementation
uses
Controls, Dialogs, JvPageList, JvExComCtrls, JvComCtrls, JvPageListEditorForm,
DesignIntf, DesignEditors;
type
TWizardFrameComponentEditor = class(TComponentEditor)
private
procedure InsertPage;
procedure PrevPage;
procedure NextPage;
procedure RemovePage;
function GetPageControl: TJvPageControl;//TJvCustomPageList;
public
procedure ExecuteVerb(Index: Integer); override;
function GetVerb(Index: Integer): string; override;
function GetVerbCount: Integer; override;
end;
procedure Register;
begin
RegisterClass(TWizardFrame);
RegisterComponents('Standard', [TWizardFrame]);
RegisterComponentEditor(TWizardFrame, TWizardFrameComponentEditor);
end;
{ TWizardFrameComponentEditor }
function TWizardFrameComponentEditor.GetPageControl: TJvPageControl;//TJvCustomPageList;
begin
if Component is TWizardFrame then
Result := TWizardFrame(Component).PageControl;
end;
procedure TWizardFrameComponentEditor.InsertPage;
var
C: TJvPageControl;
P: TTabSheet;
begin
C := GetPageControl;
P := TTabSheet(Designer.CreateComponent(TTabSheet, C, 0, 0, 0, 0));
P.PageControl := C;
C.ActivePage := P;
Designer.SelectComponent(C);
Designer.Modified;
end;
procedure TWizardFrameComponentEditor.ExecuteVerb(Index: Integer);
begin
case Index of
0: {PrevPage};
1: {NextPage};
2: ;
3: InsertPage;
4: {RemovePage};
end;
end;
function TWizardFrameComponentEditor.GetVerb(Index: Integer): string;
begin
case Index of
0: Result := 'Prev Page';
1: Result := 'Next Page';
2: Result := '-';
3: Result := 'Add Page';
4: Result := 'Delete Page'
else
Result := '';
end;
end;
function TWizardFrameComponentEditor.GetVerbCount: Integer;
begin
Result := 5;
end;
end.
OlegPFR (2005-11-25 15:43:00) [1]Спасибо, помогло. Интересно, а можно ли как-то бороться с глюком расположения фрейма в дизайнере (не сохраняется позиция фрейма в дизайнере при переоткрытии модуля)?
Юрий Зотов (2005-11-24 16:39:00) [2]> Как определить, что PageControl уже есть в DFM и его создавать не надо?
Например, перенести код создания из конструктора в AfterCreate, а там перед созданием проверять:
if PageControl = nil then
begin
... // создаем
end;
> там, правда, есть недостаток - форма создается без DFM'а.
Это не недостаток, это сделано специально. При генерации текста PAS в него включается директива {$R *.DFM}, а это значит, что если DFM и не было, то IDE создаст его сама.
> как создать DFM к модулю
По аналогии с генерацией текста PAS (в IOTAModuleCreator есть метод NewFormFile).
OlegPFR (2005-11-24 11:26:00) [3]Спасибо, получилось, в DFM сохраняет. Но возникла другая проблема: при переоткрытии формы PageControl создается и в Create и загружается из DFM. Как определить, что PageControl уже есть в DFM и его создавать не надо? Вообще, Frame создается из экперта, который создан по примеру CFPack Орлика, там, правда, есть недостаток - форма создается без DFM'а. Если бы знать, как создать DFM к модулю, то можно было бы обойтись без создания PageControl в конструкторе.
Юрий Зотов (2005-11-23 22:26:00) [4]Кто назначается Owner'om TabSheet'ов при их создании? PageControl?
Если Owner'om всех контролов сделать форму (как это и делается средой при их набрасывании на форму вручную), то все будет сохраняться. Даже и без SetSubComponent.
OlegPFR (2005-11-23 15:59:00) [5]Частично помогло FPageControl.SetSubComponent(True). В DFM свойства сохраняются следующим образом:
object WizardFrame1: TWizardFrame
...
PageControl.Left ...
PageControl.Top ...
end
Но добавленные с помощью TWizardFrameComponentEditor страницы TTabSheet, видимые в дизайнере, не сохраняются... Хочется видить в DFM что-то типа:
object WizardFrame1: TWizardFrame
...
object PageControl: TJvPageControl
...
object TabSheet1: TTabSheet
...
end
object TabSheet2: TTabSheet
...
end
...
end
end
Вообщем, как сделать так, чтобы созданные в дизайнере TTabSheet сохранялись в DFM'е?
Юрий Зотов (2005-11-22 20:40:00) [6]Вариант 1 - сказать, что FPageControl является подкомпонентом:
FPageControl.SetSubComponent(True);
Вариант 2 - сделать владельцем FPageControl форму . В этом случае потребуется замещение деструктора.
type
TWizardFrame = class(TFrame)
private
FPageControl: TJvPageControl;
...
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override; // !!!
published
property PageControl: TJvPageControl read FPageControl; // !!!
...
end;
constructor TWizardFrame.Create(AOwner: TComponent);
begin
inherited;
FPageControl := TJvPageControl.Create( GetParentForm(Self));
...
end;
destructor TWizardFrame.Destroy;
begin
FreeAndNil(FPageControl);
inherited
end;
И в любом случае свойство PageControl должно быть доступно только для чтения, иначе оно запросто может быть переназначено и возникнет утечка памяти.