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

Вниз

Timer vs ListBox   Найти похожие ветки 

 
Наталья   (2013-01-21 11:06) [0]

Здравствуйте. При прокрутке ListBox колесом мыши (именно при прокрутке колесом) Работа таймера в программе приостанавливается. Как можно обойти этот не желательный эффект?


 
clickmaker ©   (2013-01-21 11:26) [1]

А что делает таймер?


 
И. Павел ©   (2013-01-21 11:27) [2]

Попробуйте использовать не TTimer а что-нибудь поточнее.
http://delphimaster.net/view/1-70307


 
Наталья   (2013-01-21 11:30) [3]


> clickmaker ©   (21.01.13 11:26) [1]

Timer - читает данные в массив;
PaintBox.OnPaint - рисует график в себе на основании массива.

Данные должны обновляться очень часто.


 
clickmaker ©   (2013-01-21 11:36) [4]

И что, неужели прокрутка может длиться настолько долго, что это критично для графика?


 
Наталья   (2013-01-21 11:45) [5]

Это Mp3 плеер на курсовую. (Визуализация проигрывания трека)

в общих чертах:

procedure TMainForm.TimerRenderTimer(Sender: TObject);
begin
 BASS_ChannelGetData(Channel, @FFTFata, BASS_DATA_FFT1024);
 PaintBox.Repaint;
end;

procedure TMainForm.PaintBoxPaint(Sender: TObject);
begin
 //рисуем данные из @FFTFata
end;


 
Наталья   (2013-01-21 11:46) [6]


> И что, неужели прокрутка может длиться настолько долго,
> что это критично для графика?

Очень не красиво


 
brother ©   (2013-01-21 11:47) [7]

[5]! а причем тут ListBox?


 
brother ©   (2013-01-21 11:51) [8]

http://jqbook.narod.ru/delphi/bass_vis.htm
может чем поможет


 
QAZ10   (2013-01-21 11:58) [9]


>  Как можно обойти этот не желательный эффект?

отключить в винде "плавную прокрутку списков"
либо не использовать соотв. компоненты


 
Наталья   (2013-01-21 13:44) [10]


> brother ©   (21.01.13 11:51) [8]

да не в том дело, все это получается - примеров полно.

Вопрос вот в чем:

есть таймер и листбокс

procedure TForm1.Timer1Timer(Sender: TObject);
begin
i := i + 1;
Form1.Caption := IntToStr(i);
end;


когда мы будем крутить колесо мыши в листбокс, то работа таймера будет приостанавливаться. Вывод переменной I будет рывками.


 
O'ShinW ©   (2013-01-21 13:53) [11]


> procedure TForm1.Timer1Timer(Sender: TObject);
> begin
> i := i + 1;
> Form1.Caption := IntToStr(i);
> end;
>

проблема не воспроизводится


 
O'ShinW ©   (2013-01-21 14:09) [12]


> проблема не воспроизводится


win7, d7
вывод плавный, хоть обкрутись
timer interval = 100
строк в листбокс 10


 
brother ©   (2013-01-21 14:37) [13]

[10] вот чувствую, что дело не в тех кусках кода, что Вы показываете!


 
brother ©   (2013-01-21 14:39) [14]

и не вижу ответа на [7]...


 
Наталья   (2013-01-21 14:42) [15]


> вывод плавный, хоть обкрутись


нет не плавный, попробуйте колесом (если есть)


 
Sha ©   (2013-01-21 14:42) [16]


> Наталья   (21.01.13 13:44) [10]
> когда  мы будем крутить колесо мыши в листбокс, то работа таймера
> будет приостанавливаться. Вывод переменной I будет рывками.


Неправильно i показывать.
Правильно показывать f(GetTickCount), например, (GetTickCount-StartTickCount) div 1000


 
brother ©   (2013-01-21 14:43) [17]

> нет не плавный

будем спорить?


 
brother ©   (2013-01-21 14:43) [18]

> Неправильно i показывать.

хрен с ним как, главное: кто очередь сообщений вешает...


 
Наталья   (2013-01-21 14:49) [19]


> brother ©   (21.01.13 14:39) [14]


Весь модуль и покрутите колесом.


unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ExtCtrls, StdCtrls;

type
 TForm1 = class(TForm)
   Timer1: TTimer;
   ListBox1: TListBox;
   procedure FormCreate(Sender: TObject);
   procedure Timer1Timer(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 i: Integer;
implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 Timer1.Interval := 100;
 i := 0;
 //заполним ListBox1 через инспектор
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
 Inc(i);
 Caption := IntToStr(i);
end;

end.



 
Sha ©   (2013-01-21 14:54) [20]

> Наталья   (21.01.13 14:49) [19]

Попробуйте в FormCreate: StartTickCount:=GetTickCount;
в Timer1Timer: Caption := (GetTickCount-StartTickCount) div 100;


 
Sha ©   (2013-01-21 14:56) [21]

и Timer1.Interval := 50;


 
Наталья   (2013-01-21 15:09) [22]


> Sha ©   (21.01.13 14:54) [20]


Тоже самое - скроллинг колесом вешает вывод.


 
brother ©   (2013-01-21 15:10) [23]

проблемму подтверждаю, но мне кажется пока идет такой скролл вешается все окно...


 
Sha ©   (2013-01-21 15:12) [24]

Не совсем то же самое.
В моем варианте в течение "повешенного" интервала просто нет вывода, но время течет непрерывно.
В вашем варианте время останавливается на время зависания.


 
Наталья   (2013-01-21 15:26) [25]


> Sha ©   (21.01.13 15:12) [24]
>
> Не совсем то же самое.
> В моем варианте в течение "повешенного" интервала просто
> нет вывода, но время течет непрерывно.
> В вашем варианте время останавливается на время зависания.
>


Результат конечный тот же.


 
brother ©   (2013-01-21 15:28) [26]

посмотрел через spy++ на момент "такого" прокручивания окно перестает получать сообщения... значит просто проблемму не решить, или вообще не решаема...


 
Sha ©   (2013-01-21 15:29) [27]

> Наталья   (21.01.13 15:26) [25]
> Результат конечный тот же.

Результатом работы программы является мерцание таймера 10 раз в секунду или нечто другое?
Просто любопытно.


 
Наталья   (2013-01-21 15:29) [28]

Даже такая авантюра не спасает


 while True do
   Application.ProcessMessages;


 
brother ©   (2013-01-21 15:31) [29]

я использовал другой подход к "подвешиванию" окна: нажимаем на колесико и ведем мышь ввех-вниз до любого скролла...


 
Sha ©   (2013-01-21 15:34) [30]

> Наталья   (21.01.13 15:29) [28]
> Application.ProcessMessages;

Пристрелите того гада, который вам это показал.


 
aka   (2013-01-21 15:55) [31]

Уважаемые, я сталкивался с подобной проблемой (кстати тоже писал когда то плеер).

Может я извращенец, но проблему решил заменой ListBox на

ScrollBox и PaintBox.

Я все рано собирался в ListBox через OnDrawItem, рисовать по своему, а в PaintBox это получилось даже как то удобней.

только для прокрутки колесом нужно:

procedure TForm1.ScrollBoxMouseWheel(Sender: TObject; Shift: TShiftState;
 WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
begin
  Handled := True;
  TScrollBox(Sender).VertScrollBar.Position := TScrollBox(Sender).VertScrollBar.Position - WheelDelta;
end;


и учтите, что в ScrollBox нет фокуса. Нужно мудрить самостоятельно, ну хотя бы так
procedure TForm1.ScrollBoxClick(Sender: TObject);
begin
 TScrollBox(Sender).SetFocus;
end;


 
aka   (2013-01-21 15:58) [32]

А сам выводил из в StringList.


 
Sha ©   (2013-01-21 15:59) [33]

> aka   (21.01.13 15:55) [31]

Мне не совсем ясно, зачем нужна визуализация плеера в момент прокрутки.


 
aka   (2013-01-21 16:04) [34]


> Sha ©   (21.01.13 15:59) [33]


Я не знаю что визуализирует автор вопроса. Лично у меня это был спектр частот
И действительно получается не красиво, когда крутишь колесо, а отрисовка останавливается. В идеале этого не должно быть.
Чититать данные для этого можно только таймером, который виснет.


 
Sha ©   (2013-01-21 16:15) [35]

А если, скажем, для отображения списка используется TListView, который во многом ведет себя аналогично TListBox, то придется реализовать весь его функционал вручную?
Гораздо проще применить другое интерфейсное решение, например, сдвиг отображалки спектра за пределы окна на время работы со списком.


 
Плохиш ©   (2013-01-21 16:20) [36]

Из основ программирования под виндовс: События таймеров имеют наинизший приоритет, соответственно выполняются после обработки всех имеющихся/появляющихся в системе событий. Т.ч. прекращайте заниматься онанизмом.


 
aka   (2013-01-21 16:23) [37]


> Sha ©   (21.01.13 16:15) [35]


Кто же спорит. Но если нужно вывести только список, то можно и в PaintBox. Я там еще и процентное выделение текущей песни другим цветом делал в зависимости от времени проигрывания.


 
aka   (2013-01-21 16:29) [38]


> Sha ©   (21.01.13 16:15) [35]

А если прятать прийдется все на свете, ну хотя бы ползунок прогресса проигрывание, ведь его передвижения окромя как таймером не сделать.


 
QAZ10   (2013-01-21 16:30) [39]


> brother ©   (21.01.13 15:28) [26]

а читал ли кто вообще что написано в [9] ???!!!


 
Sha ©   (2013-01-21 16:34) [40]

> aka   (21.01.13 16:29) [38]

Во-первых, сделать.
Во-вторых, есть другое окно.
В третьих, фокус внимания пользователя не может быть одновременно на всем: и на ползунке, и на спектре, и на списке. Решите, с чем он работает, все остальное не важно.


 
aka   (2013-01-21 16:35) [41]


> QAZ10   (21.01.13 11:58) [9]
>
>
> >  Как можно обойти этот не желательный эффект?
>
> отключить в винде "плавную прокрутку списков"
> либо не использовать соотв. компоненты


Ну читали, и что?

1) Отключить программно или вручную.
и то и другое это большие в сто раз ивращение чем моя замена на ScrollBox & PaintBox.

2) Ну и чем же заменить?


 
aka   (2013-01-21 16:37) [42]


>  Sha ©   (21.01.13 16:34) [40]

Это переливание из пустого в порожнее, давайте больше не развивать эту тему.


 
QAZ10   (2013-01-21 16:56) [43]


> Ну и чем же заменить?

listview


 
Наталья   (2013-01-21 18:43) [44]


> listview

Вообще не подходит,


 
QAZ10   (2013-01-21 19:31) [45]

странно :)
99% плейлистов на нем и сделаны


 
aka   (2013-01-21 19:33) [46]


> AZ10   (21.01.13 19:31) [45]
>
> странно :)
> 99% плейлистов на нем и сделаны


Это кто вам такую информацию слил?
а 1% на чем?


 
знайка   (2013-01-21 20:15) [47]


> а 1% на чем?
ScrollBox & PaintBox


 
NoUser   (2013-01-22 04:12) [48]

procedure TForm1.FormMouseWheelDown(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
ListBox1.ItemIndex:= ListBox1.ItemIndex+1;
Handled:=True;
end;

procedure TForm1.FormMouseWheelUp(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
if ListBox1.ItemIndex>0 then
 ListBox1.ItemIndex:=ListBox1.ItemIndex-1;
Handled:=True;
end;



> QAZ10   (21.01.13 11:58) [9]
>

+1


 
brother ©   (2013-01-22 06:17) [49]

[48] не получится так...


 
sniknik ©   (2013-01-22 10:12) [50]

> проблемму подтверждаю, но мне кажется пока идет такой скролл вешается все окно...
сравните с автором установленные в дельфю доп.компоненты... у меня пример (Наталья   (21.01.13 14:49) [19])  ничего не вешает. дельфя (D7) "чистая".


 
sniknik ©   (2013-01-22 10:13) [51]

+
может еще от операционки зависит... все таки события из нее - XP, без схем(классика).


 
sniknik ©   (2013-01-22 10:22) [52]

и кстати проверь, если еще не проверил, вот такой глупый вариант -
type
 TListBox = class(StdCtrls.TListBox)
 protected
   procedure WMMouseWheel(var Msg: TWMMouseWheel); message WM_MOUSEWHEEL;
 end;

 TForm1 = class(TForm)
 ....
 ....

procedure TListBox.WMMouseWheel(var Msg: TWMMouseWheel);
begin
 inherited;
 Application.ProcessMessages;
end;


 
sniknik ©   (2013-01-22 10:33) [53]

хотя нет, все не то (все что выше написал фигня)
ответ тут (словил ситуацию включением, события "кончились")
QAZ10   (21.01.13 11:58) [9]

+ таймер можно заменить на поток.


 
brother ©   (2013-01-22 10:39) [54]

> + таймер можно заменить на поток.

можно конечно, но имхо, при синхронизации с основным потоком приложения (для рефреша например лэйблов), будем также висеть тк, имхо, основной поток в этот момент жестко висит...


 
clickmaker ©   (2013-01-22 10:50) [55]

поток + SendMessage + RedrawWindow(PaintBox.Handle,nil,0,RDW_INVALIDATE or RDW_UPDATENOW)


 
brother ©   (2013-01-22 10:53) [56]

[54] ща проверил, так и получается - висит...


 
brother ©   (2013-01-22 11:07) [57]

[55] проверил - висит...


 
brother ©   (2013-01-22 11:11) [58]

все, я умываю руки, Натальи удачи и прислушайтесь к [9]


 
O'ShinW ©   (2013-01-22 12:39) [59]

блин, ну нет у меня такой проблемы :)
не воспроизводится.

w7, оформление классика, спецэффекты / аеро ( / гидро / космо:) ) - все в 0 / выключено.


 
sniknik ©   (2013-01-22 12:46) [60]

> все в 0 / выключено.
> ответ тут (словил ситуацию включением, события "кончились")


 
QAZ10   (2013-01-22 12:57) [61]


> O"ShinW ©   (22.01.13 12:39) [59]

дело не в том, что у тебя выключено, а в том, что у всех по умолчанию включено


 
O'ShinW ©   (2013-01-22 13:29) [62]


> словил ситуацию включением


> у всех по умолчанию включено

да понял-понял
написал почему не воспроизвелось тогда


 
aka   (2013-01-22 14:34) [63]

Дело в том, что ListView или другие аналогичные компоненты, которые не вещают вывод все используют
procedure WMVScroll(var Message: TWMVScroll); message WM_VSCROLL;

А вот как крутит скролл ListBox нужно смотреть, но точно не так.


 
QAZ10   (2013-01-22 17:46) [64]


> aka   (22.01.13 14:34) [63]

все проще на самом деле, под списком (в руском переводе) в винде подразумеваются 2 элемента - листбокс и комбобокс
и опция плавности их прокрутки это чисто мультик, когда создается битмап и попиксельно сдвигается


 
NoUser   (2013-01-22 19:45) [65]


> brother ©   (22.01.13 06:17) [49]
> [48] не получится так...

Спецом проверил (даж гадкую прокрутку включил) - проблема была, после такого "решения" - не проявлялась.
W7, XE2.


 
brother ©   (2013-01-22 20:13) [66]

w7x64 d7 проблемма остается...


 
aka   (2013-01-23 12:53) [67]

Ну а если таймер в отдельном потоке запустить или так не получится?


 
brother ©   (2013-01-23 13:06) [68]

ты не читатель? уже более худшие варианты испробовали...


 
aka   (2013-01-23 13:34) [69]


> aka   (23.01.13 12:53) [67]
>
> Ну а если таймер в отдельном потоке запустить или так не
> получится?


Нет - не работает. Попробовал создать таймер в отдельном потоке, а эффект остался прежний.



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

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

Наверх





Память: 0.61 MB
Время: 0.003 c
2-1358943395
JohnKorsh
2013-01-23 16:16
2013.10.13
Редактор Арабского текста.


1-1315514533
Дмитрий
2011-09-09 00:42
2013.10.13
Иконки 256x256 и delphi7


2-1358780606
Аскалот
2013-01-21 19:03
2013.10.13
PaintBox и другие


15-1367785803
Юрий
2013-05-06 00:30
2013.10.13
С днем рождения ! 6 мая 2013 понедельник


2-1358839393
ixen
2013-01-22 11:23
2013.10.13
Всплывающая подсказка в JVTrayIcon





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