Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.06.2012, 00:30   #1
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
Вопрос Передача данных обьектов между 2-мя формами, через переменную

Доброго времени суток!

Имеется код, и там есть проблема.
Код:
procedure TRulesEditorForm.EditRuleBtnClick(Sender: TObject);
var
  Form: TRuleEditForm; //run-time создание 
  d: TRule;
  x: Integer;
begin
  x := RulesList.ItemIndex;
  if x <> -1 then
  begin
    d := TRule(RulesList.Items[x].Data);
    if (d <> nil) then
    begin
      d := RM.RuleByID(d.Id);
      Form := TRuleEditForm.Create(Application); //...
      try
       {
       Переменая Rule просто обьявлена в секции public у TRuleEditForm
       Она НЕ создается и НЕ уничтожается, они просто временное       вместилище данных.
       } 
       Form.Rule:=d; //Перемещаю данные в окно редактора
       {
        Открываю редактор и все данные доспны, я могу делать с ними, 
        что хочу. 
       }
        Form.ShowModal;
        if (Form.ModalResult = mrOk) then
        begin
          {
             Как вернуть новые данные назад в RM.RuleByID(d.Id):=?
          }

          RM.UpdateAll;
          RM.SaveToFile(myDir + cRulesFileName);
        end;
      finally
        Form.Free;
      end;
    end;
  end;
end;
Нет ли при таком обмене каких-нибудь утечек?

Тупняк забирает уже. Кроме тупого присвоения
RM.RuleByID(d.Id).<SameVar>:=Form.R ule.<SameVar>

Слишком много придется писать.

Ничего более умного не приходит. Может есть выход?

Последний раз редактировалось Человек_Борща; 07.06.2012 в 00:39.
Человек_Борща вне форума Ответить с цитированием
Старый 07.06.2012, 01:52   #2
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

TRule -- это класс, я надеюсь?

Код:
d := TRule(RulesList.Items[x].Data);
if (d <> nil) then
    begin
         d := RM.RuleByID(d.Id);
это зачем так? Типо RuleByID() вернёт более надёжный указатель на тот же экземпляр класса?


Цитата:
Открываю редактор и все данные доспны, я могу делать с ними,
что хочу.
..
Как вернуть новые данные назад в RM.RuleByID(d.Id):=?
данные уже там, ничего возвращать не надо.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 07.06.2012, 02:07   #3
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Код:
это зачем так? Типо RuleByID() вернёт более надёжный указатель на тот же экземпляр класса?
В целом, да.

в ListItem.Data - указатель на обьект(Сам обьект?).
Который может не соответствовать своей копии в общем списке. Ед. постоянная это id, который генерируется и присвайвается при добовлении в общий список а затем обьект помещается в поле Data.

Может я опять грабли делаю, НО Если я делаю так:
Код:
function TTargetsList.Add(aData: TTarget): boolean;
var
  LI: TListItem;
begin
  Result := False;
  if not TargetExists(aData) then
  begin
    if fVisible then
    begin
      LI := fLV.Items.Add;
      LI.Caption := aData.Name;
      LI.SubItems.Add(aData.Path);
      LI.Data := aData;
    end;
    inherited Add(aData);
    Result := True;
  end
  else
    aData.Free;
end;
LI.Data указывает или содержит обьект?



Цитата:
данные уже там, ничего возвращать не надо.
Оу.. почему все так просто? Почему?
Человек_Борща вне форума Ответить с цитированием
Старый 07.06.2012, 02:22   #4
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

Цитата:
Ед. постоянная это id
тогда можно этот id хранить в списке, а экземпляр класса получать так:

Код:
d := RM.RuleByID(  integer(RulesList.Items[x].Data)  );
далее, смотрим:

Код:
aData: TTarget
...
LI.Data := aData;
хм, в список помещаем нечто типа TTarget, а потом берем из него нечто типа TRule:

Код:
d: TRule;
...
  d := TRule(RulesList.Items[x].Data);
как оно вобще работает? Или TRule -- это наследник от TTarget (или наоборот)?

Цитата:
LI.Data указывает или содержит обьект?
все объекты -- это указатели. Например, такое присвоение, это просто присвоение указателя:

Код:
Form.Rule:=d;
т.е. Form.Rule и d указывают на одну и ту же область памяти. Если мы меняем что-то у Form.Rule, естетвенно это меняется и у d (т.к. фактически это один и тот же экземпляр). Вот, смотрите:

Код:
type
  TPerson = class
    name: string;
  end;

var
  A, B: TPerson;
begin
  A := TPerson.Create();
  A.name := 'A';
  //
  B := A;  // копируется только указатель 
  //
  B.name := 'B';
  //
  writeln(A.name); // печатает 'B', естественно
end.
так что я не помимаю, что ещё нужно куда передавать, если у вас данные и так в классе сидят.

Цитата:
почему все так просто? Почему?
так задумано.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 07.06.2012, 02:51   #5
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Вот так все выглядит:
Код:
-TRulesManager(RM)
--TRule
---TTargetsList
----TTarget
Приведенный код в 3-ем посте аналогичен для TRulesManager, и вместо TTarget там TRule.

TRulesManager список правил, каждое правило имеет список целей для которых оно работыет.
Списоц целей содержит в себе tTarget.
И список целей и список правил должны быть связаны с ListView.
Для правильного определения элемента в нивидемом списке(RM) используется идентификацтор из data-поля, где лежит указатель на данные(сами данные?), которые привязаны к этому элементу видимого списка(ListView). Суть в том, чтобы юзер работал ровно с тем, что выбрал в списке, а не так, что выбрал яблоко, а продали грушу.
Человек_Борща вне форума Ответить с цитированием
Старый 07.06.2012, 03:32   #6
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

если честно, понятней не стало, но общий смысл простой: сколько бы указателей на один и тот же объект не хранилось бы в разных местах (списках, листвьювах, листобках, whatever), все они указывают на одну и ту же область памяти.

На самом деле создать копию объекта не так-то и просто, так что я не совсем понимаю, зачем нужны какие-то дополнительные ухищрения с id.

Опять же, вот простой пример. Допустим, есть некий класс TRule, экземпляры которого мы храним в L: TList (аналог вашего RM). Добавим несколько экземпляров в список (считаем, что в конструктор передаётся id):

Код:
L.Add(TRule.Create(1));
L.Add(TRule.Create(2));
L.Add(TRule.Create(3));
Добавим их так же и в LV: TListVew:

Код:
LV.AddItem('1', L[0]);
LV.AddItem('2', L[1]);
LV.AddItem('3', L[2]);
Допустим, юзер нажал на некий элемент списка, и мы получаем экземпляр TRule:

Код:
var
  r: TRule;
begin
  r := LV.Items[LV.ItemIndex].Data;
и тут вы предлагаете для "надёжности" получить еще раз тот же самый объект, но теперь из внутреннего списка L (считаем, что метод ItemById() мы создали):

Код:
if (nil <> r) then
  r := L.ItemById(r.id);
Смысла в этом нет, т.к. оба указателя будут одинаковы.

Далее, передаём r в другую форму, где у экземпляра меняется несколько полей. Ну, к примеру:

Код:
RuleEditForm.Rule := r;
...
RuleEditForm.Rule.Name := 'New Name';
RuleEditForm.Rule.Age := 168;
Теперь вы спрашиваете, а как передать изменения в наш исходный L: TList? А они уже там, передавать нечего. Если вывести на печать (считаем, что юзер кликнул на второй элемент):

Код:
writeLn(TRule(L[1]).Name);  // 'New Name'
writeLn(TRule(L[1]).Age);  // 168
получим уже новые значения. То же самое относится и к тому, что хранится в LV: TListVew.

Т.е. никаких копий данных не создаётся (если специально этим не заниматься).
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Передача данных между формами SwitchOFF C# (си шарп) 5 13.05.2012 14:27
Передача данных между формами! MyXa Общие вопросы .NET 1 03.02.2011 18:15
Передача данных между класами Alena-b-v Общие вопросы C/C++ 3 01.09.2010 18:32
Передача данных между формами katbka Общие вопросы C/C++ 1 16.05.2010 20:45
передача данных между процедурами Неясыть Общие вопросы Delphi 15 18.11.2007 12:54