Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
2-1245675524
dmitry1991
2009-06-22 16:58
2009.08.16
составить Pattern(RegExp)


15-1245097806
Юрий
2009-06-16 00:30
2009.08.16
С днем рождения ! 16 июня 2009 вторник


4-1202326013
Velimir
2008-02-06 22:26
2009.08.16
Получить информацию о ресурсах PCI устройства


2-1245310635
wordmen
2009-06-18 11:37
2009.08.16
Как удалить символы перевода строки в Memo


2-1245498247
Mouse
2009-06-20 15:44
2009.08.16
Количество нажатий кнопки мыши





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский