Форум: "Основная";
Текущий архив: 2009.11.22;
Скачать: [xml.tar.bz2];
ВнизЗаставить 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;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.006 c