Re[5]: как создать форму другом потоке
От: Slicer [Mirkwood] Россия https://ru.linkedin.com/in/maksim-gumerov-039a701b
Дата: 16.07.04 18:39
Оценка: 10 (1) +1
А>А можно в двух словах, какая разница, выполнить один и тот-же код в теле WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) или в теле void __fastcall TThreadDesktop::Execute()?
Необходима синхронизация. Это в двух словах А подробнее — если код, работающий в Execute, обращается к GUI, все такие фрагменты кода должны быть синхронизированы с потоком, в котором работает Application, чтобы, грубо говоря, избежать одновременного чтения данных одним потоком и изменения другим. Такая синхронизация в рамках VCL осуществляется путем вызова нужного метода в потоке, в котором крутится Application (это и делает метод Synchronize).

Если же в другом потоке создается целая форма, то, полагаю (надо смотреть исходники), код, реализующий класс TForm, не содержит вызовов Synchronize, обрамляющих его контакты с другими окнами, в т.ч. с Application — и, как следствие, не является потокобезопасным и, скорее всего, приведет к нарушению функционирования приложения.

А>В каждом из них создаются свои экземпляры классов и форм, которые между собой ну никак не взаимодействуют.

Ой ли? Вы не можете быть в этом уверены. Для VCL как раз характерна изрядная степень самостоятельности. Уж наверняка все Ваши формы хоть изредка взаимодействуют, например, с Application.

А>И возвращаясь к топику — как всё-таки можно показать (новую) форму в другом потоке (десктопе, Create/SwitchDesktop)? По ходу этот поток и должен раздавать события этой форме, поэтому мне подумалось, что лучше под это дело приспособить новый экземпляр TApplication. В визуаловском сэмпле такое делается как два пальца...

Насчет нового TApplication.. Один мой знакомый пытался приделать такое, я отсоветовал — абсолютно нигде не документировано, как поведет себя приложение при создании двух экземпляров TApplication. Зато в конструкторе TApplication сказано (в Delphi): "Do not call Create directly. Each Delphi application automatically creates an instance of an application object". Даже если такой код будет работать, он не будет переносим на новые версии VCL.
Могу внести только одно предложение (пока, может, потом еще чтонить придумается ) — используйте WinAPI.

Slicer
Специалист — это варвар, невежество которого не всесторонне :)
Re[3]: как создать форму другом потоке
От: Slicer [Mirkwood] Россия https://ru.linkedin.com/in/maksim-gumerov-039a701b
Дата: 18.07.04 09:48
Оценка: +1
DTS>там много ручной работы, нужно создавать только форму (TForm), и внутри потка делать цикл обработки сообщений, еще нельзя использовать SHowModal — тк там есть обращение к Application и Screen.
Ага, и, возможно, еще много чего нельзя, что выяснится только через 48 часов тщательной отладки за день до сдачи проекта

Slicer
Специалист — это варвар, невежество которого не всесторонне :)
как создать форму другом потоке
От: Аноним  
Дата: 16.07.04 13:08
Оценка:
Известно, чтобы создать окошко в другом десктопе, надо делать отдельный поток для этого окошка, который будет раздавать ему события.
Как это сделать в билдере?

Код, вроде нижеуказанного обламывается — "Canvas does not allow drawing", хотя взят из стандартного, DesktopForm больше нигде не создаётся:

void __fastcall TForm1::Button2Click(TObject *Sender)
{
ThreadDesktop = new TThreadDesktop(false);
}

void __fastcall TThreadDesktop::Execute()
{
//---- Place thread code here ----
TApplication * Application = new TApplication(NULL);

try
{
Application->Initialize();
Application->CreateForm(__classid(TDesktopForm), &DesktopForm);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}

delete Application;
}
Re: как создать форму другом потоке
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 16.07.04 15:09
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Известно, чтобы создать окошко в другом десктопе, надо делать отдельный поток для этого окошка, который будет раздавать ему события.

А>Как это сделать в билдере?

А>Код, вроде нижеуказанного обламывается — "Canvas does not allow drawing", хотя взят из стандартного, DesktopForm больше нигде не создаётся:



Ну как бы VCL так спроектирована, что оказалось, что GUI можно управлять только из одного потока — первичного (сиречь, того, в котором крутится главная форма приложения). Все попытки обратиться к GUI из другого потока без использования Synchronize — могут жестоко обломаться вплоть до AV.
Re[2]: как создать форму другом потоке
От: Аноним  
Дата: 16.07.04 15:48
Оценка:
F>Ну как бы VCL так спроектирована, что оказалось, что GUI можно управлять только из одного потока — первичного (сиречь, того, в котором крутится главная форма приложения). Все попытки обратиться к GUI из другого потока без использования Synchronize — могут жестоко обломаться вплоть до AV

Мне этого и не надо. Тем более я в этом потоке создаю новое приложение, которое и должно обслуживать именно эту форму.
Re[3]: как создать форму другом потоке
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 16.07.04 15:49
Оценка:
Здравствуйте, Аноним, Вы писали:

F>>Ну как бы VCL так спроектирована, что оказалось, что GUI можно управлять только из одного потока — первичного (сиречь, того, в котором крутится главная форма приложения). Все попытки обратиться к GUI из другого потока без использования Synchronize — могут жестоко обломаться вплоть до AV


А>Мне этого и не надо. Тем более я в этом потоке создаю новое приложение, которое и должно обслуживать именно эту форму.


Мда... Как вы думаете, как устроен класс TApplication? Советую посмотреть... Ничего у вас не получится, по-хорошему...
Re[4]: как создать форму другом потоке
От: Аноним  
Дата: 16.07.04 15:56
Оценка:
А>>Мне этого и не надо. Тем более я в этом потоке создаю новое приложение, которое и должно обслуживать именно эту форму.

F>Мда... Как вы думаете, как устроен класс TApplication? Советую посмотреть... Ничего у вас не получится, по-хорошему...


А можно в двух словах, какая разница, выполнить один и тот-же код в теле WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) или в теле void __fastcall TThreadDesktop::Execute()?

В каждом из них создаются свои экземпляры классов и форм, которые между собой ну никак не взаимодействуют.

И возвращаясь к топику — как всё-таки можно показать (новую) форму в другом потоке (десктопе, Create/SwitchDesktop)? По ходу этот поток и должен раздавать события этой форме, поэтому мне подумалось, что лучше под это дело приспособить новый экземпляр TApplication. В визуаловском сэмпле такое делается как два пальца...
Re[4]: как создать форму другом потоке
От: Аноним  
Дата: 16.07.04 16:05
Оценка:
А ещё эта зараза при пошаговой отладке не вылазит, всё нормально показывает. Только если сразу запустить глюки вылазят...
Re[2]: как создать форму другом потоке
От: DenisTST  
Дата: 17.07.04 21:07
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>Известно, чтобы создать окошко в другом десктопе, надо делать отдельный поток для этого окошка, который будет раздавать ему события.

А>>Как это сделать в билдере?

Ну это можно сделать , я видел в интернете несколько примеров, например
на http://www.delphimaster.ru в "кладовке" был пример приложения, но этот раздел счас не работает
(Splash в другом потоке, на котором крутился Flash ролик )


там много ручной работы, нужно создавать только форму (TForm), и внутри потка делать цикл обработки сообщений, еще нельзя использовать SHowModal — тк там есть обращение к Application и Screen.
... << Rsdn@Home 1.1.4 beta 1 >>
Re[5]: как создать форму другом потоке
От: Jack128  
Дата: 18.07.04 20:39
Оценка:
Здравствуйте, Аноним, Вы писали:

А>И возвращаясь к топику — как всё-таки можно показать (новую) форму в другом потоке (десктопе, Create/SwitchDesktop)? По ходу этот поток и должен раздавать события этой форме, поэтому мне подумалось, что лучше под это дело приспособить новый экземпляр TApplication. В визуаловском сэмпле такое делается как два пальца...


И что это даст? Формы общаются конкретно с переменной Application, так что либо для основного, либо для дополнительного потока Application не будет другим. Да и не только в нем дело, например см CreationControl, да вообще один просмотр глобальных переменных в модулях Forms/Controls даст хорошее представление о "потокобезопасности" VCL
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.