Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как создать форму с потока? 
V
    Опции темы
Rohoss
  Дата 17.3.2009, 01:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Есть  вот такой код (излишние детали были убраны, дабы не усложнять суть)
Код

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    btn1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TMyTheard = class(TThread)
  protected
    procedure Execute; override;
  end;

  TMyClass = class(TObject)
  public
    procedure CreateForm;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btn1Click(Sender: TObject);
begin
  with TMyTheard.Create(True) do
  begin
    FreeOnTerminate := True;
    Resume;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin

end;

{ TMyTheard }

procedure TMyTheard.Execute;
begin
  with TMyClass.Create do
  begin
    CreateForm;
    Free;
  end;
end;

{ TMyClass }

procedure TMyClass.CreateForm;
begin
  with TForm.CreateNew(Application) do
  begin
    Show;
  end;

end;

end.


Тут происходит такая ситуация: форма создается, но сразу же уничтожается. Однако ссылки на неё остается в Components объекта Application, и соответственно при обращении к ней, таким образом, мы получаем исключения. В данной ситуации очень бы помог метод Synchronize. Но, к сожалению не понятно как синхронизировать метод другого класса (TMyClass). Можно было бы в данной ситуации создать ещё один метод, класса TMyTheard и синхронизировать его, но дело в том, что сам метод CreateForm может включать в себя ещё и другие методы класса TMyClass, а я не хочу всё это выполнять в VCL потоке. Мне в VCL потоке нужно только создать форму и всё!
 Надеюсь подробно описал ситуацию… 
Как в данном случае грамотно создать форму? 
И почему форма нормально живёт при создании с основного потока?



--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
dumb
Дата 17.3.2009, 02:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 13
Всего: 158



ответ на вопрос в заголовке: никак.

лучше опиши, зачем тебе это понадобилось.

чтиво: Многопоточность - как это делается в Дельфи.
PM MAIL   Вверх
Rohoss
Дата 17.3.2009, 02:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Цитата(dumb @  17.3.2009,  02:12 Найти цитируемый пост)
чтиво: Многопоточность - как это делается в Дельфи.

прочел не всю статью, ответа не нашёл.

Цитата(dumb @  17.3.2009,  02:12 Найти цитируемый пост)
лучше опиши, зачем тебе это понадобилось.


1.    Объект создает поток [MyCbj -> MyTh]
2.    Поток выполняет действия [MyTh -> Execute]
3.    Действия реализовано в другом классе [MyTh -> MyNewOb -> Work]
4.    И отображает результат выполнения на форме (если её нет, то создаёт) [MyTh -> MyNewOb -> Work -> FormCreate]
Примерно так
Здесь я не вижу возможности синхронизировать




--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
MetalFan
Дата 17.3.2009, 08:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



библиотека VCL потокоНЕбезепасна... если хочешь создавать формы(окна) в потоках, то варианта 2: 1. писать полностью на WinAPI 2. найти потокобезопасную библиотеку с нужным функционалом


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Alexeis
Дата 17.3.2009, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Цитата(MetalFan @  17.3.2009,  07:38 Найти цитируемый пост)
библиотека VCL потокоНЕбезепасна... если хочешь создавать формы(окна) в потоках, то варианта 2: 1. писать полностью на WinAPI 2. найти потокобезопасную библиотеку с нужным функционалом

  Можно выкрутиться если разделить VCL. Я делал такую штуку, форму поместил в Dll, затем в новом потоке вызвал LoadLibrary и загрузил библиотеку с формой. Но тогда нужно исключить прямое взаимодействие форм.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Rohoss
Дата 17.3.2009, 20:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



В моём случае, наверное, проще создать ещё один поток из класса, и с него обращаться к форме используя метод Synchronize. Но как, то через ж. получается  smile 

Если можно было бы выполнить в VCL потоке метод класса TMyClass  smile 


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
MetalFan
Дата 17.3.2009, 21:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Цитата(Rohoss @  17.3.2009,  20:44 Найти цитируемый пост)
Если можно было бы выполнить в VCL потоке метод класса TMyClass

шото я не понял мечтаний... а что мешает то?


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Rohoss
Дата 17.3.2009, 21:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Сам класс TMyClass создаётся в потоке TMyTheard, следовательно не имеет доступа к VCL потоку. И так как он не наследник TThread, у него нету метода Synchronize.
А другие объекты синхронизации насколько я понимаю, тут тоже не помогут.



--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
MetalFan
Дата 17.3.2009, 22:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



если покопаться, то можно увидеть у TThread классовую функцию Synchronize... возможно через нее получится поставить в очередь главному потоку метод стороннего класса


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
kami
Дата 17.3.2009, 23:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Создание любого окна (как визуального, так и нет) в дополнительном потоке автоматически означает необходимость создания обработчика событий в этом потоке.

простейший вид обработчика:
Код

procedure TMyThread.Execute;
var
  msg: TMsg;
begin
  PeekMessage(msg, 0, WM_USER, WM_USER, PM_NOREMOVE); // создаем очередь сообщений
// здесь можно инициализировать данные, которые должны работать в этом потоке.
  while not Terminated and GetMessage(msg, 0, 0, 0) do
      if msg.hwnd = 0 then
        // пришло сообщение нашему потоку с помощью PostThreadMessage или PostMessage(0)
        // здесь можно его обработать
      else
        DispatchMessage(msg); // иначе - передаем принятое сообщение в оконные функции.
end;


но это не отменяет
Цитата(MetalFan @  17.3.2009,  08:38 Найти цитируемый пост)
библиотека VCL потокоНЕбезепасна..
, посему работоспособность как минимум не гарантируется smile

Добавлено через 6 минут и 31 секунду
Цитата(MetalFan @  17.3.2009,  22:09 Найти цитируемый пост)
возможно через нее получится поставить в очередь главному потоку метод стороннего класса

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

Это сообщение отредактировал(а) kami - 17.3.2009, 23:46
PM MAIL WWW   Вверх
MetalFan
Дата 18.3.2009, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Цитата(kami @  17.3.2009,  23:42 Найти цитируемый пост)
Все события формы и всех компонентов на ней в любом случае будут вызываться в контексте потока, создавшего форму.

Цитата(Rohoss @  17.3.2009,  20:44 Найти цитируемый пост)
Если можно было бы выполнить в VCL потоке метод класса TMyClass

автор вроде имел ввиду просто сторонний класс. про форму не было упоминаний.

Цитата(kami @  17.3.2009,  23:42 Найти цитируемый пост)
простейший вид обработчика:

все вроде бы верно, да только не "повесит" ли GetMessage поток до появления сообщения в очереди? а если мы хотим его (поток) грохнуть, а он все будет сообщение ждать... может использовать MsgWaitForMultipleObjects+PeekMessage? либо в деструкторе предусмотреть посылку "контрольного" сообщения при убийстве потока.


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
kami
Дата 18.3.2009, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(MetalFan @  18.3.2009,  15:14 Найти цитируемый пост)
 да только не "повесит" ли GetMessage поток до появления сообщения в очереди?

Разумеется, повесит. Для выхода из цикла нужно послать WM_Quit (или "свое" сообщение, которое произведя дополнительные действия выведет из цикла).
А PeekMessage будет постоянно напрягать OC пустыми циклами, что не есть хорошо. Если же добавить WaitForXXX, то такой вариант будет ничем не лучше моего. За одним исключением - с использованием WaitFor даже простейший таймер, созданный в этом потоке работать не будет, т.к. до DispatchMessage дело не дойдет.
PM MAIL WWW   Вверх
MetalFan
Дата 18.3.2009, 19:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Цитата(kami @  18.3.2009,  18:41 Найти цитируемый пост)
Если же добавить WaitForXXX, то такой вариант будет ничем не лучше моего. За одним исключением - с использованием WaitFor даже простейший таймер, созданный в этом потоке работать не будет, т.к. до DispatchMessage дело не дойдет. 

не понял мысли.
почему не дойдет до диспатча?
1. MsgWaitFor... // ждем сообщение и/или любое другое событие С ТАЙМАУТОМ ожидания
2. Если пришло сообщение - получаем (GetMessage/PeekMessage) и обрабатываем (DispatchMessage)
3. Если таймаут - проверяем флаг Terminated
4. goto п.1.


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
kami
Дата 18.3.2009, 20:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(MetalFan @  18.3.2009,  19:50 Найти цитируемый пост)
почему не дойдет до диспатча?

Что могу сказать?
Снимаю шляпу и посыпаю голову пеплом.
Никогда не использовал ожидание с таймаутом, вот и вылетело из головы напрочь  smile 

Да и (главное) - не обратил внимание на MSGWaitFor

Это сообщение отредактировал(а) kami - 18.3.2009, 20:14
PM MAIL WWW   Вверх
Демо
Дата 18.3.2009, 22:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 30
Всего: 50



Цитата(Alexeis @  17.3.2009,  10:44 Найти цитируемый пост)
 Можно выкрутиться если разделить VCL.


Любая форма использует объекь Application и нельзя от этого избавиться.
Поэтому с формами никак не выкрутиться и невозможно их использовать в дополнительных потоках.


--------------------
    
PM MAIL ICQ Skype   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.3966 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.