Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.11.22;
Скачать: CL | DM;

Вниз

Заставить Application.ProcessMessages работать в чужом потоке   Найти похожие ветки 

 
DelphiLexx   (2008-10-31 15:15) [0]

Как мы знаем вызов Application.ProcessMessages приводит к тому что происходит обработка очереди сообщений того потока в котором собственно вызывался. У меня вопрос как в Delphi можно заставить подобную ф-цию произвести обработку сообщения в контексте заданного потока т.е. как то так:

Application.ProcessMessages(dwThreadID: DWORD);

Нужно мне собственно для того, чтобы можно было выполнить такую вещь:
MainThread (главный поток) cоздает ChildThread(дочерний поток), и далее MainThread начинает выполнять долгую операцию.

ChildThread(дочерний поток) - это по сути у меня окно в котором показывается время выполнения действия + какая-нить красивая анимация + ProgressBar и т.п. Это окно у меня используется во многих местах программы с разными MainThread"ами
так вот чтобы у пользователя не было ощущения что прога повисла делаем Application.ProcessMessages т.е.
-----------------------memory MainThread1----------------------
код инициализирующий ChildThread т.е. создание красивого окна ожидания ShowWinWait в отдельном потоке
какой код выполняющий в цикле сложные операции
for i := .. to .. do
Application.ProcessMessages
-----------------------------------------------------------------------

-----------------------memory MainThread2----------------------
код инициализирующий ChildThread т.е. создание красивого окна ожидания ShowWinWait в отдельном потокекакой код выполняющий сложные операции
Application.ProcessMessages
-----------------------------------------------------------------------

-----------------------memory MainThread3----------------------
код инициализирующий ChildThread т.е. создание красивого окна ожидания ShowWinWait в отдельном потокекакой код выполняющий сложные операции
Application.ProcessMessages
-----------------------------------------------------------------------

Как вы заметели приходиться в MainThread"ах вызывать Application.ProcessMessage это не очень удобно проще было бы так
-----------------------memory MainThread1----------------------
код инициализирующий ChildThread т.е. создание красивого окна ожидания с параметрами ShowWinWait(MainTID),
где MainTID = GetWindowThreadProcessId (Self.Handle, lpdwProcessId) - id MainThread1
какой код выполняющий в цикле сложные операции
for i := .. to .. do
-----------------------------------------------------------------------

------------------------memory ChildThread----------------------
здесь собственно код отображающие ProgressBar и т.д.
procedure OnTimerTime
begn
....
Application.ProcessMessages(MainTID);
end;
------------------------------------------------------------------------


 
Рамиль ©   (2008-10-31 15:27) [1]

А зачем окно в отдельный поток? Пусть будет в главном потоке. Тем более, что Application.ProcessMessage и потоки это как то странно. Зачем обрабатывать сообщения насильно, если при правильном проектировании с потоками все будет работать само.


 
DelphiLexx   (2008-10-31 15:33) [2]


> А зачем окно в отдельный поток? Пусть будет в главном потоке.
>  Тем более, что Application.ProcessMessage и потоки это
> как то странно. Зачем обрабатывать сообщения насильно, если
> при правильном проектировании с потоками все будет работать
> само.

Сделано уже так, хотелось бы все же Application.ProcessMessages из всех потоков вынести в один так как же заставить работать Application.ProcessMessages(dwThreadID: dword) или быть может есть аналогичная ф-ция


 
Сергей М. ©   (2008-10-31 15:34) [3]


> DelphiLexx   (31.10.08 15:15)  


Заставить кого-то делать что-то, чего он делать не умеет и/или не желает - это попахивает насилием)

А насиловать-то как раз никого не нужно, достаточно просто поставить все задуманное с головы на ноги: основной поток занимается своим делом (GUI), а дополнительный своим (длительные вычисления в контексте строго определенной возложенной на поток задачи)


 
DelphiLexx   (2008-10-31 15:47) [4]


> Заставить кого-то делать что-то, чего он делать не умеет
> и/или не желает - это попахивает насилием)

есть условия не мною поставленные, необходимо их решить
вот я пытаюсь их решить


 
Сергей М. ©   (2008-10-31 15:52) [5]

Ну хорошо, надо так надо.


> ChildThread(дочерний поток) - это по сути у меня окно


Что сие означает ?


 
KSergey ©   (2008-10-31 16:01) [6]

Надо просто AVI-анимашку нарисовать - и все.
Винда сама ее красиво отрисует в другом (своем) потоке.


 
KSergey ©   (2008-10-31 16:01) [7]

> KSergey ©   (31.10.08 16:01) [6]
> Винда сама ее красиво отрисует в другом (своем) потоке.

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


 
DelphiLexx   (2008-10-31 16:12) [8]


> Что сие означает ?

MainThread  - собственно главный поток.
WinWait - окно в котором отображается ProgressBar + анимация и т.п, данное окно содержит JVCL Timer который работает в отдельном потоке (TimerThread) и  генерит событие OnTimer на это событие повешена ф-ция, которая управляет ProgressBar"ом анимацией и прочей фигней, в нее же мне надо разместить ф-цию типа Application.ProcessMessages(MainThreadID) для обновления очереди события главного потока, если же я там размещу просто Application.ProcessMessages, то будет производиться обработка очереди сообщений потока TimerThread, но т.к. TimerThread - не содержит окон то это очередь всегда пуста и поэтому Application.ProcessMessages по сути ничего не выполняет полезного в данном случае.


 
Сергей М. ©   (2008-10-31 16:20) [9]


> DelphiLexx   (31.10.08 16:12) [8]


Т.е. окно, в котором должно происходить все это чудодейство с прогресс-баром и анимацией, создано в контексте основного потока, так ?


 
DelphiLexx   (2008-10-31 16:41) [10]

Да


 
Сергей М. ©   (2008-10-31 16:52) [11]

Что мешает вынести создание окна в доп.поток, тот самый который у тебя шурудит таймером ?


 
Leonid Troyanovsky ©   (2008-10-31 17:10) [12]


> DelphiLexx   (31.10.08 16:12) [8]

> в отдельном потоке (TimerThread) и  генерит событие OnTimer
> на это событие повешена ф-ция, которая управляет ProgressBar"ом
> анимацией и прочей фигней, в нее же мне надо разместить
> ф-цию типа Application.ProcessMessages(MainThreadID) для обновления
> очереди события главного потока

Пользуй Synchronize метода потока, который и
вызовет Application.ProcessMessages.
Ну, или пошли форме SendMessage, при обработке которого
она и вызовет Application.ProcessMessages.

--
Regards, LVT.


 
DelphiLexx   (2008-10-31 17:22) [13]


> Пользуй Synchronize метода потока, который и
> вызовет Application.ProcessMessages.

Не понял, напримере не мог бы


 
Сергей М. ©   (2008-10-31 19:17) [14]


> Leonid Troyanovsky ©   (31.10.08 17:10) [12]


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

И вопрос, как видно, как раз и заключается в том как заставить осн.поток прекратить на время заниматься этим черт-те чем и обработать очередь сообщений по кр.мере своим окнам ..


 
Германн ©   (2008-10-31 19:24) [15]


> И вопрос, как видно, как раз и заключается в

На Исходниках тоже автора никто не понимает
http://forum.sources.ru/index.php?showtopic=254918


 
Сергей М. ©   (2008-11-01 10:12) [16]


> DelphiLexx


Если уж так приспичило напрячь осн.поток несвойственной ему работой, поступи след.образом:

1. Выкинь из проекта TimerThread - его существование бессмысленно и бесполезно

2. Вместо доп.потоков TimerThread и WinThread организуй единый доп.поток ProgressWinThread, в его контексте создаешь окно (именно окно, создаваемое непосредственным вызовом соотв.ф-ции в составе WinAPI-, а не VCL-форму !!!) и тут же организуешь цикл ожидания/выборки/диспетчеризации сообщений. В этом окне в контексте этого же потока рисуешь все что тебе нужно показать юзеру. Никаких таймеров при этом организовывать не нужно - небходимые временные выдержки обеспечиваются WaitForXXXX-функциями в составе WinAPI.


 
MetalFan ©   (2008-11-01 12:51) [17]


> На Исходниках тоже автора никто не понимает

да и на винграде тоже)


 
Leonid Troyanovsky ©   (2008-11-01 13:26) [18]


> DelphiLexx   (31.10.08 17:22) [13]

> Не понял, напримере не мог бы


procedure TMyThread.CallProcessMessages;
begin
 Application.ProcessMessages;
end;


> анимацией и прочей фигней, в нее же мне надо разместить
> ф-цию типа Application.ProcessMessages(MainThreadID) для
> обновления

Synchronize(CallProcessMessages);

--
Regards, LVT.


 
MetalFan ©   (2008-11-01 14:51) [19]

ага, но если главный поток загружен, то толку от этого не будет....


 
DelphiLexx   (2008-11-05 10:16) [20]


> Synchronize(CallProcessMessages);

Под TMyThread понимается главный поток?


 
Дмитрий Белькевич ©   (2008-11-05 14:33) [21]

Если я верно понял, то у тебя проблема, похожая на мою.

Основная проблема: "VCL - это однопотоковая библиотека. Это значит, что создавать и работать с формами вы можете только в главном потоке."

Я как-то занимался проблемой, но так окончательно и не доделал - пока ограничился костылями в некоторых местах, Application.Processmessage вызываю, хотя это у меня не всегда допустимо. Сдеалал флаги, что процедура еще не окончилась. Но это всё не важно.

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


 
Дмитрий Белькевич ©   (2008-11-05 15:03) [22]

Вот откопал:



program Project2;

{$R "resources.RES"}

uses
SysUtils,
Windows,
Messages;

function WndFunc(Wnd, Msg: DWord; wParam, lParam: integer): integer; stdcall;
begin
   Result := 0
end;

begin { main }
DialogBox(hInstance,MAKEINTRESOURCE(10),0,@WndFunc);
// CreateDialog(hInstance,MAKEINTRESOURCE(10),0,@WndFunc);
end.



resources.rc, собирается brcc


/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
10 DIALOGEX 0, 0, 193, 74
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE |
 WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_TOPMOST
CAPTION "Test Application"
FONT 8, "Helv", 0, 0
BEGIN
 PUSHBUTTON      "Close",IDCANCEL,134,38,52,15
 LTEXT           "Test:",IDC_STATIC,7,7,107,10
 CONTROL         101,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE,7,68,
                 179,3
 EDITTEXT        160,7,17,179,15,ES_AUTOHSCROLL | ES_READONLY
END


Но это так - наброски. Создавай такое окно (поправив предварительно ресурс), в отдельном потоке, обрабатывай сообщения от окна в WndFunc, позицию прогрессбара меняй из основного потока. Если нужен останов - обрабатывай нажатие контрола, выставляя какой-нибудь флаг в потоке.



Страницы: 1 вся ветка

Текущий архив: 2009.11.22;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.014 c
15-1253824205
Юрий
2009-09-25 00:30
2009.11.22
С днем рождения ! 25 сентября 2009 пятница


15-1253963283
@!!ex
2009-09-26 15:08
2009.11.22
Можно ли припаять микрофон к выходу на микрофон в ноуте?


15-1252661794
Knight
2009-09-11 13:36
2009.11.22
Подскажите по Delphi 2010...


15-1254210806
Лёша
2009-09-29 11:53
2009.11.22
О компресии данных


15-1253621448
Артур Пирожков
2009-09-22 16:10
2009.11.22
Можно ли записать радио?