Форум: "Начинающим";
Текущий архив: 2014.02.23;
Скачать: [xml.tar.bz2];
ВнизВ потоке проверка MainForm.Enabled возвращает неверное значение. Найти похожие ветки
← →
Евдоким (2013-04-29 11:19) [0]Сабж. Почему?
Файл для проверки 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.
← →
clickmaker © (2013-04-29 11:30) [1]из отдельного потока не стоит напрямую обращаться к свойствам контролов vcl
← →
Евдоким (2013-04-29 11:31) [2]Если обернуть в синхронайз ситуация не меняется.
← →
Евдоким (2013-04-29 11:33) [3]
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:34) [4]Тьфу, isNeedEnableMainForm превратить в процедуру забыл.
← →
Ega23 © (2013-04-29 11:36) [5]
while not Terminated do begin
if isNeedEnableMainForm then
Synchronize(EnableMainForm);
Sleep(200);
end;
Кто там Архангельского защищал, а?
Мол, пример с Synchronize(Work)- вполне удачный?
← →
clickmaker © (2013-04-29 11:38) [6]вообще, какая-то странная задача... в чем цель-то?
← →
Ega23 © (2013-04-29 11:38) [7]Хотя нет, невнимательно посмотрел. Прошу прощения.
← →
Евдоким (2013-04-29 11:41) [8]Олегыч, задача не реальная, а гипотетическая, в конкретном случае сведенная к минимуму для повторения.
Цель в любой момент времени узнать что
fsModal in fMainForm.FormState= True
и
fMainForm.Enabled = False
← →
clickmaker © (2013-04-29 11:43) [9]> Цель в любой момент времени узнать что
> fsModal in fMainForm.FormState= True
ну так и узнавай. Поток-то зачем?
← →
clickmaker © (2013-04-29 11:45) [10]кстати, почему в момент, когда показана вторая форма, MainForm.Enabled не должно быть true?
← →
Евдоким (2013-04-29 11:53) [11]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:54) [12]> fsModal in fMainForm.FormState должно вернуть True?
с какой радости?
← →
Евдоким (2013-04-29 11:58) [13]Ага, ошибку осознал, курю маны :)
А может тогда подскажите как можно узнать что MainForm в данный момент не активна в том смысле, что кто-то показан модально по отношению к ней?
← →
clickmaker © (2013-04-29 12:01) [14]> как можно узнать что MainForm в данный момент не активна
> в том смысле, что кто-то показан модально по отношению к
> ней?
узнать откуда?
← →
Евдоким (2013-04-29 12:04) [15]Александр, ну не надо издеваться. Неужели из диалога выше не ясно откуда? Из потока конечно.
← →
clickmaker © (2013-04-29 12:12) [16]Application.ModalLevel
либо ловить OnModalBegin
← →
Евдоким (2013-04-29 12:21) [17]Хм...
при этом IsWindowEnabled(fMainForm.Handle) возвращает False когда показана вторая форма.
Спасибо.
← →
clickmaker © (2013-04-29 12:28) [18]логично. Потому что при входе в модальный цикл вызывается DisableTaskWindows
← →
SergeyIT © (2013-04-29 23:33) [19]Может еще getlastactivepopup ?
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2014.02.23;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.003 c