Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
4-1221721293
roughneck
2008-09-18 11:01
2009.11.22
Получить иконку связанную с недоступным в сети файлом


1-1225211215
leonidus
2008-10-28 19:26
2009.11.22
Кодирование кириллицы для использования в URL


15-1253630278
TRSteep
2009-09-22 18:37
2009.11.22
Авто дописывание кода


15-1253538729
KSergey
2009-09-21 17:12
2009.11.22
Про защитные картинки


15-1253568604
Юрий
2009-09-22 01:30
2009.11.22
С днем рождения ! 22 сентября 2009 вторник





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский