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

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

Поток и ShowModal (Delphi2009)


Страницы:   1 2

NatashaZ ©   (2012-05-31 20:29:00) 

Здравствуйте!
Почему при вызове из неосновного потока форма вызывается по Showmodal, но не закрывается потом по нажатию на [X] или кнопку Exit (Button1), на клике которой процедура Close. Если вызывать ту же форму из основного потока программы, то форма закрывается нормально и так и так. Я слышала, что из потоков лучше не работать с визуальными объектами и может из-за этого проблема, но может есть какой-то обход данной проблемы?


Max   (2012-05-31 21:52:00) [21]


> Просто очень нужно, что бы во время работы потока при возникновении
>  определенной ситуации выдавалось сообщение с определенным
> текстом

Windows.MessageBox


Сергей М.   (2012-05-31 21:50:00) [22]


> NatashaZ


> нужно, что бы во время работы потока при возникновении  
> определенной ситуации выдавалось сообщение с определенным
> текстом


MessageBox


Давайте будем жрать!   (2012-05-31 21:45:00) [23]


> Такая конструкция разве допускается в потоке SendMessage(Form1.
> Handle,...)
Не допускается.


> Ну или может поток создать так: MyThread.Create(Form1)?
Возможно. Думай дальше.


> переменная используется потом не только в этом потоке и
> не только в этом юните. Поэтому решила её объявить глобально,
>  доступной для всех юнитов.
http://www.gunsmoker.ru/2011/04/blog-post.html


NatashaZ   (2012-05-31 21:37:00) [24]


> во-первых, глобальная переменная -- это само по себе плохо.

Спасибо за код. Эта переменная используется потом не только в этом потоке и не только в этом юните. Поэтому решила её объявить глобально, доступной для всех юнитов.


NatashaZ   (2012-05-31 21:35:00) [25]


> только вот ни к Application, ни к формам из потока обращаться
> нельзя, так что надо придумать, как форма потоку свой хэндл
> отдаст

Ну почему же?
Такая конструкция разве допускается в потоке SendMessage(Form1.Handle,...)?
Ну или может поток создать так: MyThread.Create(Form1)?


Давайте будем жрать!   (2012-05-31 21:33:00) [26]

во-первых, глобальная переменная -- это само по себе плохо.
во-вторых, надо делать что-то вроде

procedure TMyThread.Syncronized;
begin
 with TMyModalForm.Create(Application) do
   try
     ShowModal;
     Z := Edit1.Text; // Z -- поле TMyThread, а не глобальная переменная
   finally
     Free;
   end;
end;

procedure TMyThread.Execute;
begin
 if Formula() = 0 then
  Synchronize(Synchronized);
 ...
end;


NatashaZ   (2012-05-31 21:25:00) [27]


> но лучше воспользоваться советом [1].

Пока никак не  придумала, что можно поменять в логике задачи. Вычисляется результат по одной формуле и если результат равен 0, то выдаем диалог (вызываем форму с возможностью ввода числового значения в Edit). Дальше это значение записывается в переменную Z (Z объявлена глобальной переменной) по закрытию формы и дальше используется в том же потоке. Потоку нужно просто получить от пользователя следующее значение при результате 0. Поэтому модальное окно и нужно вызвать прямо из потока, приостановив все действия до закрытия формы с присвоением значения переменной Z.
Если есть мысли, как можно изменить логику, то очень буду признательна.


Давайте будем жрать!   (2012-05-31 21:20:00) [28]

только вот ни к Application, ни к формам из потока обращаться нельзя, так что надо придумать, как форма потоку свой хэндл отдаст


NatashaZ   (2012-05-31 21:16:00) [29]

Спасибо за код. Домашнее задание решила так: MainFormHandle должно быть Application.MyMainForm.handle


Давайте будем жрать!   (2012-05-31 21:11:00) [30]

Ну, в принципе, "поток в это время не должен производить никакие операции" сильно меняет задачу. И да, в таком случае Synchronize() уместен, но лучше воспользоваться советом [1].


NatashaZ   (2012-05-31 21:09:00) [31]

Вроде еще нашла вариант с вызовом Synchronize(). Может так можно будет что-то сделать?


Давайте будем жрать!   (2012-05-31 21:09:00) [32]

const
 MyMessage = WM_USER + 42;

type
 TMyMainForm = class(TForm)
   procedure WmMyMessage(var AMessage: TMessage); message MyMessage;
 end;

procedure TMyMainForm.WmMyMessage;
begin
 if модальная_форма_ещё_не_показана then
   with TMyModalForm.Create(Application) do
     try
       ShowModal;
     finally
       Free;
     end;
end;

procedure TMyThread.Execute;
begin
 for I := 1 to 1000000 do begin
   безумно_сложные_вычисления(I);
   if I mod 1000 = 0 then
     SendMessage(MainFormHandle, MyMessage, 0, 0);
 end;
end;

В качестве домашнего задания — разобраться, как потоку получить хэндл главной формы.


NatashaZ   (2012-05-31 21:04:00) [33]

Самое главное - поток в это время не должен производить никакие операции, пока не закроется модальное окно.


NatashaZ   (2012-05-31 21:03:00) [34]

Я так понимаю, что это при помощи SendMessage(Form1,...) делается, но как именно?


NatashaZ   (2012-05-31 21:01:00) [35]


> из потока отправляешь пользовательское сообщение главной
> форме. главная форма отлавливает сообщение и выводит модальную
> форму.

А пример такого кода можете привести? Заранее благодарна.


Давайте будем жрать!   (2012-05-31 20:59:00) [36]

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


NatashaZ   (2012-05-31 20:37:00) [37]

А если попробовать вызвать процедуру, описанную в TForm, а уже из неё вызвать ShowModal? Как думаете, получится?
Просто очень нужно, что бы во время работы потока при возникновении  определенной ситуации выдавалось сообщение с определенным текстом. Вот не могу понять пока как бы сделать, что бы работало именно модальное окно. Поиском искала, но ответа про showmodal и потоки не нашла :(


sniknik   (2012-05-31 20:33:00) [38]

не "лучше не работать", а нельзя, не "с визуальными объектами" а полностью с VCL.

> обход данной проблемы?
переписать VCL. или, невероятно конечно, понимаю, но - подумать и изменить логику программы.


Страницы:   1 2

Наверх

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