Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 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-сайт: hw.t-k.ru
 Профиль | | #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)

    ;Dim 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
            ;DrawIconEx Pic1.hdc, i, j, hIcon, 16, 16, 0, 0, DI_NORMAL
            Set Pic1.Picture = Pic1.Image
        Next j
    Next i
    t = Timer - t
    ;Debug.Print t ' 3.9 сек

2 вариант (InvalidateRect)

    ;Dim 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
            ;DrawIconEx Pic1.hdc, i, j, hIcon, 16, 16, 0, 0, DI_NORMAL
        Next j
    Next i
    t = Timer - t
    ;Debug.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
            ;DrawIcon hTmpDC, 0&, 0&, hIcon
            Res = BitBlt(Picture1.hdc, 0&, 0&, 32, 32, hTmpDC, 0&, 0&, SRCCOPY)
            ;DestroyIcon hIcon
            ;DeleteDC 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-у поменять высоту на требуемую, менял ее в начале каждого ряда. Как только сделал это один раз, до рисования, все, естественно, встало на свои места - приятно посмотреть. Бывает... Спасибо всем.

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам