Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.09.14;
Скачать: [xml.tar.bz2];

Вниз

Окно - прогресс в отдельном потоке   Найти похожие ветки 

 
Сергей М. ©   (2008-07-18 14:40) [40]

Я вообще не понимаю, зачем при данных условиях нужен доп.поток и почему осн.поток не должен "отвлекаться" .. Ведь пока осн.поток занят , GUI мертв ! Ни форму двинуть, ни приложение терминировать, ни картинку перерисовать  .."Живое" окно доп.потока с прогресс-баром и кнопкой "Отмена" в расчет не берем - это, конечно, тоже GUI, но совершенно бестолковый, "корове седло")


 
Игорь Шевченко ©   (2008-07-18 14:45) [41]


> Таймер - лишнее, конечно. PostThreadMessage.


в ряде случаев отнюдь не лишнее. Пользователю необязательно видеть изменения прогресса при КАЖДОМ его изменении, иногда достаточно обновления раз в некоторый интервал, в секунду, в две...


 
Сергей М. ©   (2008-07-18 14:46) [42]


> спросил - какой способ лучше?


Любой, позволяющий получать и диспетчеризовать только нужные (а не все подряд) сообщения - Get/PeekMessage + DispatchMessage


> как в отдельном потоке - конечно, Application.ProcessMessages
> не нужен, от него и избавляемся.
>


Да не то что не нужен - не допустим !

Но я, вообще-то, об основном, в котором Application.ProcessMessages допустим по логике VCL, но при этом якобы недопустим по твоей прикладной логике. Вот про возможные его альтернативы я и повел речь.


 
Тын-Дын ©   (2008-07-18 15:26) [43]


> Дмитрий Белькевич ©   (18.07.08 11:03) [23]
>
> Согласитесь,
>  что сделать одно окно проще


Заметь, ты сам написал - "окно"

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


 
Дмитрий Белькевич ©   (2008-07-18 15:51) [44]

>Игорь Шевченко

Большое спасибо, посмотрю.

>Ведь пока осн.поток занят , GUI мертв !

Вот. Что бы оживить GUI (прогресс-форму), мне в основном потоке приходится постоянно в цикле обработки вызывать ProcessMessages.
Во время вызова, как я пониамаю, обрабатываются все сообщения, накопившиеся в очереди. Так вот - иногда в очередь попадают нежелательные сообщения, которые должны будут обработаться только после того, как основной поток отработает цикл. И потерять, или отфильтровать эти сообщения нельзя.

>в ряде случаев отнюдь не лишнее. Пользователю необязательно видеть изменения прогресса при КАЖДОМ его изменении, иногда достаточно обновления раз в некоторый интервал, в секунду, в две...

Да, знаю такое, но немного по-другому делал. Сейчас есть два метода у формы - Step и Step100, первый обновляет прогрессбар после каждого вызова, второй ведёт внутренний счетчик и обновляет только каждый сотый.

В этом случае, да - таймер тоже хорош.

>Любой, позволяющий получать и диспетчеризовать только нужные (а не все подряд) сообщения - Get/PeekMessage + DispatchMessage

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

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

Нет, конечно, иначе бы не было бы никаких вопросов. Поэтому нужно простое окно Windows, без VCL"а.


 
Дмитрий Белькевич ©   (2008-07-18 15:54) [45]

>когда основной поток сильно грузит компьютер дисковыми операциями.

Когда основной, и он же - единственный... То есть всё - и основная работа и обработка прогресс-форма идёт только в нём. Просто, что бы не подумали, что у меня потоков несколько. Он сейчас один. Собсно, с VCL формой по-другому и не сделать.


 
Тын-Дын ©   (2008-07-18 16:38) [46]


> Нет, конечно, иначе бы не было бы никаких вопросов. Поэтому
> нужно простое окно Windows, без VCL"а.


program ProgBar;
//Ляпа ©
uses
 Windows,
 Messages,
 commctrl;

Var Tim:Word;
  hProgressBarWnd:HWND;
  MaxPos,MinPos:WORD;

function MyWndProc(Window:HWND;Mess:word;
       WParam:LongInt;LParam:LongInt):LongInt;stdcall;
 begin
   case Mess of
     WM_CREATE:
           begin
             hProgressBarWnd:=CreateWindow(PROGRESS_CLASS,"",
                      WS_CHILD+WS_VISIBLE,
                      10,75,150,20,window,0,HInstance,nil);
           SendMessage(hProgressBarWnd, PBM_SETRANGE,0,MAKELPARAM(MinPos,MaxPos));
           SendMessage(hProgressBarWnd,PBM_SETSTEP,1,0);
           SendMessage(hProgressBarWnd,PBM_SETPOS,0,0);
           Result:=0;
           end;
     WM_DESTROY:
          begin
//Удаляем таймер
             KillTimer( Window, 1 );
             PostQuitMessage(0);
             Result:=0
          end;
     WM_TIMER:
          begin
              SendMessage(hProgressBarWnd, PBM_STEPIT, 0, 0);
            Result:=0
          end;
     else Result:=DefWIndowProc(Window,Mess,WParam,LParam)
 end;
end;

var
wc:TWndClass;
wnd:HWND;
Msg:TMsg;

PollingDelay:integer=500; //500 - интервал 0.5 сек

begin
//Регистрация класса окна
wc.style:=CS_HREDRAW+CS_VREDRAW;
wc.lpfnWndProc:=@MyWndProc;
wc.cbClsExtra:=0;
wc.cbWndExtra:=0;
wc.hInstance:=HInstance;
wc.hIcon:=LoadIcon(THandle(nil),IDI_APPLICATION);
wc.hCursor:=LoadCursor(THandle(nil),IDC_ARROW);
wc.hbrBackground:=COLOR_BTNFACE+1;//COLOR_WINDOW+1;
wc.lpszMenuName:=nil;
wc.lpszClassName:="MyWndClass";

if (RegisterClass(wc)=0) then exit;
//InitCommonControl(CC: Integer): Boolean;  InitCommonControlsEx
InitCommonControls;
   MaxPos:=100;
   MinPos:=0;
//создаем окно
wnd:=CreateWindow("MyWndClass","Таймер",
   WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,0,CW_USEDEFAULT,0,
   0,0,HInstance,nil);
//Устанавливаем таймер
SetTimer( Wnd, 1, PollingDelay, nil );
//показываем окно
ShowWindow(wnd,SW_RESTORE);
UpdateWindow(wnd);
//начинаем тривиальный цикл сообщений
while GetMessage(Msg,0,0,0) do
begin
 TranslateMessage(Msg);
 DispatchMessage(Msg)
end

end.


 
ANB   (2008-07-18 16:54) [47]


> Вот. Что бы оживить GUI (прогресс-форму), мне в основном
> потоке приходится постоянно в цикле обработки вызывать ProcessMessages.
>
> Во время вызова, как я пониамаю, обрабатываются все сообщения,
>  накопившиеся в очереди. Так вот - иногда в очередь попадают
> нежелательные сообщения, которые должны будут обработаться
> только после того, как основной поток отработает цикл. И
> потерять, или отфильтровать эти сообщения нельзя.

Если нарисовать кнопку отмены и прогресс-бар в окне доп.потока, то это окошко жить будет, а вот основное окно приложения будет висеть. Т.е. его нельзя будет ни сдвинуть ни свернуть. Оно даже перерисовываться не будет.


 
GrayFace ©   (2008-07-18 22:34) [48]

из [38] возьми вот это и вставь вместо Application.ProcessMessages:
while GetMessage(Msg, FWindow, 0, 0) and not Terminated do begin
  TranslateMessage(Msg);
  DispatchMessage(Msg);
end;

FWindow - SuperPuperProgressForm1.Handle. Думаю, поможет.


 
Тын-Дын ©   (2008-07-19 00:41) [49]


> GrayFace ©   (18.07.08 22:34) [48]


Бесполезно. TApplication слишком вросся в TForm.


 
GrayFace ©   (2008-07-19 00:47) [50]

Почему? Я говорю об обработке в главном потоке, без извращений с формой в другом потоке.


 
Сергей М. ©   (2008-07-19 11:54) [51]


> Что бы оживить GUI (прогресс-форму), мне в основном потоке
> приходится постоянно в цикле обработки вызывать ProcessMessages


Да кто ж тебя заставляет для конкретной цели использовать ProcessMessages ?

Нужно перерисовать прогресс-бар ? Просто вызови его метод Update.

Нужно знать не нажал ли юзер "отмену" ? Выбери из очереди и диспетчеризуй только клавиатурные события.

Всего делов-то)


 
MultIfleX   (2008-07-21 06:31) [52]


> Дмитрий Белькевич ©

Тебе надо чтобы пользователь ждал? Так делай Enable формы False, а в конце твоей "длительной обработки" возвращай True, и используй стандартный ProcessMessages, в прЫнципе это для тебя лучший вариант - ни потоков, ни замутов с апи, все просто и функционально. Если это выходит для тебя накладно по времени, попробуй вызывать реже, или по условию что GetTickCount больше "числа Х".


 
Дмитрий Белькевич ©   (2008-07-30 20:27) [53]

Извиняюсь, что долго не отвечал - был в отъезде.

>Выбери из очереди и диспетчеризуй только клавиатурные события.

При диспетчиризации часть очереди будет потеряна, а это неприемлемо.

>Если нарисовать кнопку отмены и прогресс-бар в окне доп.потока, то это окошко жить будет, а вот основное окно приложения будет висеть. Т.е. его нельзя будет ни сдвинуть ни свернуть. Оно даже перерисовываться не будет.

Это не проблема.

>Я говорю об обработке в главном потоке, без извращений с формой в другом потоке.

Интересны новые решения, но не старые догмы.

Нашел между делом функцию CreateDialog, буду пробовать с её помощью показать диалог, что бы на api с окнами не возиться.


 
Сергей М. ©   (2008-07-30 20:38) [54]


> При диспетчиризации часть очереди будет потеряна


Чавой-то ?!

Фигню ты сейчас сморозил.

WinAPI-диспетчеризация - это, если угодно и дословно, вызов DispatchMessage.

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

Т.е. диспетчеризация не имеет никакого отношения к каким-то там "потерям" - у нее иные задачи.


 
Leonid Troyanovsky ©   (2008-07-31 08:44) [55]


> Дмитрий Белькевич ©   (30.07.08 20:27) [53]

> Интересны новые решения, но не старые догмы.

Решение старо как мир: клиент-сервер.

--
Regards, LVT.



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

Форум: "Начинающим";
Текущий архив: 2008.09.14;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.57 MB
Время: 0.043 c
15-1216662669
Пробегал2....
2008-07-21 21:51
2008.09.14
HTML-элемент "checkbox"


4-1196619757
Belorus
2007-12-02 21:22
2008.09.14
CreateFiber


2-1217946143
Krolm
2008-08-05 18:22
2008.09.14
Модуль для создания списка ссылок из html страницы


2-1217453505
Alex_Storm
2008-07-31 01:31
2008.09.14
Добавить строки в ListViev


2-1216308535
Дмитрий Белькевич
2008-07-17 19:28
2008.09.14
Окно - прогресс в отдельном потоке





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский