Форум: "Начинающим";
Текущий архив: 2009.08.16;
Скачать: [xml.tar.bz2];
ВнизСтранный зависон приложения :( Найти похожие ветки
← →
b/@. © (2009-06-17 10:20) [0]Сделал форму для показа информации о программе и выводе версии.
Эта форма имеет такие особенности:
BorderStyle = bsNone
FormStyle = fsStayOnTop
также имеется таймер, для закрытия формы по интервалу
procedure TAbout.TimerTimer(Sender: TObject);
begin
Button.Click();
end;
procedure TAbout.ButtonClick(Sender: TObject);
begin
Release();
end;
и так как форма не имеет заголовка, то сделан обработчик для того, чтобы форму можно было двигать
procedure TAbout.WMNCHitTest(var Message: TWMNCHitTest);
begin
Message.Result := HTCAPTION;
end;
Но вот в чём загвоздка, когда я вывожу формуTAbout
поShowModal();
и ничего не нажимаю, или нажимаю только на кнопку, то всё отрабатывает нормально.
Но если после показа модальной формы я начинаю интенсивно таскать её мышкой по экрану, то получаю ексепшн
AV at address 00000000. Read of address 00000000.
и при этом главная форма висит и не принимает фокус, хотя часть сообщений, в часности WM_PAINT отрабатывает.
Складывается такое ощущение, что модальная форма исчезла с экрана, но тем не менее еще не закрыта.
Интуиция подсказала мне, что нужно применитьReleaseCapture();
в обработчике таймера.
При этом AV исчезло, но может нужно использовать что-то другое ?
← →
Сергей М. © (2009-06-17 10:39) [1]
> FormStyle = fsStayOnTop
А это-то зачем, если форма будет визуализироваться тобой искл-но модально ?
← →
Ega23 © (2009-06-17 10:47) [2]
procedure TAbout.ButtonClick(Sender: TObject);
begin
ModalResult := mr....; // Например, mrOK
end;
← →
Плохиш © (2009-06-17 10:50) [3]
> procedure TAbout.ButtonClick(Sender: TObject);
> begin
> Release();
> end;
>
Интересно, и чемClose
не угодило?
← →
b/@. © (2009-06-17 10:52) [4]
> Сергей М. © (17.06.09 10:39) [1]
> > FormStyle = fsStayOnTop
> А это-то зачем, если форма будет визуализироваться тобой искл-но модально ?
В этом случае модально, но не всегда...
> Ega23 © (17.06.09 10:47) [2]> procedure TAbout.ButtonClick(Sender: TObject);
> begin
> ModalResult := mr....; // Например, mrOK
> end;
Эту штуку пробовал, тем более у Button и так высталено mrOk.
← →
Нат © (2009-06-17 10:56) [5]procedure TMyForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caFree;
end;
← →
Ega23 © (2009-06-17 10:59) [6]
> Нат © (17.06.09 10:56) [5]
>
> procedure TMyForm.FormClose(Sender: TObject; var Action:
> TCloseAction);
> begin
> Action:=caFree;
> end;
Спорное утверждение. Сильно зависит от того, каким образом вызывается форма.
← →
b/@. © (2009-06-17 11:09) [7]
> Плохиш © (17.06.09 10:50) [3]
> Интересно, и чем Close не угодило?
> Нат © (17.06.09 10:56) [5]> procedure TMyForm.FormClose(Sender: TObject; var Action:
> TCloseAction);
> begin
> Action:=caFree;
> end;
Это роли не играет. После показа форма мне не нужна, так почему бы не мучать и не удалить :)
← →
KSergey © (2009-06-17 11:48) [8]> b/@. © (17.06.09 10:52) [4]
> > ModalResult := mr....; // Например, mrOK
> > end;
>
> Эту штуку пробовал,
И каков результат?
← →
b/@. © (2009-06-17 12:13) [9]
> KSergey © (17.06.09 11:48) [8]
> И каков результат?
Точно такой же как и без него...
← →
Ega23 © (2009-06-17 12:41) [10]
> Точно такой же как и без него...
Сдаётся мне, ты гонишь. Либо не пробовал, либо пробовал, но через опу.
← →
b/@. © (2009-06-17 14:40) [11]
> Ega23 © (17.06.09 12:41) [10]
> Сдаётся мне, ты гонишь. Либо не пробовал, либо пробовал, но через опу.
А что, по-вашему, должно было произойти ?
← →
Ega23 © (2009-06-17 14:57) [12]
> А что, по-вашему, должно было произойти ?
Знаешь, я вот только что написал код. Создаёт форму с таймером и кнопкой, запускает её модально. Можно дёргать усиленно по экрану. Никаких AV. Использовал ModalResult.
Ну что, код давать? :)
← →
Нат © (2009-06-17 14:58) [13]Присвоение ModalResult приводит к закрытию или сокрытию окна.
В зависимости от обрабочика OnClose
Use ModalResult to close the form when it is displayed modally.
By default, ModalResult is mrNone. Set ModalResult to any nonzero value to close the form. The value assigned to ModalResult becomes the return value of the ShowModal function call used to display the form.
← →
Сергей М. © (2009-06-17 15:00) [14]
> начинаю интенсивно таскать её
Что значит "интенсивно" ?
А если не "интенсивно" то что происходит ?
← →
Ega23 © (2009-06-17 15:00) [15]
> Присвоение ModalResult приводит к закрытию или сокрытию
> окна.
Только если оно модальное.
← →
Cobalt © (2009-06-17 15:03) [16]А что говорит стек вызовов (CallStack)?
а еще скомпилировать с Debug dcu.
AV оно же ниоткуда не выскакивает просто так, кто-то где-то что-то забыл, или понадеялся на что-то.
← →
b/@. © (2009-06-17 15:21) [17]
> Ega23 © (17.06.09 14:57) [12]
> Ну что, код давать? :)
Давай.
← →
Ega23 © (2009-06-17 15:47) [18]
> Давай.
Ну на.
procedure TForm1.Button8Click(Sender: TObject);
var
frm : TForm5;
begin
frm := TForm5.Create(nil);
try
frm.ShowModal;
finally
frm.Free;
end;
end;
unit Unit5;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;
type
TForm5 = class(TForm)
Button1: TButton;
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form5: TForm5;
implementation
{$R *.dfm}
procedure TForm5.Button1Click(Sender: TObject);
begin
ModalResult := mrOk;
end;
procedure TForm5.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
ModalResult := mrOk;
end;
end.
← →
b/@. © (2009-06-17 16:25) [19]
> Ega23 © (17.06.09 15:47) [18]
У меня был точно такой же, но в этом коде два ньюанса:
1. Форму нужно уничтожать принудительно.
2. Форму можно таскать безконечно долго, сообщение от таймера прийдёт только только после окончания перетаскивания.
Благодаря совету Cobalt © (17.06.09 15:03) [16] выяснил, что AV в моём коде происходило из-за слишком раннего вызоваRelease();
и некорректом закрытии при этом модального окна.
AV вызывалось в методеTCustomForm.CloseModal
в строчкеif CloseQuery then
, причём в саму функциюCloseQuery
даже не заходило.
На данный момент, для предотвращения AV, можно использовать совет Ega23 © (17.06.09 10:47) [2] одновременно с Нат © (17.06.09 10:56) [5].
При этом остаётся лишь ньюанс №2, но этим можно и пожертвовать :)
Но самое интересное - что мой собственный вариант сReleaseCapture();
приводит к точно такому же результату, но ньюанс №2 при этом не возникает - форма закрывается в любом случае, и во время перетаскивания тоже...
← →
Ega23 © (2009-06-17 16:29) [20]
> 1. Форму нужно уничтожать принудительно.
А где её не уничтожают?
← →
Нат © (2009-06-17 16:37) [21]При перетаскивании нужно останавливать таймер.
Вероятно, из-за перетаскивания окна в момент его уничтожения по таймеру, происходило обращение к свойствам объекта.
И соот-но, AV.
← →
b/@. © (2009-06-17 16:40) [22]
> Ega23 © (17.06.09 16:29) [20]
> > 1. Форму нужно уничтожать принудительно.
> А где её не уничтожают?
В вашем варианте форма уничтожается здесь:
> frm := TForm5.Create(nil);
> try
> frm.ShowModal;
> finally
> frm.Free;
> end;
В моём же варианте, она уничтожается сама после закрытия.
Кстати Плохиш ©, вы были правы,Close
лучше.
← →
Игорь Шевченко © (2009-06-17 16:47) [23]
> procedure TAbout.ButtonClick(Sender: TObject);
> begin
> Release();
> end;
перед release вставь таймер.enabled := false
← →
b/@. © (2009-06-17 16:48) [24]
> Нат © (17.06.09 16:37) [21]
> При перетаскивании нужно останавливать таймер.
> Вероятно, из-за перетаскивания окна в момент его уничтожения по таймеру, происходило обращение к свойствам объекта. И соот-но, AV.
Думаю немножко не так.
Я неправильно воспользовалсяRelease();
. Получалось так что сначала выполнялся FormDestroy, и на момент выполненияCloseModal
объект был уничтожен и вычищен.
← →
b/@. © (2009-06-17 16:59) [25]
> Игорь Шевченко © (17.06.09 16:47) [23]
> перед release вставь таймер.enabled := false
Это сделано еще вTimerTimer
, просто не указал.
Таймер срабатывает только один раз, но даже если этого делатьTimer.Enabled := false;
, то второй раз не успеет сработать - интервал=5 секундам, а AV возникает сразу.
← →
Игорь Шевченко © (2009-06-17 17:17) [26]Да, Close вместо Release
AV никаких нетunit about;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm2 = class(TForm)
Button1: TButton;
Timer1: TTimer;
procedure Button1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
procedure HitTest(var Message: TMessage); message WM_NCHITTEST;
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
begin
Timer1.Enabled := false;
Close;
end;
procedure TForm2.HitTest(var Message: TMessage);
begin
Message.Result := HTCAPTION;
end;
procedure TForm2.Timer1Timer(Sender: TObject);
begin
Button1.Click;
end;
end.
и вызывать по Create(Application) do
try
showmodal;
finally
free;
end;
← →
Нат © (2009-06-17 17:18) [27]"Вычищен" - это что имеется ввиду?
Обниливайте указатель, перед обращением проверяйте на nil.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.08.16;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.007 c