Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

В потоке проверка MainForm.Enabled возвращает неверное значение.


Евдоким ©   (2013-04-29 11:19:00) 

Сабж. Почему?

Файл для проверки http://files.hostingdj.us/downloads/20130429_Unit12496587.pas(Unit.pas)

Суть.
При создании формы запускается поток, в котором проверяется
fsModal in fMainForm.FormState
и
fMainForm.Enabled

На форме одна кнопка, которая создает и отображает модально другую форму.
И вот когда показана вторая форма проверка в потоке возвращает
fMainForm.FormState = []
fMainForm.Enabled = True

Почему?

Код, для тех кто не хочет качать:


unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TagrSomeThread = class;

 TForm1 = class(TForm)
   Button1: TButton;
   procedure FormDestroy(Sender: TObject);
   procedure FormCreate(Sender: TObject);
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
   m_theSomeThread: TagrSomeThread;
 public
   { Public declarations }
 end;

 TMyForm = class(TForm)
 private
   { Private declarations }
 public
   { Public declarations }
 end;

 TagrSomeThread = class(TThread)
 private
   fMainForm: TForm;
   procedure EnableMainForm;
   function isNeedEnableMainForm: boolean;
 protected
   procedure Execute; override;
 public
   constructor Create(MainForm: TForm; CreateSuspended: Boolean);
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormDestroy(Sender: TObject);
begin
 if m_theSomeThread <> nil then begin
   m_theSomeThread.Terminate;
   if m_theSomeThread.Suspended then
     m_theSomeThread.Start;
   m_theSomeThread.WaitFor;
   FreeAndNil(m_theSomeThread);
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 m_theSomeThread := TagrSomeThread.Create(Self, True);
 m_theSomeThread.FreeOnTerminate := False;
 m_theSomeThread.Priority := tpLower;
 m_theSomeThread.Start;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 with TMyForm.CreateNew(nil) do begin
   ShowModal;
 end;
end;

{ TagrSomeThread }
constructor TagrSomeThread.Create(MainForm: TForm; CreateSuspended: Boolean);
begin
 inherited Create(CreateSuspended);
 fMainForm := MainForm;
end;

procedure TagrSomeThread.EnableMainForm;
begin
 if fMainForm = nil then
   Exit;
//  fMainForm.Enabled := True;
end;

procedure TagrSomeThread.Execute;
begin
 while not Terminated do begin
   if isNeedEnableMainForm then
     Synchronize(EnableMainForm);
   Sleep(200);
 end;
end;

function TagrSomeThread.isNeedEnableMainForm: boolean;
begin
 Result := False;
 if fMainForm = nil then
   Exit;
 if fsModal in fMainForm.FormState then
   Exit;
 if fMainForm.Enabled then
   Exit;
 Result := True;
end;

end.


SergeyIT   (2013-04-29 23:33:00) [1]

Может еще getlastactivepopup ?


clickmaker   (2013-04-29 12:28:00) [2]

логично. Потому что при входе в модальный цикл вызывается DisableTaskWindows


Евдоким   (2013-04-29 12:21:00) [3]

Хм...
при этом IsWindowEnabled(fMainForm.Handle) возвращает False когда показана вторая форма.

Спасибо.


clickmaker   (2013-04-29 12:12:00) [4]

Application.ModalLevel
либо ловить OnModalBegin


Евдоким   (2013-04-29 12:04:00) [5]

Александр, ну не надо издеваться. Неужели из диалога выше не ясно откуда? Из потока конечно.


clickmaker   (2013-04-29 12:01:00) [6]

> как можно узнать что MainForm в данный момент не активна
> в том смысле, что кто-то показан модально по отношению к
> ней?

узнать откуда?


Евдоким   (2013-04-29 11:58:00) [7]

Ага, ошибку осознал, курю маны :)

А может тогда подскажите как можно узнать что MainForm в данный момент не активна в том смысле, что кто-то показан модально по отношению к ней?


clickmaker   (2013-04-29 11:54:00) [8]

> fsModal in fMainForm.FormState должно вернуть True?

с какой радости?


Евдоким   (2013-04-29 11:53:00) [9]

clickmaker ©   (29.04.13 11:43) [9]
> ну так и узнавай. Поток-то зачем?

Вот я и узнаю, а оно не узнается. А в потоке потому, что больше негде.

clickmaker ©   (29.04.13 11:45) [10]
> кстати, почему в момент, когда показана вторая форма, MainForm.Enabled не должно быть true?

Может и не должна, но fsModal in fMainForm.FormState должно вернуть True?


clickmaker   (2013-04-29 11:45:00) [10]

кстати, почему в момент, когда показана вторая форма, MainForm.Enabled не должно быть true?


clickmaker   (2013-04-29 11:43:00) [11]

> Цель в любой момент времени узнать что
> fsModal in fMainForm.FormState= True

ну так и узнавай. Поток-то зачем?


Евдоким   (2013-04-29 11:41:00) [12]

Олегыч, задача не реальная, а гипотетическая, в конкретном случае сведенная к минимуму для повторения.

Цель в любой момент времени узнать что
fsModal in fMainForm.FormState= True
и
fMainForm.Enabled = False


Ega23   (2013-04-29 11:38:00) [13]

Хотя нет, невнимательно посмотрел. Прошу прощения.


clickmaker   (2013-04-29 11:38:00) [14]

вообще, какая-то странная задача... в чем цель-то?


Ega23   (2013-04-29 11:36:00) [15]

 while not Terminated do begin
   if isNeedEnableMainForm then
     Synchronize(EnableMainForm);
   Sleep(200);
 end;


Кто там Архангельского защищал, а?
Мол, пример с Synchronize(Work)- вполне удачный?


Евдоким   (2013-04-29 11:34:00) [16]

Тьфу, isNeedEnableMainForm превратить в процедуру забыл.


Евдоким   (2013-04-29 11:33:00) [17]


procedure TagrSomeThread.Execute;
begin
 while not Terminated do begin
   Synchronize(isNeedEnableMainForm);
   if fTestBool then
     Synchronize(EnableMainForm);
   Sleep(200);
 end;
end;

function TagrSomeThread.isNeedEnableMainForm: boolean;
begin
 fTestBool := False;
 if fMainForm = nil then
   Exit;
 if fsModal in fMainForm.FormState then
   Exit;
 if fMainForm.Enabled then
   Exit;
 fTestBool := True;
end;


Евдоким   (2013-04-29 11:31:00) [18]

Если обернуть в синхронайз ситуация не меняется.


clickmaker   (2013-04-29 11:30:00) [19]

из отдельного потока не стоит напрямую обращаться к свойствам контролов vcl


Наверх

Титульная страница Поиск, карта сайта Написать письмо