Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Компоненты";
Текущий архив: 2006.06.04;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.039 c
2-1148008142
not ZX
2006-05-19 07:09
2006.06.04
как получить картинку окна если оно невидно?


15-1147110984
dimodim
2006-05-08 21:56
2006.06.04
ARP Где найти полную информацию по Арп"у для сетей


3-1144923173
KyRo
2006-04-13 14:12
2006.06.04
Диалог ConnectionString


2-1147882049
Belorus
2006-05-17 20:07
2006.06.04
Как на форме показать .png файл?


1-1146105828
DF_Slayer
2006-04-27 06:43
2006.06.04
property Shape = stLine





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский