Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 08.10.2012, 22:22
bfrogg bfrogg вне форума
Прохожий
 
Регистрация: 08.10.2012
Сообщения: 2
Репутация: 10
По умолчанию Динамический массив из записей

Здравствуйте, помогите понять в чем проблема.

Создаю динамический массив из записей вида
Код:
type
  TPipe = record
    x, y: integer;
    concentration: real;
  end;

Объявляю его в var
Код:
var
  Form2: TForm2;
  i: integer;
  pipe: array of Tpipe;

Далее я инициализирую массив при открытии формы. N переходит из предыдущей формы и вводится пользователем.

Код:
procedure TForm2.FormCreate(Sender: TObject);
begin
  i:= 0;
  SetLength(pipe, Form1.n);
end;

Хочу сделать, чтобы при нажатии на кнопку поля x и y i-того элемента массива заполнялись значениями из edit1 и edit2.

Код:
procedure TForm2.btn1Click(Sender: TObject);
begin
  if i <= Form1.n - 1
    then
      begin
        pipe[i].x:= StrToInt(edit1.Text);
        pipe[i].y:= StrToInt(edit2.Text);
        i:= i + 1;
      end
    else
      begin
        Form3.Show;
        Form2.Hide;
      end;
end;

Программа компилируется, но при попытке присвоить значение полю x,
вылезает ошибка "pipe[i].x = Inaccessible value"
Не получается даже просто присвоить полю какую либо константу.
Ответить с цитированием
  #2  
Старый 09.10.2012, 03:07
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от bfrogg
Далее я инициализирую массив при открытии формы. N переходит из предыдущей формы и вводится пользователем.

Код:
procedure TForm2.FormCreate(Sender: TObject);
begin
  i:= 0;
  SetLength(pipe, Form1.n);
end;
Думаю ошибка здесь. FormCreate это событие не "при открытии формы", а "при создании формы". Разница существенная. А понятия "при открытии формы" даже и не существует. Есть понятия "при создании/разрушении формы" и есть "при показе/скрытии формы". Т.е. если форма создана, но скрыта (невидима), а ты ей говоришь "Show" или "Visible:=True", то она появляется, но событие FormCreate не сработает (так как форма уже была создана), а значит и не проинициализируются переменные i и pipe.

Цитата:
Сообщение от bfrogg
Программа компилируется, но при попытке присвоить значение полю x,
вылезает ошибка "pipe[i].x = Inaccessible value"
Не получается даже просто присвоить полю какую либо константу.
Поставь точку останова в этом месте и в отладчике посмотри чему равно значение переменной i и сколько элементов у массива pipe.
Или добавь программную проверку. Например так:
Код:
procedure TForm2.btn1Click(Sender: TObject);
begin
  if i <= Form1.n - 1
    then
      begin
        Assert((i>=Low(pipe)) and (i<=High(pipe)),
               'Вне диапазона! Количество элементов в массиве pipe равно '+
               IntToStr(Length(pipe))+', а переменная i равна '+IntToStr(i));
        pipe[i].x:= StrToInt(edit1.Text);
        pipe[i].y:= StrToInt(edit2.Text);
....

p.s. Также можно ещё включить проверку на выход из диапазона (в опциях проекта или директивой {$R}). Но это я написал только для полноты картины, а включать эту опцию я не рекомендую.
Ответить с цитированием
  #3  
Старый 10.10.2012, 11:31
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,723
Репутация: 52347
По умолчанию

Цитата:
Думаю ошибка здесь. FormCreate это событие не "при открытии формы", а "при создании формы". Разница существенная. А понятия "при открытии формы" даже и не существует.
А еще есть событие FormActivate. Его можно в принципе воспринимать как "открытие формы" .
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #4  
Старый 10.10.2012, 14:35
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Страдалецъ
А еще есть событие FormActivate. Его можно в принципе воспринимать как "открытие формы" .
Вряд ли событие FormActivate можно воспринимать как "открытие формы".
Смысл событий OnActivate/OnDeactivate у формы заключается только в том, что форма активировалась или деактивировалась, ни какого отношения к открытию и закрытию эти события не имееют.
Если у приложения есть формы, то одна и только одна из этих форм должна быть активной. Какая форма активна в данный момент можно узнать из свойства Screen.ActiveForm.
К примеру если у приложения открыто на экране 10 форм, то одна из них обязательно будет активной. Если кликнуть по любой неактивной форме, то в активной форме произойдёт событие OnDeactivate, а у той по которой кликнули произойдёт событие OnActivate.
Т.е. эти события означали просто, что одна форма деактивировалась в то время как другая активировалась. Вот и всё, никаких открытий/закрытий форм при этом не происходило.
Ответить с цитированием
  #5  
Старый 10.10.2012, 22:33
bfrogg bfrogg вне форума
Прохожий
 
Регистрация: 08.10.2012
Сообщения: 2
Репутация: 10
По умолчанию

Большое спасибо за ответ!

Проблема действительно в этом. Когда я провожу инициализацию при нажатии на кнопку все работает. Но как сделать, чтобы инициализация проходила без участия пользователя? Кроме обработки события OnCreate, я не знаю как делать.

Проблема решена: инициализирую массив в первой форме, нажатием на кнопку))

Последний раз редактировалось bfrogg, 10.10.2012 в 22:46.
Ответить с цитированием
  #6  
Старый 11.10.2012, 10:29
Аватар для ~TB~
~TB~ ~TB~ вне форума
Начинающий
 
Регистрация: 17.02.2006
Адрес: Казахстан
Сообщения: 172
Версия Delphi: XE
Репутация: 1500
По умолчанию

Еще можно при создании формы создать одноразовый таймер, который инициализирует все, что надо, как только форма будет создана. Главное не забыть подтереть за собой его. Самый простой способ для решения задач подобного класса, хоть и не самый красивый.
__________________
00110001 00101100 00110110 00110001 00111000 00110000 00110011 00110011 00111001 00111000 00111000 00110111 00110100 00111001 00111000 00111001 00110100 00111000 00110100 00111000 00110010 00110000 00110100 00110101 00111000 00110110 00111000 00110011 00110100 00110011 00110110 00110101 00110110
Ответить с цитированием
  #7  
Старый 11.10.2012, 10:40
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от ~TB~
Еще можно при создании формы создать одноразовый таймер, который инициализирует все, что надо, как только форма будет создана. Главное не забыть подтереть за собой его. Самый простой способ для решения задач подобного класса, хоть и не самый красивый.
Я ещё иногда делаю одноразовый обработчик сообщений и в OnCreate формы посылаю это сообщение ей же (через PostMessage конечно же, а не через SendMessage ), а когда форма будет создана, она обработает это сообщение в обработчике которого я инициализирую всё что нужно.
Ответить с цитированием
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение:
~TB~ (11.10.2012)
  #8  
Старый 11.10.2012, 12:02
Аватар для ~TB~
~TB~ ~TB~ вне форума
Начинающий
 
Регистрация: 17.02.2006
Адрес: Казахстан
Сообщения: 172
Версия Delphi: XE
Репутация: 1500
По умолчанию

Цитата:
Сообщение от poli-smen
Я ещё иногда делаю одноразовый обработчик сообщений и в OnCreate формы посылаю это сообщение ей же (через PostMessage конечно же, а не через SendMessage ), а когда форма будет создана, она обработает это сообщение в обработчике которого я инициализирую всё что нужно.

Ну так еще лучше. И поэлегантнее.
__________________
00110001 00101100 00110110 00110001 00111000 00110000 00110011 00110011 00111001 00111000 00111000 00110111 00110100 00111001 00111000 00111001 00110100 00111000 00110100 00111000 00110010 00110000 00110100 00110101 00111000 00110110 00111000 00110011 00110100 00110011 00110110 00110101 00110110
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 20:07.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025