Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Как сделать задумчивый курсор?


Автор: Kbl4AH 8.12.2008, 16:42
Здравствуйте.
Подскажите, плиз.
У меня по нажатию кнопок в окне программа довольно долго думает.
Мне бы хотелось, чтоб во время раздумий был курсор - песочные часики.
Делаю:
Код

procedure TFMain.Button1Click(Sender: TObject);
begin
  Cursor := crHourGlass;
  ...
  ...
  ...
  Cursor := crDefault;
end;
, но ничего не происходит. Почему так?

Автор: CodeMonkey 8.12.2008, 17:40
Как насчёт:
Код
procedure TFMain.Button1Click(Sender: TObject);
begin
  Screen.Cursor := crHourGlass;
  try
    Application.ProcessMessages;
    ...
  finally
    Screen.Cursor := crDefault;
  end;
end;

?

Автор: Kbl4AH 10.12.2008, 15:39
CodeMonkey, спасибо, все хорошо.
А можно пояснить, что это: 
Код

Application.ProcessMessages;
?

Автор: Poseidon 10.12.2008, 15:49
ProcessMessages позволяет выполнить очередь сообщений, которые накапливаются для приложения.

Автор: Kbl4AH 10.12.2008, 15:57
Ага, это я понял.
Код

Многие начинающие программисты не знают о методе Application.ProcessMessages() и сталкиваются
с проблемами, которых не могут объяснить. Например хотим написать что-то на форме и через 5 секунд стереть.
Нужно сделать так:
--------------------------------------------------------------------------------
Procedure TForm1.Button1Click(SEnder: TObject);
Begin
Label1.Caption:='Started';
Application.ProcessMessages();
sleep(1000);
Label1.Caption:='Finished';
End;
Попробуйте убрать Application.ProcessMessages() и 'Started' вы никогда не увидите,
это связано с тем, что Windows ждет пока накопятся задачи в очереди
а не выполняет их сразу, Application.ProcessMessages() заставляет выполнить
все задачи которые накопились в данный момент.
Подробнее читайте в Help.
Это также можно применить в таком примере:
--------------------------------------------------------------------------------
Procedure TForm1.Button1Click(SEnder: TObject);
Var i: integer;
Begin
For i:=1 to 100000 do Application.ProcessMessages();
End;
если не будет ProcessMessages() то пока крутится цикл мы не сможем сдвинуть или свернуть форму.

Только мне не понятен 2-й пример? Почему так?
И что, теперь Application.ProcessMessages после каждой конструкции писать нужно?
И зачем в примере CodeMonkey вставлен try finally?

Автор: Poseidon 10.12.2008, 16:07
Цитата(Kbl4AH @  10.12.2008,  15:57 Найти цитируемый пост)
Только мне не понятен 2-й пример? Почему так?
В примере просто показывается, что даже когда работает цикл (читай, выполняются ресурсоемкие действия) сообщения для приложения обрабатываются. Т.е. его можно "тягать", жмакать на кнопочки. А если ProcessMessages убрать, то пока цикл не выполнится, приложение не будет отвечать, т.е. появится ощущение что программа зависла.

Цитата(Kbl4AH @  10.12.2008,  15:57 Найти цитируемый пост)
И зачем в примере CodeMonkey вставлен try finally?
А вдруг у тебя там ошибка времени выполнения. Что тогда будет, без try finally? Курсор обратно кто менять будет? А с try finally есть гарантия, что даже при ошибках курсор будет изменен на crDefault

Автор: Kbl4AH 10.12.2008, 16:16
Цитата(Poseidon @ 10.12.2008,  17:07)
А вдруг у тебя там ошибка времени выполнения.

Что значит вдруг? Я для этого программу и отлаживаю, чтоб их не было...
Получается - 
с одной стороны, везде нужно втыкать Application.ProcessMessages и try..finally,
а с другой, они усложняют программу.
Нужно искать золотую середину?

Автор: CodeMonkey 10.12.2008, 16:16
А книжу в руки не проще взять? 
Или хотя-бы электронный вариант? http://www.delphikingdom.ru/lyceum/seminar.asp?ID=6-там?

Автор: Kbl4AH 10.12.2008, 16:23
Цитата(CodeMonkey @ 10.12.2008,  17:16)
А книжу в руки не проще взять? 
Или хотя-бы электронный вариант?

Да я уж почитал про try..except..finally в нете...
Только не понял зачем это в конкретном примере?
Ведь для того, что бы ситуаций не возникало не нужных, защита от дураков и делается...
А то читаю форум и везде на этот try..finally натыкаюсь...
Создается чувство, что это какая-то дань модному стилю...
Хотя, наверняка, я ошибаюсь...

Добавлено через 3 минуты и 54 секунды
Цитата(CodeMonkey @  10.12.2008,  17:16 Найти цитируемый пост)
 Мануал-там

Отдельное спасибо!

Автор: Kbl4AH 10.12.2008, 16:50
Фишка была в том, чтобы написать не Cursor :=;
а именно Screen.Cursor.

Автор: THandle 10.12.2008, 18:14
Цитата(Kbl4AH @  10.12.2008,  16:23 Найти цитируемый пост)
А то читаю форум и везде на этот try..finally натыкаюсь...
Создается чувство, что это какая-то дань модному стилю...


Ошибка может возникнуть где угодно, надо предохраняться.

Автор: MetalFan 11.12.2008, 13:23
Цитата(Kbl4AH @  10.12.2008,  15:57 Найти цитируемый пост)
Procedure TForm1.Button1Click(SEnder: TObject);
Begin
Label1.Caption:='Started';
Application.ProcessMessages();
sleep(1000);
Label1.Caption:='Finished';
End;
Попробуйте убрать Application.ProcessMessages() и 'Started' вы никогда не увидите,

кста, можно наверняка менее ресурсоемко "перерисоваться". например так:
Код

Label1.Caption:='Started';
Label1.Update;
sleep(1000);
Label1.Caption:='Finished';

Автор: Poseidon 11.12.2008, 16:34
Цитата(Kbl4AH @  10.12.2008,  16:16 Найти цитируемый пост)
Что значит вдруг? Я для этого программу и отлаживаю, чтоб их не было...
Мне вот интересно, как отладкой выловить, к примеру, "Out of memory"? Они на то и "времени выполенния", что возникают не постоянно. Вот случится у тебя такое и что тогда? Придется перегружать программу, что бы вернуть курсор в начальное значение.

Автор: Kbl4AH 11.12.2008, 16:37
Цитата(Poseidon @  11.12.2008,  17:34 Найти цитируемый пост)
Мне вот интересно, как отладкой выловить, к примеру, "Out of memory"? Они на то и "времени выполенния", что возникают не постоянно. Вот случится у тебя такое и что тогда? Придется перегружать программу, что бы вернуть курсор в начальное значение.

каюсь

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)