![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Окно - прогресс в отдельном потоке [D7, WinXP]
Дмитрий Белькевич © (2008-07-17 19:28:00)Нужно реализовать простую прогресс-форму с прогресс баром, небольшой картинкой и кнопкой прерывания процесса.
Нужно, что бы она работала в отдельном потоке.
То, что обычные формы работать в потоке не будут, знаю.
То что рекомендуют выносить код в поток знаю. Но не представляется возможным - прогресс применяется где-то в 25-30 местах и делать 30 разных потоков нецелесообразно.
Переделываю с обычной формы, так как применение processmessages не всегда допустимо, и при долгом процессе часто бывает, что форма прогресса не реагирует на вызов 'hide', оставаясь 'висеть'.
Может быть кто-то видел готовое решение, скорее всего, как я понял, на API. Несколько часов гугленья не принесли результата.
Германн (2008-07-18 01:57:00) [41]
> Дмитрий Белькевич © (18.07.08 01:34) [13]
>
> Посмотрел.
> Окна - формы VCL. Для корректной отрисовки и реализвации
> реакции на кнопку, ессно, им нужен Application.ProcessMessages.
> От ProcessMessages я, среди прочего, хочу избавится.
>
Туда же. Ну почитай наконец книжки.
Ну какой смысл использовать доппоток в данном случае?
Германн (2008-07-18 01:42:00) [42]
> Дмитрий Белькевич © (18.07.08 00:45) [8]
>
> >У тебя кошмарная каша в голове - "форму .. что бы она работала
> в отдельном потоке"
>
> Извиняюсь, окно... дальше по тексту.
>
Книжки читай.
Иначе так запорешь чушь, что вышеназванная тебя привлёчёт по суду.
:)
Дмитрий Белькевич (2008-07-18 01:34:00) [43]Посмотрел.
Окна - формы VCL. Для корректной отрисовки и реализвации реакции на кнопку, ессно, им нужен Application.ProcessMessages. От ProcessMessages я, среди прочего, хочу избавится.
Дмитрий Белькевич (2008-07-18 01:16:00) [44]Спасибо.
Amoeba (2008-07-18 01:08:00) [45]Послал на contact@makhaon.com
Дмитрий Белькевич (2008-07-18 00:56:00) [46]
> Выслал автору вопросу пару демок.
Спасибо, но, к сожалению, ничего не получил...
Дмитрий Белькевич (2008-07-18 00:55:00) [47]Еще немного поискал.
Вот хочется нечто такое, только 'с прогресс баром, небольшой картинкой и кнопкой прерывания процесса'
type
TT=class(TThread)
private
FStopEvent:THandle;
FWaitTime:DWORD;
protected
procedure Execute;override;
procedure Stop;
end;
implementation
var
Z:integer;
function WndProc(wnd:HWND; msg:UINT; w:UINT; l:UINT):UINT;stdcall;
var
dc:HDC;
cr:TRect;
ps:PAINTSTRUCT;
str:string;
begin
case msg of
WM_PAINT:
begin
BeginPaint(wnd,ps);
GetClientRect(wnd,cr);
str:=IntToStr(Z);
DrawText(ps.hdc,PChar(str),Length(str),cr,DT_CENTER or DT_VCENTER or DT_SINGLELINE);
EndPaint(wnd,ps);
end
else
Result:=DefWindowProc(wnd,msg,w,l);
end;
end;
procedure TT.Stop;
begin
SetEvent(FStopEvent);
WaitFor;
end;
procedure TT.Execute;
var
msg:TMsg;
wnd:HWND;
wc:WNDCLASS;
lastTick:DWORD;
procedure OnIdle;
begin
if GetTickCount-LastTick>FWaitTime then
begin
LastTick:=GetTickCount;
InterlockedIncrement(Z);
InvalidateRect(wnd,nil,true);
end;
end;
begin
wc.style:=0;
wc.cbClsExtra:=0;
wc.cbWndExtra:=0;
wc.hInstance:=hInstance;
wc.hIcon:=0;
wc.hCursor:=0;
wc.hbrBackground:=GetStockObject(LTGRAY_BRUSH);
wc.lpszMenuName:=nil;
wc.lpszClassName:='TESTCLS';
wc.lpfnWndProc:=@WndProc;
Windows.RegisterClass(wc);
wnd:=CreateWindow('TESTCLS','Hello world',WS_CAPTION,CW_USEDEFAULT,CW_USEDEFAULT,200,80,HWND_DESKTOP,0,hInstance,ni l);
ShowWindow(wnd,SW_NORMAL);
UpdateWindow(wnd);
FStopEvent:=CreateEvent(nil,false,false,nil);
FWaitTime:=100;
lastTick:=GetTickCount;
while not Terminated do
begin
OnIdle;
case MsgWaitForMultipleObjects(1, FStopEvent, False, FWaitTime, QS_ALLEVENTS) of
WAIT_OBJECT_0:Terminate;
WAIT_OBJECT_0+1:
while PeekMessage(msg, 0, 0, 0, PM_REMOVE) do
begin
TranslateMessage(msg);
DispatchMessage(msg);
end;
end;
end;
DestroyWindow(wnd);
CloseHandle(FStopEvent);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
with TT.Create(true) do
begin
FreeOnTerminate:=true;
Resume;
end;
end;
Дмитрий Белькевич (2008-07-18 00:45:00) [48]>У тебя кошмарная каша в голове - "форму .. что бы она работала в отдельном потоке"
Извиняюсь, окно... дальше по тексту.
Amoeba (2008-07-18 00:39:00) [49]Выслал автору вопросу пару демок.
Германн (2008-07-18 00:14:00) [50]
> У тебя кошмарная каша в голове - "форму .. что бы она работала
> в отдельном потоке"
Целиком и полностью +
Loginov Dmitry (2008-07-17 23:52:00) [51]
> сам понял, что написал ?
написано коряво, но суть надеюсь понятна.
Неприятный эффект может проявится например в следующем коде:
with TProgressViewer.Create(...) do
try
Sleep(500);
finally
Terminate;
end;
Form1.ShowModal;
в результате активным может оказаться любое окно на рабочем столе, а Form1 имеет шанс оказаться на заднем плане. В данном случае проблем больше из-за особенностей TProgressViewer, чем из-за винды.
Однако если сделать задержку >= 5 секунд, то Windows считает основной поток зависшим, и в некоторыхслучаях может передать фокус какому либо другому окну. Случаи же бывают разные.
Игорь Шевченко (2008-07-17 23:39:00) [52]
> После таких окон винда в некоторых случаях может передать
> фокус рандомно любому расположенному на рабочем столе окну.
>
сам понял, что написал ?
Loginov Dmitry (2008-07-17 23:34:00) [53]
> Может быть кто-то видел готовое решение, скорее всего, как
> я понял, на API. Несколько часов гугленья не принесли результата.
>
http://matrix.kladovka.net.ru/index.php?page=downloads&categ=other&pagenum=1
только будь осторожен. Там используется окна типа topmost (поверх всех). После таких окон винда в некоторых случаях может передать фокус рандомно любому расположенному на рабочем столе окну. Но скорее всего у тебя этот эффект не проявится.
Сергей М. (2008-07-17 20:57:00) [54]Пойми, дружок, что форма - это в огороде бузина, а поток - это в Киеве дядька.
Сергей М. (2008-07-17 20:56:00) [55]
> Несколько часов гугленья не принесли результата
Значит ты не в тот огород гуглил)
Скажу больше - нет такого огорода.
Как ни гугли)
У тебя кошмарная каша в голове - "форму .. что бы она работала в отдельном потоке"