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