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

Delphi Sources



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

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 19.12.2013, 11:54
Curen Curen вне форума
Прохожий
 
Регистрация: 19.12.2013
Сообщения: 9
Версия Delphi: Delphi XE2
Репутация: 10
Печаль Динамическое удаление объектов

Здравствуйте все, кто решил сюда заглянуть.
Хочу сразу сказать, что в Делфи я новичок, изучал его самостоятельно, по разным книжкам и в институтах да университетах программированию (имею ввиду программированию вообще) меня не учили. Здесь я тоже впервые. Пытался найти решение своей проблемы через поиск, но не нашел. Не только здесь, но и в интернете. Видимо, я первый с такой проблемой.

Собственно проблема вот в чем:

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

Если пользователь хочет создать новую карточку, то он нажимает на кнопки и форма должна обновиться, т.е. появляются начальные объекты на форме. Новые уже добавляются потом. Объекты находятся на панели TPanel1. При нажатии кнопки, чтобы удалить все разом, я делают так:

TPanel.free;

А потом программа динамически опять создает эту же панель и выстраивает на ней форму. Сразу скажу - если тыкать по кнопке мышью - все работает! Но начальство хочет, чтобы сие работало также при нажатии горячих клавиш. И тут проблема. Собственно процедура:
Код:
procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (ssCtrl in Shift) and (key = 78) then
  begin
    NewModul;
  end;
end;

NewModul - процедура, где находится собственно Panel1.free и другие операторы, создающие новую форму. Если форма изначальная, т.е. пользователь не успел добавить ни одного динамического объекта, то все работает. Если добавлен хоть один, то возникает ошибка:

Project nabor.exe raised exception class $C0000005 with message 'accees violation at 0x00455bab: read of address 0x00000000'

Блин, перепробовал уже наверное все, но в чем дело так и не понял. Самое интересное, что если в окне, описывающем ошибку, нажать кнопку "Continue", то программа сработает как надо. Пробовал запускать собственно exe'шник - тоже выдает окно с ошибкой, но тем не менее все срабатывает. В чем дело, может кто знает?

Последний раз редактировалось Admin, 19.12.2013 в 19:58.
Ответить с цитированием
  #2  
Старый 19.12.2013, 12:05
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

выложи минимальный проект воспроизводящий ошибку
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #3  
Старый 19.12.2013, 12:06
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Из всего вышенаписанного я не вижу проблемы. Если не допускать ошибок, то динамическое создание и уничтожение объектов работает безупречно - ошибка где-то в твоём коде - например пытаешься работать с уже уничтоженным объектом или возможно пытаешься дважды уничтожить один и тот же объект.
Хотя у тебя уже есть одна подсказка - посмотри что по адресу 0x00455bab.
Ответить с цитированием
  #4  
Старый 19.12.2013, 13:01
Curen Curen вне форума
Прохожий
 
Регистрация: 19.12.2013
Сообщения: 9
Версия Delphi: Delphi XE2
Репутация: 10
По умолчанию

Цитата:
Сообщение от NumLock
выложи минимальный проект воспроизводящий ошибку

Честно говоря, даже и не знаю, что Вам выложить, ведь уже все рассказал. В обработчике onClicke кнопки написано:
Код:
procedure TMainForm.newButtonClick(Sender: TObject);
var
Pnl : TPanel;
Rich, ObTrEd, ObTelEd : TRichEdit;
Ed : TEdit;
Bt : TButton;
TrSpBt, ObTrSpBT, TelSpBt : TSpeedButton;

begin
 Panel1.Free; //тут удаляю панель, на которой раньше находилась форма вместе со всеми объектами сразу

 Pnl := TPanel.Create(mainform); // Создаю на этой же форме эту же панель под тем же именем и теми же свойствами
 Pnl.Parent := ScrollBox1;
 Pnl.Top := 3; Pnl.Left := 3;
 Pnl.Width := 995; Pnl.Height := 294;
 Pnl.Visible := true;
 Pnl.Name := 'Panel1';
 Pnl.Caption := '';
 Pnl.BevelInner := bvNone;
 Pnl.BevelKind := bkNone;
 pnl.BevelOuter := bvNone;

 Rich := TRichEdit.Create(mainform); 
 Rich.Parent := Panel1; ... // Тут уже создаю сами объекты формы на панели. Полностью выкладывать не буду, ибо много объектов, да и код очень похож
 ...
 ShapkaEdit.SetFocus; // передаю фокус первому (сверху) объекту, чтобы пользователь сразу же мог начать вводить текст
end;
Админ: Пользуемся тегами для оформления кода!

Вот, в общем-то, и все. Повторюсь - если кликать мышью по кнопке - все работает без проблем. Если использовать горячие клавиши - то выходит ошибка. Я уже было подумал, что процедуре обязательным параметром должен быть передан вызывающий его объект. Но уже чего не передавал - и саму кнопку, и форму и вообще ничего. В итоге запулил все в отдельную процедуру вообще без параметров - с тем же результатом, т.е. от мыши работает, а от горячих клавиш нет. Думал еще на то, что может какой-то из удаляемых объектов находится в фокусе, так перед удалением панели менял фокус на другой объект, не находящийся на этой панели - с тем же результатом... Чё делать - не понимаю...

Последний раз редактировалось Admin, 19.12.2013 в 19:59.
Ответить с цитированием
  #5  
Старый 19.12.2013, 13:05
Curen Curen вне форума
Прохожий
 
Регистрация: 19.12.2013
Сообщения: 9
Версия Delphi: Delphi XE2
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
Из всего вышенаписанного я не вижу проблемы. Если не допускать ошибок, то динамическое создание и уничтожение объектов работает безупречно - ошибка где-то в твоём коде - например пытаешься работать с уже уничтоженным объектом или возможно пытаешься дважды уничтожить один и тот же объект.
Хотя у тебя уже есть одна подсказка - посмотри что по адресу 0x00455bab.

Я же говорю, что я еще нуб в программировании. Можешь пояснить популярно, по простому, где можно посмотреть, что находится по этому адресу, что это вообще за адрес и, заодно, как расшифровать что там написано? Или дать ссылку на то, где про это можно почитать?
Ответить с цитированием
  #6  
Старый 19.12.2013, 13:06
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

А где описание процедуры NewModul?
Ответить с цитированием
  #7  
Старый 19.12.2013, 13:13
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Curen
Я же говорю, что я еще нуб в программировании. Можешь пояснить популярно, по простому, где можно посмотреть, что находится по этому адресу, что это вообще за адрес и, заодно, как расшифровать что там написано? Или дать ссылку на то, где про это можно почитать?
Запусти приложение из под отладчика Delphi, поставь на паузу, выбери в меню "Search" -> "Go to Address", введи в поле ввода адрес $00455bab, нажми кнопку "OK" - должно перенести (если это возможно) тебя на строку которая вызвала это исключение. Наиболее вероятная ошибка вот именно в этой строке.
Ответить с цитированием
  #8  
Старый 19.12.2013, 13:19
Curen Curen вне форума
Прохожий
 
Регистрация: 19.12.2013
Сообщения: 9
Версия Delphi: Delphi XE2
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
А где описание процедуры NewModul?

Ну так все, что было в newButtonClick я в newModul и перенес. Я же говорю, что создал новую процедуру вообще без параметров, вот это она, newModul, и есть.
Ответить с цитированием
  #9  
Старый 19.12.2013, 13:28
Curen Curen вне форума
Прохожий
 
Регистрация: 19.12.2013
Сообщения: 9
Версия Delphi: Delphi XE2
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
Запусти приложение из под отладчика Delphi, поставь на паузу, выбери в меню "Search" -> "Go to Address", введи в поле ввода адрес $00455bab, нажми кнопку "OK" - должно перенести (если это возможно) тебя на строку которая вызвала это исключение. Наиболее вероятная ошибка вот именно в этой строке.

Сделал, как было сказано. Делфи выдал новое окно под названием CPU и подсветил там строчку, в которой прописано:

00455BAB 8B08 mov ecx, [eax]

Есть подозрение, что это ассемблер. Т.е. вообще для меня темный лес...
Ответить с цитированием
  #10  
Старый 19.12.2013, 13:38
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Curen
Сделал, как было сказано. Делфи выдал новое окно под названием CPU и подсветил там строчку, в которой прописано:

00455BAB 8B08 mov ecx, [eax]

Есть подозрение, что это ассемблер. Т.е. вообще для меня темный лес...
Значит этот адрес не указывает на строку с исходным кодом или исходный код не доступен для этого адреса или возможно ты после появления ошибки уже что-то изменял в программе и строка с ошибкой сместилась в другой адрес - попробуй ещё раз вызвать ошибку и если там будет указан другой адрес поищи по нему.

Цитата:
Сообщение от Curen
Ну так все, что было в newButtonClick я в newModul и перенес. Я же говорю, что создал новую процедуру вообще без параметров, вот это она, newModul, и есть.
Ну так этот код у меня не вызывает никаких ошибок ни при нажатии на кнопку ни при нажатии горячей клавиши.
Ответить с цитированием
  #11  
Старый 19.12.2013, 13:52
Curen Curen вне форума
Прохожий
 
Регистрация: 19.12.2013
Сообщения: 9
Версия Delphi: Delphi XE2
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
Значит этот адрес не указывает на строку с исходным кодом или исходный код не доступен для этого адреса или возможно ты после появления ошибки уже что-то изменял в программе и строка с ошибкой сместилась в другой адрес - попробуй ещё раз вызвать ошибку и если там будет указан другой адрес поищи по нему.

Попробовал еще раз. Тот же адрес, то же содержание...

Цитата:
Сообщение от poli-smen
Ну так этот код у меня не вызывает никаких ошибок ни при нажатии на кнопку ни при нажатии горячей клавиши.

Счас попробовал чуть по другому. Кинул на форму левую кнопку. Во время выполнения программы, перед тем, как нажать горячие клавиши, мышью передал фокус на эту кнопку. ВСЕ СРАБОТАЛО!!! Но, почему-то, когда программно пытают передать фокус на нее, опять ничего не работает... Блин... Теперь точно уверен, что дело в фокусе (каламбур, однако), но как с ним справится?
Ответить с цитированием
  #12  
Старый 19.12.2013, 13:58
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Curen
Счас попробовал чуть по другому. Кинул на форму левую кнопку. Во время выполнения программы, перед тем, как нажать горячие клавиши, мышью передал фокус на эту кнопку. ВСЕ СРАБОТАЛО!!! Но, почему-то, когда программно пытают передать фокус на нее, опять ничего не работает... Блин... Теперь точно уверен, что дело в фокусе (каламбур, однако), но как с ним справится?
У меня проблема всё ещё не воспроизводится, так что не могу сказать что не так в твоём коде.
Ответить с цитированием
  #13  
Старый 19.12.2013, 14:07
Curen Curen вне форума
Прохожий
 
Регистрация: 19.12.2013
Сообщения: 9
Версия Delphi: Delphi XE2
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
У меня проблема всё ещё не воспроизводится, так что не могу сказать что не так в твоём коде.

Если Вы не против, могу попытаться отправить Вам листинг и exe'шник программы на почту. Вполне возможно что я плохо объясняю, либо что-то забыл добавить к своим словам... Если Вы дадите адрес своей почты
Ответить с цитированием
  #14  
Старый 19.12.2013, 14:20
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Curen
Если Вы не против, могу попытаться отправить Вам листинг и exe'шник программы на почту. Вполне возможно что я плохо объясняю, либо что-то забыл добавить к своим словам... Если Вы дадите адрес своей почты
Через почту не получится, выложи например на http://zalil.ru/ Только исходники, exe-шник не нужен.
Ответить с цитированием
  #15  
Старый 19.12.2013, 14:32
Curen Curen вне форума
Прохожий
 
Регистрация: 19.12.2013
Сообщения: 9
Версия Delphi: Delphi XE2
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
Через почту не получится, выложи например на http://zalil.ru/ Только исходники, exe-шник не нужен.

http://zalil.ru/34859382 - тут листинг программы в txt файле
http://zalil.ru/34859386 - на всякий случай проект полностью в архиве
Ответить с цитированием
Ответ


Delphi Sources

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

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

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

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


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


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

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

ВКонтакте   Facebook   Twitter