Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / спрятать проперть типа TStrings из секции published в секцию protected компонента / 19 сообщений из 19, страница 1 из 1
18.01.2019, 18:30
    #39761701
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
спрятать проперть типа TStrings из секции published в секцию protected компонента
проблема в совместимости с предыдущими версиями.
изначально было:
Код: 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
18.01.2019, 18:39
    #39761706
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
спрятать проперть типа TStrings из секции published в секцию protected компонента
Код: pascal
1.
 Filer.DefineProperty('MyList.Strings', ReadList, WriteList, DoWrite);


???
...
Рейтинг: 0 / 0
18.01.2019, 21:48
    #39761756
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
спрятать проперть типа TStrings из секции published в секцию protected компонента
_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
18.01.2019, 22:43
    #39761765
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
спрятать проперть типа TStrings из секции published в секцию protected компонента
Код: 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
18.01.2019, 23:17
    #39761772
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
спрятать проперть типа TStrings из секции published в секцию protected компонента
Хотя в поздних версиях механизм чтения переделали и это работатет
Код: 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
21.01.2019, 11:47
    #39762274
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
спрятать проперть типа TStrings из секции published в секцию protected компонента
18.01.2019 18:39, _Vasilisk_ пишет:
> Filer.DefineProperty('MyList.Strings', ReadList, WriteList, DoWrite);

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

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


тут вот есть пример с subcomponent, может поможет...
...
Рейтинг: 0 / 0
21.01.2019, 12:42
    #39762310
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
спрятать проперть типа TStrings из секции published в секцию protected компонента
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
21.01.2019, 12:50
    #39762314
Tactical Nuclear Penguin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
спрятать проперть типа TStrings из секции published в секцию protected компонента
да, такова
...
Рейтинг: 0 / 0
21.01.2019, 15:35
    #39762418
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
спрятать проперть типа TStrings из секции published в секцию protected компонента
Мимопроходящий> Filer.DefineProperty('MyList.Strings', ReadList, WriteList, DoWrite);

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



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

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

вот посему и возник этот топег...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
21.01.2019, 16:13
    #39762436
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
спрятать проперть типа TStrings из секции published в секцию protected компонента
Может так ???
Код: 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
21.01.2019, 16:16
    #39762437
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
спрятать проперть типа TStrings из секции published в секцию protected компонента
21.01.2019 16:13, DimaBr пишет:
> Может так ???

маниак! :-)
хорошая идея.
СПАСИБО.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
21.01.2019, 16:31
    #39762446
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
спрятать проперть типа TStrings из секции published в секцию protected компонента
Правильнее конечно создать свой Reader, а не хакать имеющейся
...
Рейтинг: 0 / 0
23.01.2019, 17:20
    #39763724
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
спрятать проперть типа TStrings из секции published в секцию protected компонента
работает под 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
23.01.2019, 17:52
    #39763768
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
спрятать проперть типа TStrings из секции published в секцию protected компонента
DimaBrработает под D7я же говорил, что ты МАНИАК!

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


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