Страница: 1 |
Страница: 1 |
Вопрос: Как побороть Autoredraw?
Добавлено: 02.09.04 20:17
Автор вопроса:
shareman
Есть PictureBox в котором посредством DrawIcon рисуется множество иконок - скажем, для примера, 750. Если Autoredraw установлен в False, то все происходит очень быстро, но и иконки, как и следовало ожидать, сразу пропадают. Если True - все, конечно видно, но скорость... сами понимаете, запихнуть всю эту кучу в память... Есть какой-нибудь совет? Спасибо.
Ответы
Всего ответов: 9
Номер ответа: 1
Автор ответа: cresta
Вопросов: 117
Ответов: 1538
Профиль | | #1
Добавлено: 02.09.04 22:22
Можно попробовать первый раз отрисовать с False, а когда отрисовка закончится, по нарисованному ещё раз с True. Вторая прорисовка будет медленнее, но это не должно бросаться в глаза, т.к. рисунки уже не меняются.
И ещё: зачем держать в памяти кучу икон? Получил, нарисовал, удалил.
Номер ответа: 2
Автор ответа: shareman
Вопросов: 11
Ответов: 37
Профиль | | #2
Добавлено: 02.09.04 23:00
>И ещё: зачем держать в памяти кучу икон?
Я имел в виду вот это:
AutoRedraw = True - Enables automatic repainting of a Form object or PictureBox control. Graphics and text are written to the screen and to an image stored in memory. The object doesn't receive Paint events; it's repainted when necessary, using the image stored in memory - MSDN
А попробовать сначала False, а потом True - пробовал, конечно, давно, только это ничего не дает.
Номер ответа: 3
Автор ответа: cresta
Вопросов: 117
Ответов: 1538
Профиль | | #3
Добавлено: 02.09.04 23:31
Возможно, у тебя перерисовывается весь пикчербокс при добавлении очередной иконки, т.е. те которые были уже нарисованы, рисуются ещё раз при каждом добавлении, т.к. фактически рисуется весь пикчербокс, а не только последняя добавляемая иконка. Может, попробовать сабклассинг и на WM_PAINT перерисовать только часть пикчербокса, которая требует перерисовки (под последнюю добавляемую икону), а не весь пикчербокс. InvalidateRect позволяет перерисовать кусок hDC, а не весь. А по умолчанию, если кусочек не оговорен, при каждом добавлении она перерисовывает весь hDC, в том числе и уже нарисованные куски. Может отсюда и тормоза?
Номер ответа: 4
Автор ответа: sne
Разработчик Offline Client
ICQ: 233286456
Вопросов: 34
Ответов: 5445
Web-сайт:
Профиль | | #4
Добавлено: 03.09.04 01:51
Можно попробовать поколдовать с UpdateWindow, RedrawWindow, InvalidateRect... Изх них некоторые могут перерисовать и какой-то отлдельный квадрат а не все окно...
Номер ответа: 5
Автор ответа: LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #5
Добавлено: 03.09.04 11:06
В сысле, сразу пропадают? Они хоть рисуются? Если рисуются и исчезают при смене фокуса - сделай перед этим сделай Picture1.Picture=Picture1.Image.
А вообще, лучше сначала создай DC и отрисуй там, а затем уж просто откопируй в PictureBox.
Номер ответа: 6
Автор ответа: cresta
Вопросов: 117
Ответов: 1538
Профиль | | #6
Добавлено: 03.09.04 17:11
Я тут поэкспериментировал, в общем два варианта, один с Set Pic1.Picture = Pic1.Image, второй с InvalidateRect Pic1.hwnd, Rct, 1.
Первый вариант отрисовывает за 3,9 сек. Второй за 0,3. Как говорится, почувствуйте разницу.
Вот оба варианта: количество икон - 1400 с хвостом.
1 вариант (Set Pic1.Picture = Pic1.Image)
 im i As Long, j As Long, hIcon As Long, Rct As RECT, t As Single
hIcon = ExtractAssociatedIcon(App.hInstance, "C:\Autoexec.bat", 2)
Pic1.AutoRedraw = True
t = Timer
For i = 0 To 672 Step 16
For j = 0 To 512 Step 16
 rawIconEx Pic1.hdc, i, j, hIcon, 16, 16, 0, 0, DI_NORMAL
Set Pic1.Picture = Pic1.Image
Next j
Next i
t = Timer - t
 ebug.Print t ' 3.9 сек
2 вариант (InvalidateRect)
 im i As Long, j As Long, hIcon As Long, Rct As RECT, t As Single
hIcon = ExtractAssociatedIcon(App.hInstance, "C:\Autoexec.bat", 2)
Pic1.AutoRedraw = True
t = Timer
For i = 0 To 672 Step 16
For j = 0 To 512 Step 16
SetRect Rct, i, j, i + 16, j + 16
InvalidateRect Pic1.hwnd, Rct, 1
 rawIconEx Pic1.hdc, i, j, hIcon, 16, 16, 0, 0, DI_NORMAL
Next j
Next i
t = Timer - t
 ebug.Print t ' 0,3 сек
Возможно, CreateCompatibleDC тоже ускорит, не пробовал.
Номер ответа: 7
Автор ответа: shareman
Вопросов: 11
Ответов: 37
Профиль | | #7
Добавлено: 03.09.04 22:59
Не-а...
У меня в программе вместе с InvalidateRect (правда у меня там еще много чего по дороге) на 670 иконок срабатывает за 4.16 сек.
А если AutoRedraw = FALSE, тогда за 0.9!!!
Только не видно ничего
Я пытался попробовать сначала бросить все на промежуточный DC, а потом на WM_PAINT вернуть на PictureBox, но что-то не выходит каменный цветок, никакого изображения. Может что-то не так:
Private Sub Command1_Click()
Dim hIcon As Long
Dim Res As Long
Dim hTmpDC As Long
hIcon = ExtractIcon(0&, "C:\windows\notepad.exe", 0)
If hIcon <> 0 Then
hTmpDC = CreateCompatibleDC(Picture1.hdc)
If hTmpDC <> 0 Then
 rawIcon hTmpDC, 0&, 0&, hIcon
Res = BitBlt(Picture1.hdc, 0&, 0&, 32, 32, hTmpDC, 0&, 0&, SRCCOPY)
 estroyIcon hIcon
 eleteDC hTmpDC
End If
End If
End Sub
Номер ответа: 8
Автор ответа: cresta
Вопросов: 117
Ответов: 1538
Профиль | | #8
Добавлено: 04.09.04 10:02
Боюсь, что CreateCompatibleDC не ускорит твоё дело. Может надо посмотреть, что там у тебя "там еще много чего по дороге".
Что за процессор у тебя, сколько ОЗУ, и какие операции выполняются "по дороге"? Уж больно велика разница с тем как рисовалось у меня (если с учетом количества иконок, то в 35 раз медленнее). Там случайно SHGetFileInfo не присутствует?
А на скорость в случае AutoRedraw = FALSE ориентироваться не стоит.
Номер ответа: 9
Автор ответа: shareman
Вопросов: 11
Ответов: 37
Профиль | | #9
Добавлено: 04.09.04 16:55
Все правильно - именно по дороге. Дело в том, что я вместо того, чтобы сразу PictureBox-у поменять высоту на требуемую, менял ее в начале каждого ряда. Как только сделал это один раз, до рисования, все, естественно, встало на свои места - приятно посмотреть. Бывает... Спасибо всем.