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

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

Передача данных из модельной формы в главную [D6, WinXP]


DeepProg ©   (2005-07-06 11:13:00) 

Цель: передать TStrings из модальной формы в главную. Инструкцию брал в help'e Delphi 6 (Programmnig with Delphi->Developing the Application User Interface-> Retrieving data from Modal forms). Прошу посмотерть, чтобы понять каким образом там все должно происходить.

Почему возникает Access Violation? - память не выделена? С "безразмерными" ANSI-строками это проходит нормально
Или так в принципе делать нельзя.

type
TForm1 = class(TForm)
btnNone: TButton;
lbxSelect: TListBox;
...
private
 pSelected : Pointer;
public
 constructor CreateWithList(pItems: Pointer; AOwner: TComponent); //pSelected получит значение от pItems,
//к-рое есть адрес переменной TStrings в модуле главной формы
...

procedure TForm1.btnNoneClick(Sender:TObject);
begin
TStrings(pSelected^).Add('Nothing Selected...'); //AV here
end;


Вышеприведеный код - в модуле модальной формы.

Если сделать
TStrings(pSelected^) := lbxSelect.Items;
то AccessViolation произойдет, когда я попытаюсь обратиться к переменной (в модуле главной формы), адрес которой я передавал конструктору(кстати, пришлось весь метод Create выдирать из исходников и вставлять в этот горе-конструктор чтобы форма создавалась, иначе возникала Cannot make a visible window...)


DeepProg   (2005-07-06 13:13:00) [1]

DigitmanИзвини: объект не существовал. Спасибо msguns : указал на это. Я TStrings собственно впервые пользуюсь без постоянной связи с XXXBox'ами.

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


Digitman   (2005-07-06 12:37:00) [2]


> DeepProg   (06.07.05 12:28) [7]
> Объект и существует... Для модальной формы!


а зачем тогда переменная типа TStrings в модуле вызывающей формы ?


> смотрел указанный раздел справки?


что мне на него смотреть ?)
ничего нового я там не увижу


msguns   (2005-07-06 12:32:00) [3]

>DeepProg   (06.07.05 12:28) [7]
>А главная про него знать не знает. Хочешь сказать, что это не  так?

Это как это ? Главная хочет получить то, о чем знать не знает ?


DeepProg   (2005-07-06 12:31:00) [4]

Ууу блин. Понапутали все.
DeepProg   (06.07.05 12:28) [7]  - это для Digitman(флуд в общем).


DeepProg   (2005-07-06 12:28:00) [5]

Объект и существует... Для модальной формы!
А главная про него знать не знает. Хочешь сказать, что это не  так?

p.s. ты смотрел указанный раздел справки? По-твоему это в принципе не правильно?


msguns   (2005-07-06 12:28:00) [6]

>DeepProg   (06.07.05 12:14) [4]
>Метод Add класса TStrings сам по себе дает AV. По-моему у меня что-то с системой...

Вряд ли.. Возможно, перед Add надо все же создать объект TStrings ?

Для передачи данных, введенных пользователем, из модальных (и не только) форм в главную (и не только) лучше всего использовать записи в объекте-"заказчике" (в данном случае это - главная форма) или же в датамодуле. Если "заказчик" не главная форма, то в ней создать объект-запись (через типизированный указатель и процедуру NEW) и указатель на него передать "модальной" сразу после ее креєйта, но ДО вызова ShowModal. Поинтер, естессвенно, должен быть объявлен в public модальной. Модальная запишет полученные данные в эту запись (или любой другой объект сложной структуры, достаточной для инкапсуляции данных) и закроет себя.
Инфа же будет в объекте-"заказчике", который обработает их.
В событии OnClose формы-"заказчика" надо не забыть прибить созданный объект-контейнер (Dispose и Free, если надо).


Юрий Зотов   (2005-07-06 12:23:00) [7]

> DeepProg   (06.07.05 12:14) [4]

> Есть адрес: модальная форма пишет туда, а главная - в курсе
> существования этого адреса

А перед вызовом модальной формы была ли выделена по этому адресу память нужного размера? Иначе как же модальная форма туда писать будет? Вот Вам и AV.

Соответственно, после закрытия модальной формы эту память нужно освободить, как только данные в ней станут уже не нужны.

А чтобы не заморачиваться с ручной работой и расчетом нужного объема памяти, проще сделать, как советуют: создать перед показом модальной формы экземпляр TStringList и передать его для заполнения (а когда станет уже ненужным - уничтожить.


Digitman   (2005-07-06 12:21:00) [8]


> DeepProg   (06.07.05 12:14) [4]



> Имеет.


НЕТ, не имеет !

речь идет о правильной передаче параметра некоего метода, а не модальности чего-то там !

и фактическим параметром в дан.случае д.б. переменная типа TStrings, ссылающаяся на РЕАЛЬНО существующий объект-наследник класса TStrings ... ты ведь вызываешь метод объекта (Add), значит объект должен существовать на этот момент !


DeepProg   (2005-07-06 12:14:00) [9]

Нормально...
Метод Add класса TStrings сам по себе дает AV. По-моему у меня что-то с системой...

Digitman

> p.s.
> "модальность" или "немодальность" формы НЕ имеет никакого
> отношения к сабжу

Имеет.

Ребят, я может потихоньку съезжаю с катушек, но как может главная форма получить данные из модальной вашим методом. Ведь переданная конструктору переменная не меняется.

Когда ему задавался адрес, все было логично.
Есть адрес: модальная форма пишет туда, а главная - в курсе существования этого адреса(она его и передает модальной для заполнения данными), после смерти модальной чиатет оттуда. Со строкой все просто и красиво. Как это сделать с массивом строк (да, да  я всего лишь спрашиваю, почему нехитрые операции с указателями не принесли желаемого результата)?


Плохиш   (2005-07-06 11:23:00) [10]

Замени Pointer на TStrings.


begin...end   (2005-07-06 11:22:00) [11]

type
 TForm1 = class(TForm)
   btnNone: TButton;
   ...
 private
   S: TStrings;
 public
   constructor CreateWithList(AItems: TStrings; AOwner: TComponent);
 end;

constructor TForm1.CreateWithList(AItems: TStrings; AOwner: TComponent);
begin
 Create(AOwner);
 S := AItems
end;

procedure TForm1.btnNoneClick(Sender: TObject);
begin
 S.Add('Nothing Selected...')
end


Digitman   (2005-07-06 11:21:00) [12]

type
TForm1 = class(TForm)
btnNone: TButton;
lbxSelect: TListBox;
...
private
pSelected : TStrings;
public
constructor CreateWithList(pItems: TStrings; AOwner: TComponent);

procedure TForm1.btnNoneClick(Sender:TObject);
begin
pSelected.Add('Nothing Selected...');
end;

p.s.
"модальность" или "немодальность" формы НЕ имеет никакого отношения к сабжу


Наверх

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