Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.06.04;
Скачать: CL | DM;

Вниз

Компонент не сохраняет свойства   Найти похожие ветки 

 
OlegPFR   (2005-11-22 19:26) [0]

В написании компонентов новичек, но надо же когда-то начинать...
Проблема в следующем: Создаю компонент 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.



 
Юрий Зотов ©   (2005-11-22 20:40) [1]

Вариант 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 должно быть доступно только для чтения, иначе оно запросто может быть переназначено и возникнет утечка памяти.


 
OlegPFR   (2005-11-23 15:59) [2]

Частично помогло 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-23 22:26) [3]

Кто назначается Owner"om TabSheet"ов при их создании? PageControl?

Если Owner"om всех контролов сделать форму (как это и делается средой при их набрасывании на форму вручную), то все будет сохраняться. Даже и без SetSubComponent.


 
OlegPFR   (2005-11-24 11:26) [4]

Спасибо, получилось, в DFM сохраняет. Но возникла другая проблема: при переоткрытии формы PageControl создается и в Create и загружается из DFM. Как определить, что PageControl уже есть в DFM и его создавать не надо? Вообще, Frame создается из экперта, который создан по примеру CFPack Орлика, там, правда, есть недостаток - форма создается без DFM"а. Если бы знать, как создать DFM к модулю, то можно было бы обойтись без создания PageControl в конструкторе.


 
Юрий Зотов ©   (2005-11-24 16:39) [5]

> Как определить, что PageControl уже есть в DFM и его создавать не надо?

Например, перенести код создания из конструктора в AfterCreate, а там перед созданием проверять:

if PageControl = nil then
begin
  ... // создаем
end;

> там, правда, есть недостаток - форма создается без DFM"а.

Это не недостаток, это сделано специально. При генерации текста PAS в него включается директива {$R *.DFM}, а это значит, что если DFM и не было, то IDE создаст его сама.

>  как создать DFM к модулю

По аналогии с генерацией текста PAS (в IOTAModuleCreator есть метод NewFormFile).


 
OlegPFR   (2005-11-25 15:43) [6]

Спасибо, помогло. Интересно, а можно ли как-то бороться с глюком расположения фрейма в дизайнере (не сохраняется позиция фрейма в дизайнере при переоткрытии модуля)?



Страницы: 1 вся ветка

Текущий архив: 2006.06.04;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.057 c
1-1146169429
delphi-oracle
2006-04-28 00:23
2006.06.04
Как поворачивать скролл


4-1142334849
DelphiLexx
2006-03-14 14:14
2006.06.04
При нажатии клавиши передавать символ в два окна


3-1144513827
VadimSpb
2006-04-08 20:30
2006.06.04
Экспорт в Excel


2-1147893173
valduk
2006-05-17 23:12
2006.06.04
Папка


4-1141895510
msg
2006-03-09 12:11
2006.06.04
GetMessage в отдельном потоке