Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.07.29;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.017 c
3-95228
ioRaptor
2002-07-08 15:33
2002.07.29
Как записать дату


3-95212
Гас
2002-07-08 09:49
2002.07.29
Простой и красивый способ распространения проги с базой под IB


1-95443
BlackSun
2002-07-12 20:12
2002.07.29
Кэш


1-95316
KiKo
2002-07-17 17:02
2002.07.29
Измерение времени нажатия клавиши


1-95351
ilg
2002-07-18 13:07
2002.07.29
AnsiLowerCase для Char