![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
||||
|
||||
|
Всем привет. Я сделал прогу, в которой заполняется ProgressBar. Код такой:
Код:
While Form1.ProgressBar1.Position<100 do Begin a:=random(15); Form1.ProgressBar1.Position:=Form1.ProgressBar1.Position+a; Sleep(3000); Application.ProcessMessages; End; Все в принципе работает, но! - при работе прогрессбара виснет главная форма. То есть на ней ничего нельзя сделать, даже закрыть. Пробовал поставить Application.ProcessMessages (вроде должно помочь) - не помогает... Кто знает - подскажите, как быть? ЗЫ. Сорри, если не там тему создал, я тут новичек еще) |
|
#2
|
|||
|
|||
|
Виснет оно у тебя на sleep(3000).
Сделай так: Код:
var
i : Integer;
While Form1.ProgressBar1.Position<100 do
Begin
a:=random(15);
Form1.ProgressBar1.Position:=Form1.ProgressBar1.Position+a;
For i := 1 To 30 Do
Begin
Sleep(100);
Application.ProcessMessages;
End;
End; |
|
#3
|
||||
|
||||
|
Цитата:
P.S. Sleep(3000) - вроде на 3 секунды "усыплять" должно? |
|
#4
|
|||
|
|||
|
Ну да, вот оно и усыпляет. Т.е. блокирует выполнение.
Если совсем не помогает (хотя должно), то тогда переделывай на потоки (TThread). Хотя вот такой фокус вполне дает возможность манипулировать с интерфейсом, хотя все и выполняется в одном, главном, потоке программы. |
|
#5
|
||||
|
||||
|
Цитата:
|
|
#6
|
||||
|
||||
|
Да нафига вы вообще его усыпляете? Уберите вообще вызов Sleep. Вам дали не вешающую альтернативу - Application.ProcessMessages, вот ей и пользуйтесь.
|
|
#7
|
||||
|
||||
|
Цитата:
Цитата:
|
|
#8
|
|||
|
|||
|
На самом деле, Application.ProcessMessages позволит только обработать сообщения, которые становятся в очередь. Естественно, такой код НЕ ПОЗВОЛИТ ПАРАЛЛЕЛЬНО выполнять еще какие-либо задачи. Для этого сущетсвуют потоки.
По потокам - воспользуйся поиском (недавно были по ним темы) и, конечно, читай документацию. Там все достаточно просто. |
|
#9
|
||||
|
||||
|
Тогда вам надо не Sleep выполнять, а самому нужный промежуток времени отслеживать:
Код:
StartTime := GetTickCount;
While Form1.ProgressBar1.Position<100 do
Begin
a:=random(15);
if GetTickCount - StartTime >= 3000
then begin
Form1.ProgressBar1.Position:=Form1.ProgressBar1.Position+a;
StartTime := GetTickCount;
end;
Application.ProcessMessages;
End; |
|
#10
|
||||
|
||||
|
ты сделай какую нибудь долгую процедуру и проверь можно ли пользоваться окном при работе БАРА (естественно убрав слип) если можно убирай слип напрочь нельзя ищи другой вариант
надеюсь этот ответ поможет тебе и всем че-нибудь понять ![]() |
|
#11
|
||||
|
||||
|
Вопрос - как именно заставить поток двигать бар? http://www.delphikingdom.com/asp/vie...catalogid=1370 - я читал эту статью, жму File - New - Thread Object, а дальше что делать то? Я пробовал в код
Код:
procedure Thread.Execute;
begin
{ Place thread code here }
end;Код:
While Form1.ProgressBar1.Position<100 do Begin a:=random(15); Form1.ProgressBar1.Position:=Form1.ProgressBar1.Position+a; Sleep(3000); Application.ProcessMessages; End; Код:
Stream:=TNewThread.Create(true); Stream.FreeOnTerminate:=true; Stream.Priority:=tpLower; Stream.Resume; Добавляю в начало процедуры Код:
procedure TForm2.Button1Click(Sender: TObject); Stream: TNewThread; begin Ну и т.п. Кто нибудь знает, как правильно сделать? |
|
#12
|
||||
|
||||
|
P.S. У меня всего 3 формы в программе, бар на первой форме... Кнопка, которая должна его запустить - на второй... Это я так, на всякий случай - может, я как то не так связь между формами сделал...
|
|
#13
|
||||
|
||||
|
Модуль потока
Код:
unit UNewThead;
interface
uses
Classes;
type
TNewThead = class(TThread)
private
{ Private declarations }
FPos: Integer;
procedure SetPos();
protected
procedure Execute; override;
public
constructor Create();
end;
implementation
uses SysUtils, Unit1;// прописываем модуль Form1
{ TNewThead }
constructor TNewThead.Create;
begin
inherited Create(true);
FreeOnTerminate:=true;
Priority:=tpLower;
Resume;
end;
procedure TNewThead.Execute;
begin
{ Place thread code here }
FreeOnTerminate:=true;
FPos := 0;
while FPos < 100 do
begin
Synchronize(SetPos);
Inc(FPos, random(15));
Sleep(3000);
end;
end;
procedure TNewThead.SetPos;
begin
Form1.ProgressBar1.Position := FPos;
FPos := Form1.ProgressBar1.Position;
end;
end.В модуле второй формы Код:
implementation uses SysUtils, UNewThead; // прописываем модуль потока procedure TForm2.Button1Click(Sender: TObject); Stream: TNewThread; begin Stream:=TNewThread.Create(); end; |
|
#14
|
|||
|
|||
|
Создай на форме таймер(TTimer). В обработчик события OnTimer(два раза клацни по таймеру) напиши:
Код:
a := random(15); Form1.ProgressBar1.Position := Form1.ProgressBar1.Position + a; Timer1.Interval := random(3000); if Form1.ProgressBar1.Position > = 100 then begin Timer1.Enabled := false; // Другие события, которые должны выполнятся при заполнении прогрессБара end; Этот метод самый простой и самый надежный. Моя аська 398202116, можеш написать в аську, я подробней опишу. Последний раз редактировалось Admin, 28.01.2010 в 10:17. |
|
#15
|
||||
|
||||
|
Цитата:
Подставляем в место Код:
// Другие события, которые должны выполнятся при заполнении 3 секунды чтото выполняем с подвисанием формы, потом random(3000) миллисекунд ничего не делаем - но можно нажать на форму. и так пока все не сделаем. если же в TNewThead.Execute; вместо Sleep(3000); подставить действие на 3 секунды - то оно будет выполняться в фоне и прерываться только на установку шкалы. Немного доделать TNewThead и можно в фоне выполнять что то полезное с возможностью прерывания. Последний раз редактировалось s0Creator, 28.01.2010 в 09:57. |