powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / спрятать проперть типа TStrings из секции published в секцию protected компонента
19 сообщений из 19, страница 1 из 1
спрятать проперть типа TStrings из секции published в секцию protected компонента
    #39761701
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
проблема в совместимости с предыдущими версиями.
изначально было:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
TSomeComp = class(TComponet)
private
  FList: TStrings;
  ...
published
  property MyList: TStrings read FList write FList;
  ...
end;

понадобилось спрятать эту проперть внутрь protected, но так чтоб сохранённые в DFM'е свойства таки читались.
примерно так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
TSomeComp = class(TComponet)
private
  FList: TStrings;
  procedure ReadList(Reader: TReader);
  procedure WriteList(Writer: TWriter);

  ...
protected
  procedure DefineProperties(Filer: TFiler); override;
  property MyList: TStrings read FList write FList stored True;
published
  ...
end;

procedure TSomeComp.DefineProperties(Filer: TFiler);

  function DoWrite: Boolean;
  begin
    if Filer.Ancestor <> nil then
      begin
        Result := True;
        if Filer.Ancestor is TStrings then
          Result := not FList.Equals(TStrings(Filer.Ancestor))
      end
    else
      Result := FList.Count > 0;
  end;

begin
  inherited DefineProperties(Filer);
  Filer.DefineProperty('MyList', ReadList, WriteList, DoWrite);
end;

procedure TSomeComp.ReadList(Reader: TReader);
begin
  Reader.ReadListBegin;
  with FList do
    begin
      BeginUpdate;
      try
        Clear;
        while not Reader.EndOfList do
          Add(Reader.ReadString);
      finally
        EndUpdate;
      end;
    end;
  Reader.ReadListEnd;
end;

procedure TSomeComp.WriteList(Writer: TWriter);
var
  I: Integer;
begin
  Writer.WriteListBegin;
  with FList do
    for I := 0 to Count - 1 do
      Writer.WriteString(Strings[I]);
  Writer.WriteListEnd;
end;


НО!
старый вариант компонента писал в DFM таким макаром:
Код: sql
1.
2.
3.
4.
5.
object TSomeComp1: TSomeComp
    Params.Strings = (
      '1'
      '2')
  end

а вот новый пишет:
Код: sql
1.
2.
3.
4.
5.
object TSomeComp1: TSomeComp
    Params = (
      '1'
      '2')
  end



есть мысли, как победить?
...
Рейтинг: 0 / 0
спрятать проперть типа TStrings из секции published в секцию protected компонента
    #39761706
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
 Filer.DefineProperty('MyList.Strings', ReadList, WriteList, DoWrite);


???
...
Рейтинг: 0 / 0
спрятать проперть типа TStrings из секции published в секцию protected компонента
    #39761756
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Код: pascal
1.
 Filer.DefineProperty('MyList.Strings', ReadList, WriteList, DoWrite);


???
Думаешь это сработает ?
Код: pascal
1.
2.
3.
4.
procedure TReader.DefineProperty(const Name: string;
  ReadData: TReaderProc; WriteData: TWriterProc; HasData: Boolean);
begin
  if SameText(Name, FPropName) and Assigned(ReadData) then
...
Рейтинг: 0 / 0
спрятать проперть типа TStrings из секции published в секцию protected компонента
    #39761765
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
while True do
      begin
        J := I;
        while (I <= L) and (PropPath[I] <> '.') do Inc(I);
        FPropName := Copy(PropPath, J, I - J);
        if I > L then Break;
// Если свойство составное (то есть с точкой), то выделяем первую его часть (до точки) (а в дальнейшем и дальше)
// и находим её тип через GetPropInfo

        PropInfo := GetPropInfo(Instance.ClassInfo, FPropName);
        if PropInfo = nil then
          PropertyError(FPropName);
// Если перенести проперти в PROTECTED, то тут будет валиться при чтении и до DefineProperties дело не дойдёт

        PropValue := nil;
        if PropInfo^.PropType^.Kind = tkClass then
          PropValue := TObject(GetOrdProp(Instance, PropInfo));
        if not (PropValue is TPersistent) then PropPathError;
        Instance := TPersistent(PropValue);
        Inc(I);
      end;
      PropInfo := GetPropInfo(Instance.ClassInfo, FPropName);
      if PropInfo <> nil then ReadPropValue(Instance, PropInfo) else
      begin
        { Cannot reliably recover from an error in a defined property }
        FCanHandleExcepts := False;
        Instance.DefineProperties(Self);
...
Рейтинг: 0 / 0
спрятать проперть типа TStrings из секции published в секцию protected компонента
    #39761772
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хотя в поздних версиях механизм чтения переделали и это работатет
Код: pascal
1.
Filer.DefineProperty('MyList.Strings', ReadList, WriteList, DoWrite);



XE2
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
      while True do
      begin
        J := I;
        while (I <= L) and (PropPath[I] <> '.') do Inc(I);
        FPropName := Copy(PropPath, J, I - J);
        if I > L then Break;
        PropInfo := GetPropInfo(Instance.ClassInfo, FPropName);
        if PropInfo = nil then
        begin
          // Call DefineProperties with the entire PropPath
          // to allow defining properties such as "Prop.SubProp"
          FPropName := PropPath;
          { Cannot reliably recover from an error in a defined property }
          FCanHandleExcepts := False;
          Instance.DefineProperties(Self);
          FCanHandleExcepts := True;
          if FPropName <> '' then
            PropertyError(FPropName);
          Exit;
        end;

...
Рейтинг: 0 / 0
спрятать проперть типа TStrings из секции published в секцию protected компонента
    #39762274
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
18.01.2019 18:39, _Vasilisk_ пишет:
> Filer.DefineProperty('MyList.Strings', ReadList, WriteList, DoWrite);

это пришло в голову в первую очередь.
но нет.
писать так можно, а вот читать - хрен.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
спрятать проперть типа TStrings из секции published в секцию protected компонента
    #39762297
Tactical Nuclear Penguin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мимопроходящий18.01.2019 18:39, _Vasilisk_ пишет:
> Filer.DefineProperty('MyList.Strings', ReadList, WriteList, DoWrite);

это пришло в голову в первую очередь.
но нет.
писать так можно, а вот читать - хрен.


тут вот есть пример с subcomponent, может поможет...
...
Рейтинг: 0 / 0
спрятать проперть типа TStrings из секции published в секцию protected компонента
    #39762310
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
21.01.2019 12:20, Tactical Nuclear Penguin пишет:
> тут вот есть пример с subcomponent, может поможет...

можно попробовать.
хотя статья не совсем о том.
идея как я понимаю такова:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
TStringsComp = class(TComponent)
private
  FList: TStrings;
published
  property Strings: TStrings read FList write FList;
end;

TSomeComp = class(TComponet)
private
  FListComp: TStringsComp;
  function GetList: TStrings;
  procedure SetList(Value: TStrings);
  ...
protected
  procedure DefineProperties(Filer: TFiler); override;
  property MyList: TStrings read GetList write SetList stored True;
published
  ...
end;



Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
спрятать проперть типа TStrings из секции published в секцию protected компонента
    #39762314
Tactical Nuclear Penguin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да, такова
...
Рейтинг: 0 / 0
спрятать проперть типа TStrings из секции published в секцию protected компонента
    #39762418
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мимопроходящий> Filer.DefineProperty('MyList.Strings', ReadList, WriteList, DoWrite);

это пришло в голову в первую очередь.
но нет.
писать так можно, а вот читать - хрен.



в XE2 работает
...
Рейтинг: 0 / 0
спрятать проперть типа TStrings из секции published в секцию protected компонента
    #39762421
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
21.01.2019 15:35, DimaBr пишет:
> + в XE2 работает

а толку то?
D7
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
спрятать проперть типа TStrings из секции published в секцию protected компонента
    #39762423
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Про Д7 я уже писал. Там механизм чтения иной.
Код: pascal
1.
2.
3.
PropInfo := GetPropInfo(Instance.ClassInfo, FPropName);
if PropInfo = nil then
   PropertyError(FPropName);
...
Рейтинг: 0 / 0
спрятать проперть типа TStrings из секции published в секцию protected компонента
    #39762424
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
То есть исходя из имеющегося метода чтения Params - должен быть PUBLISHED
...
Рейтинг: 0 / 0
спрятать проперть типа TStrings из секции published в секцию protected компонента
    #39762426
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
21.01.2019 15:44, DimaBr пишет:
> То есть исходя из имеющегося метода чтения Params - должен быть PUBLISHED

вот посему и возник этот топег...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
спрятать проперть типа TStrings из секции published в секцию protected компонента
    #39762436
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может так ???
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
type
THackComp = class(TComponent);
TMyReader = class(TReader)
  procedure MyReadProperty(AInstance: TPersistent);
  procedure MyReadDataInner(Instance: TComponent);
end;

{ TMyReader }

procedure TMyReader.MyReadDataInner(Instance: TComponent);
var
  OldParent, OldOwner: TComponent;
begin
  while not EndOfList do MyReadProperty(Instance);
  ReadListEnd;
  OldParent := Parent;
  OldOwner := Owner;
  Parent := THackComp(Instance).GetChildParent;
  try
    Owner := THackComp(Instance).GetChildOwner;
    if not Assigned(Owner) then Owner := Root;
    while not EndOfList do ReadComponent(nil);
    ReadListEnd;
  finally
    Parent := OldParent;
    Owner := OldOwner;
  end;
end;

procedure TMyReader.MyReadProperty(AInstance: TPersistent);
var PropPath: string;
    P: integer;
begin
  P := Position;
  PropPath := ReadStr;
  if PropPath = 'MyList.Strings' then begin
// читаем как нужно
  end
  else begin
    Position := P;
    ReadProperty(AInstance);
  end;
end;

procedure TSomeComp.ReadState(Reader: TReader);
begin
//  inherited;
  TMyReader(Reader).MyReadDataInner(self);
end;
...
Рейтинг: 0 / 0
спрятать проперть типа TStrings из секции published в секцию protected компонента
    #39762437
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
21.01.2019 16:13, DimaBr пишет:
> Может так ???

маниак! :-)
хорошая идея.
СПАСИБО.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
спрятать проперть типа TStrings из секции published в секцию protected компонента
    #39762446
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Правильнее конечно создать свой Reader, а не хакать имеющейся
...
Рейтинг: 0 / 0
спрятать проперть типа TStrings из секции published в секцию protected компонента
    #39763724
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
работает под D7
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
procedure TMyReader.MyReadDataInner(Instance: TComponent);
var
  OldParent, OldOwner: TComponent;
begin
  while not EndOfList do ReadPropertyXE(Instance);
  ReadListEnd;
  OldParent := Parent;
  OldOwner := Owner;
  Parent := THackComp(Instance).GetChildParent;
  try
    Owner := THackComp(Instance).GetChildOwner;
    if not Assigned(Owner) then Owner := Root;
    while not EndOfList do ReadComponent(nil);
    ReadListEnd;
  finally
    Parent := OldParent;
    Owner := OldOwner;
  end;
end;

// скопировал с XE2
procedure TMyReader.ReadPropertyXE(AInstance: TPersistent);
var
  I, J, L: Integer;
  Instance: TPersistent;
  PropInfo: PPropInfo;
  PropValue: TObject;
  PropPath: string;

  procedure HandleException(E: Exception);
  var
    Name: string;
  begin
    Name := '';
    if AInstance is TComponent then
      Name := TComponent(AInstance).Name;
    if Name = '' then Name := AInstance.ClassName;
    raise EReadError.CreateResFmt(@SPropertyException, [Name, DotSep, PropPath, E.Message]);
  end;

  procedure PropPathError;
  begin
    SkipValue;
    raise EReadError.CreateRes(@SInvalidPropertyPath);
  end;

var P: Pointer;
begin
  try
    PropPath := ReadStr;
    try
      I := 1;
      L := Length(PropPath);
      Instance := AInstance;

      PBoolean(@(CanHandleExceptions))^ := true; // пишем в ReadOnly свойство
      while True do
      begin
        J := I;
        while (I <= L) and (PropPath[I] <> '.') do Inc(I);
        PString(@(PropName))^ := Copy(PropPath, J, I - J);
        if I > L then Break;
        PropInfo := GetPropInfo(Instance.ClassInfo, PropName);
        if PropInfo = nil then
        begin
          // Call DefineProperties with the entire PropPath
          // to allow defining properties such as "Prop.SubProp"
          PString(@(PropName))^ := PropPath;
          { Cannot reliably recover from an error in a defined property }
          PBoolean(@(CanHandleExceptions))^ := False;
          THackComp(Instance).DefineProperties(Self);
          PBoolean(@(CanHandleExceptions))^ := True;
          if PropName <> '' then
            PropertyError(PropName);
          Exit;
        end;
        PropValue := nil;
        if PropInfo^.PropType^.Kind = tkClass then
          PropValue := TObject(GetOrdProp(Instance, PropInfo));
        if not (PropValue is TPersistent) then PropPathError;
        Instance := TPersistent(PropValue);
        Inc(I);
      end;
      PropInfo := GetPropInfo(Instance.ClassInfo, PropName);
      if PropInfo <> nil then
        ReadPropValue(Instance, PropInfo)
      else
      begin
        { Cannot reliably recover from an error in a defined property }
        PBoolean(@(CanHandleExceptions))^ := False;
        THackComp(Instance).DefineProperties(Self);
        PBoolean(@(CanHandleExceptions))^ := True;
        if PropName <> '' then
          PropertyError(PropName);
      end;
    except
      on E: Exception do HandleException(E);
    end;
  except
    on E: Exception do
      if not CanHandleExceptions or not Error(E.Message) then raise;
  end;
end;

...
Рейтинг: 0 / 0
спрятать проперть типа TStrings из секции published в секцию protected компонента
    #39763768
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBrработает под D7я же говорил, что ты МАНИАК!

СПАСИБО!
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / спрятать проперть типа TStrings из секции published в секцию protected компонента
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]