Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Сохранение свойств незарегистрированного компонента [D6, WinXP]


Страницы:   1 2

--= Eagle =-- ©   (2006-11-06 17:55:00) 

Доброго времени суток!
Есть такой вопрос: есть панельки, которые создаются на главной компоненте в дизайн-тайме, но они не зарегистрированы и регистрировать их нельзя. У форм довольно много свойств, в т. ч. PopupMenu. Если бы нужно было сохранить пару-тройку свойств я бы не заморачиваясь сделал бы это через псевдосвойства основной компоненты, но нужно сохранять почти все свойства панелек. Что посоветуете?


DimaBr   (2006-11-08 11:19:00) [1]

Если сохранять нужно не только панели, а всё остальное что брошено на Главную панель, тогда GetChildren вообще не нужен и код сокращается до
TMyChildPanel = class(TCustomPanel)
protected
  procedure SetParent(AParent: TWinControl);override;
end;

TMyPanel = class(TCustomPanel)
end;


DimaBr   (2006-11-08 09:27:00) [2]


unit TestPanel;

interface
uses Classes,ExtCtrls,SysUtils, Controls;

type
TMyChildPanel = class(TCustomPanel)
 protected
   procedure SetParent(AParent: TWinControl);override;
end;

TMyPanel = class(TCustomPanel)
 protected
   procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
end;

implementation

procedure TMyPanel.GetChildren( Proc: TGetChildProc; Root: TComponent );
var i: Integer;
begin
 for i := 0 to ControlCount -1 do
   if Controls[i] is TMyChildPanel then Proc( Controls[i] );
end;

{ TMyChildPanel }

procedure TMyChildPanel.SetParent(AParent: TWinControl);
begin
 if (AParent is TMyPanel) or (AParent = nil)
   then inherited
   else raise Exception.Create('Error Parent Control !');
end;

initialization
 RegisterClasses([TMyChildPanel]);

end.



unit TestReg;

interface
uses Classes, TestPanel,DesignEditors,DesignIntf;

type
TMyEditor = class(TComponentEditor)
 procedure ExecuteVerb(Index: integer); override;
 function GetVerb(Index: integer): string; override;
 function GetVerbCount: integer; override;
end;

procedure Register;

implementation

{ TMyEditor }

procedure TMyEditor.ExecuteVerb(Index: integer);
begin
 case Index of
  0: Designer.CreateComponent(TMyChildPanel,TMyPanel(Component),0,0,100,100);
  else inherited ExecuteVerb(Index);
 end;
end;

function TMyEditor.GetVerb(Index: integer): string;
begin
 case Index of
  0: Result := 'Add Panel';
  else  Result := inherited GetVerb(Index)
 end;
end;

function TMyEditor.GetVerbCount: integer;
begin
 Result := inherited GetVerbCount+1;
end;

procedure Register;
begin
 RegisterComponents('Standard',[TMyPanel]);
 RegisterComponentEditor(TMyPanel,TMyEditor);
end;

end.


Ketmar   (2006-11-07 22:44:00) [3]

>[26] --= Eagle =--(c) 7-Nov-2006, 18:37
> Ketmar, а мож харэ флудить-то, а? >-:[
может. если б я первый начал...


Юрий Зотов   (2006-11-07 20:57:00) [4]

> --= Eagle =--

Положите на форму обычную панель, а на нее - обычную кнопку. Вторую обычную кнопку положите прямо на форму. Просмотрите форму в виде текста и обратите внимание, что кнопки сохраняются в DFM по-разному.

Вам нужно добиться того же. Как это сделать - см. [17]. Еще можно в коде VCL посмотреть, как перекрыты GetChildren (а также GetParentComponent и другие соответствующие методы), например, у TMenu и TMenuItem (или у TDataSet и TField). Ключ к решению именно здесь.

А что касается "регистрировать их нельзя" - посмотрите RegisterNoIcon. Именно так регистрируются, например, TMenuItem, все TxxxField и другие подобные компоненты.

Другой способ - DefineProperties. Но не надо вручную перечислять все, что сохраняется, можно просто вызывать Read/WriteComponent.


Percent   (2006-11-07 19:11:00) [5]

Зарегать эти панельки? Нельзя! Они зависят от главного компонента и НЕ могут быть положены на форму...

Пусть себе зависят, какое это имеет значение?

Насчет того, что панельки "не могут быть положены" на любой другой компонент кроме главного компонента: обрабатывай SetParent(), в котором проверяй родителя, и, если он не "главный", то выдавай предупреждение (в design-time) и удаляй панельку.

То есть, регистрируй панельки - и в добрый путь!


--= Eagle =--   (2006-11-07 18:37:00) [6]

Ketmar, а мож харэ флудить-то, а? >-:[


Ketmar   (2006-11-07 18:23:00) [7]

>[24] --= Eagle =--(c) 7-Nov-2006, 18:21
> Ketmar, спроси что тебе нужно знать - и я отвечу
очень хочу знать, как работает головной мозг. подробно. полностью.


--= Eagle =--   (2006-11-07 18:21:00) [8]

Ketmar, спроси что тебе нужно знать - и я отвечу, если сам это знаю. Я к данному компоненту прикручиваю только сохранение состояния его панелек и компонентов, которые на них лежат. Вот практически и всё.
P.S. Oпубликовать исходники, естессно, не получится...


Ketmar   (2006-11-07 18:16:00) [9]

я вообще ничего не предлагаю, потому что описание задачи засекречено. я только сильно подозреваю, что там изначально что-то сделано через странное место.


--= Eagle =--   (2006-11-07 17:57:00) [10]

Ketmar, ну что ты предлагаешь? Зарегать эти панельки? Нельзя! Они зависят от главного компонента и НЕ могут быть положены на форму... Какие ещё будут советы? Пока всего кода, что я "переписывал" VCL - меньше 100 строк...


--= Eagle =--   (2006-11-07 17:52:00) [11]

Дааа... на счёт не будут загружаться я маненько обшибся... Вобщем, сделал так:

 for I := 0 to ControlCount - 1 do
 begin
   Control := Controls[I];
   if (Control.Owner = Self {Root}) then
     if (not (Control is TMyPanel)) or (csWriting in ComponentState) then
     begin
       Beep;
       Proc(Control);
     end;
 end;

Вобщем, при загрузке оно действительно не бипает, но всё же хочет загрузить компоненту, но говорит что та не зарегана, и что её можно Cancel, Ignore или Ignore all... Странно это всё...


Ketmar   (2006-11-07 17:41:00) [12]

бр-р-р. не пробовал вообще VCL переписать? тоже занятие интересное.

ну вот не понимаю я, зачем делать то, что уже сделано.


--= Eagle =--   (2006-11-07 17:07:00) [13]

т.е. я имею ввиду, что установить проперти TMyPanel-ов в те значения, которые сохранены в форме


--= Eagle =--   (2006-11-07 16:57:00) [14]

Что-то не получается... :(
Вобщем, я сделал такую вот вещь:

procedure TMyComponent.GetChildren(Proc: TGetChildProc; Root: TComponent);
var
 I: Integer;
 Control: TControl;

begin
//  inherited GetChildren(Proc, Root);
 for I := 0 to ControlCount - 1 do
 begin
   Control := Controls[I];
   if (Control.Owner = Root) and (not (Control is TMyPanel)) then Proc(Control);
 end;
{...}
end;

В результате в TMyComponent уже должны сохраняться TMyPanel и их свойства, и они не будут загружаются Делфой. Уже теплее, но это ещё не всё. Осталось загрузить свойства этой TMyPanel... Как бы это сделать?


DimaBr   (2006-11-07 14:47:00) [15]

В таком случае GetChildren, GetChildren и ещё раз GetChildren


--= Eagle =--   (2006-11-07 14:45:00) [16]

Пока делаю через DefineProperty и перечисляю всё что мне нужно будет сохранить, но это же, конечно, не выход... :(


--= Eagle =--   (2006-11-07 14:43:00) [17]

да, оно
нет, их можно добавлять/удалять в любом количестве и ещё и разными способами :D


DimaBr   (2006-11-07 14:39:00) [18]

То есть хранятся панельки в виде списка, в принципе это я уже понял
http://forum.sources.ru/index.php?showtopic=159196
Количество панелек фиксированно ?


--= Eagle =--   (2006-11-07 14:34:00) [19]

В дизайнере: Designer.SelectComponent(SomePanel) и можно изменять их свойства


DimaBr   (2006-11-07 14:09:00) [20]

Вы изменяете свойства панелек в дизайнере ? Каким образом представленны эти панели как свойства или через редактор ?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо