Форум: "Начинающим";
Текущий архив: 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