![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
В потоке проверка 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