![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Сохранение свойств незарегистрированного компонента [D6, WinXP]
--= 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]Вы изменяете свойства панелек в дизайнере ? Каким образом представленны эти панели как свойства или через редактор ?