Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.07.29;
Скачать: [xml.tar.bz2];

Вниз

Access Violation при закрытии программы.   Найти похожие ветки 

 
Дельфятник   (2002-07-15 10:52) [0]

При закрытии программы закрываются окна, и когда программа пытается закрыть одно из окон, то возникают проблемы когда это окно в этот момент видимо - у этого окна по событию FormHide вызывается рисование картинки на главной форме. И выскакивает Access Violation. Я, конечно, поставил вызов перерисовки в try..except и пользователь не видит этой ошибки, но хотелось бы понять почему эта ошибка происходит. Сообщение такое:
Project prj.exe raised exception class EAccessViolation with message "Access violation at address 77F81B4D in module "ntdll.dll". Read of address 000003A0". Process stopped. Use Step or Run to Continue.
Я в отладчике нашёл строку, на которой выскакивает это сообщение. Выглядит она так:
canvas.brush.style:=bsSolid;
Чуть выше этой строки стоит with bm_w do begin, то есть Canvas относится к bm_w типа TBitmap. При этом я проверял
bm_w=nil - возвращает False,
Bm_w.Canvas=nil - возвращает False,
Bm_w.Canvas.Brush=nil - возвращает False,
Bm_w.Canvas.Brush.Style=nil - возвращает False.
В чём может быть дело?


 
Digitman   (2002-07-15 12:36) [1]

>>Bm_w.Canvas.Brush.Style=nil - возвращает False.

А вот это - нонсенс. Св-во Style не указательного типа, это - св-во типо "перечисление"


 
AL2002   (2002-07-15 13:05) [2]

try..except — и всё нормально.
canvas.brush.style:=bsSolid;
Получается, на этой строчке ошибка?
То выкинь её.


 
valery_f   (2002-07-15 13:22) [3]

> Дельфятник (15.07.02 10:52) ...При закрытии программы...

Похоже одна форма пытается обратиться ко второй, когда она уже убита (убита, а указатель остался прежним и проверка на nil, ессно, ничего не даст).

Если я правильно тебя понял, то, так чтоб по простому, - предположим Form1 - главная, а Form2 - пытается рисовать в главной при OnHide:

procedure TForm1.FormDestroy(Sender: TObject);
begin
Form1 := nil;
end;

procedure TForm2.FormHide(Sender: TObject);
begin
//а может Form1 уже не существует?
if Form1 <> nil then begin
//рисуем
Form1.Canvas...
...
end;
end;


 
Дельфятник   (2002-07-15 15:05) [4]

Для valery_f:
У меня главная форма называется fm_main, и, соответственно:

procedure TFm_main.FormDestroy(Sender: TObject);
begin
fm_main:=nil
end;

procedure TForm2.FormHide(Sender: TObject);
begin
try
if (fm_main<>nil) and fm_main.Visible then // вызов перерисовки
except
end
end;

Не помогло. Причём если сначала закрыть Form2 (вручную), а затем программу, то всё нормально. Но я же не могу этого требовать от пользователя.


 
valery_f   (2002-07-15 15:20) [5]

2 Дельфятник

Мыльни исходник, посмотрим.


 
Дельфятник   (2002-07-15 16:40) [6]

А к исходнику нужна база ~700Мб.


 
valery_f   (2002-07-15 17:00) [7]

> А к исходнику нужна база ~700Мб

Как все плохо... Если отрисовка (с возникающим AV) не связана с базой - можно скопировать проект и выкинуть базу, а если так уж сильно связана - можно в таблицах оставить 1-2 демо-записи, и будет это - считанные килобайты...

Покажи хотя-бы полный текст перерисовки в TForm2.FormHide и поясни как обе формы связаны.


 
Дельфятник   (2002-07-15 17:58) [8]

Отрисовка связана с базой - рисуются данные из базы. Кроме того база - это более 75 таблиц.
А формы связаны так - на главной форме рисуются данные из Form2 когда Form2 видима и не рисуются когда Form2 невидима. Поэтому по закрытию Form2 надо перерисовывать картинку.

Перерисовка начинается так:
begin
obj_priz_ris;
with bm_w do
begin
width:=Fm_main.width;
height:=Fm_main.height;
pen_width:=fm_main.Im1.Canvas.Pen.Width;
pen_color:=fm_main.Im1.Canvas.Pen.color;
brush_Color:=fm_main.Im1.Canvas.brush.Color;
pen_Style:=fm_main.Im1.Canvas.Pen.style;
canvas.brush.style:= bsSolid; // здесь как раз и выскакивает AV
ну и дальше прорисовка всякая

Im1: TImage - на нём всё и рисуется - сначала рисуется на bm_w, а потом в конце перерисовки bm_w копируется на fm_main.Im1:

fm_main.Im1.Canvas.draw(0,0,bm_w)


 
BAY   (2002-07-15 18:03) [9]

>Дельфятник
А пробовол запускать не под Дельфей, а напрямую exe-шник?


 
Дельфтник   (2002-07-15 18:05) [10]

Ну я ж написал, что я try..except поставил, и в результате пользователь никакого AV не видит. Соответственно, если запустить exe, то никакой ошибки не будет. Но вопрос в том, как избавиться от этой ошибки по-нормальному, а не через try..except.


 
BAY   (2002-07-15 18:10) [11]

>Дельфтник
Я имею ввиду без try..except


 
Дельфятник   (2002-07-15 18:16) [12]

2 BAY: Да, всё равно выскакивает.


 
Дельфятник   (2002-07-16 09:48) [13]

Кстати, я тут посмотрел что событие Form2.OnHide обрабатывается раньше, чем Fm_main.FormDestroy. Поэтому-то и не помог первый совет Валерия (valery_f (15.07.02 13:22)).


 
valery_f   (2002-07-16 11:45) [14]

> Дельфятник (15.07.02 17:58) ...на главной форме рисуются данные из Form2 когда Form2 видима... по закрытию Form2 надо перерисовывать картинку...

Ты хочешь сказать, что код отрисовки главной формы впаян в другую форму? Это не очень-то красиво. Каждая форма должна САМА рисовать все, что ей нужно, прочие варианты потенциально глюкавы, и, по большей части, именно в такие моменты - создание и уничтожение форм. Старайся избавляться от перекрестных ссылок и связей, а то это уже не только не ООП, но даже и не модульное программирование...

В твоем примере пока не все ясно. Для начала - кому "принадлежит" bm_w? Когда bm_w создается и когда уничтожается? Может - на момент OnHide битмапа ужет нет?

Давай так. Глянь - жив ли bm_w в момент глюка (сдается мне что таки нет), если все в порядке - замыль мне DFM и PAS для главного окна и для второй формы.


 
Дельфятник   (2002-07-17 13:53) [15]

Точно. По TFm_main.FormClose происходило bm_w.Free и обнуление массивов, из которых рисовались данные на картинке. А TFm_main.FormClose происходило до Form2.FormHide и, соответственно, выскакивала ошибка. Я закомментировал эти обнуления в TFm_main.FormClose и всё стало нормально.
Большое спасибо!



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2002.07.29;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.107 c
1-95411
NewUser
2002-07-16 12:54
2002.07.29
Поток ввода-вывода и массив


1-95448
strel
2002-07-16 20:09
2002.07.29
Ошибка при использовании DLL !!! беда :)


1-95379
maxim2
2002-07-15 20:53
2002.07.29
Можноли отловить событие MouseDown в событии MouseMove


14-95532
Alx2
2002-07-03 12:08
2002.07.29
Задачка :)


1-95333
Iren
2002-07-18 07:52
2002.07.29
Функция MessageDlg





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский