Перерисовка, Refresh(),Invalidate()

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

percilacus
Начинающий
Начинающий
 
Сообщения: 15
Зарегистрирован: 12.07.2009 (Вс) 18:13

Перерисовка, Refresh(),Invalidate()

Сообщение percilacus » 17.08.2009 (Пн) 18:26

Здравствуйте!
Не могу разрешить одну досадную проблему
Составил код для рисования линий мышкой на форме. Идея такова, что когда мышка двигается над формой, срабатывает MouseMove и координаты e.X e.Y становятся концом линии, а перед этим событием MouseDown устанавливаются координаты начала линии.
При каждом наступлении события MouseMove требуется перерисовка. Но вот здесь гемор. Ни Refresh ни Invalidate не помогают и картинка страшным образом мерцает и пропадает.
Помогите.
перцилакус такой маленький а уже знает что такое хорошо а что такое плохо

Williams
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1280
Зарегистрирован: 06.05.2008 (Вт) 18:35
Откуда: System.Reflection.Williams (увидел себя в зеркале :))

Re: Перерисовка, Refresh(),Invalidate()

Сообщение Williams » 17.08.2009 (Пн) 18:28

перерисовывать надо в событии Paint
И вы думаете, что вас оставят в живых после прочтения этого поста?

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Перерисовка, Refresh(),Invalidate()

Сообщение MIT » 17.08.2009 (Пн) 18:37

Всю динамическую графику надо рисовать в буфер, в OnPaint`е же только рендерить буфер на форму.
От мерцания тебя спасет процедура SetStyle контрола, на котором рисуешь (или формы), с набором параметров, равным примерно такому: ControlStyles.AllPaintingInWmPaint, ControlStyles.UserPaint и ControlStyles.OptimizedDoubleBuffer. Ну и ControlStyles.Opaque, если надо.
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

percilacus
Начинающий
Начинающий
 
Сообщения: 15
Зарегистрирован: 12.07.2009 (Вс) 18:13

Re: Перерисовка, Refresh(),Invalidate()

Сообщение percilacus » 18.08.2009 (Вт) 20:15

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

Williams
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1280
Зарегистрирован: 06.05.2008 (Вт) 18:35
Откуда: System.Reflection.Williams (увидел себя в зеркале :))

Re: Перерисовка, Refresh(),Invalidate()

Сообщение Williams » 18.08.2009 (Вт) 21:14

percilacus писал(а):MIT, можно поподробнее. Какой буфер, это класс, модуль? Если модуль какое пространство имен, чтобы о нем я мог прочитать.


Буфер это буфер.
Объект, в котором ты хранишь свою графику. А это может быть Bitmap, стрим, массив байт.
И вы думаете, что вас оставят в живых после прочтения этого поста?

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Перерисовка, Refresh(),Invalidate()

Сообщение MIT » 18.08.2009 (Вт) 21:56

percilacus писал(а):Какой буфер, это класс, модуль?
В самом простом случае можно использовать связку объекта Bitmap и класса Graphics. Для рендеринга можно юзать DrawImageUnscaled.
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

percilacus
Начинающий
Начинающий
 
Сообщения: 15
Зарегистрирован: 12.07.2009 (Вс) 18:13

Re: Перерисовка, Refresh(),Invalidate()

Сообщение percilacus » 19.08.2009 (Ср) 15:50

Ничего не получается.
Короче, вот код:
Код: Выделить всё
Imports System.Drawing.Drawing2D
Public Class Form1
    Dim Gr As Graphics = Me.CreateGraphics
    Dim pen1 As New Pen(Color.Blue, 20)
    Dim thecol As New Collection
    Dim grpath As New GraphicsPath
    Dim last_point As New PointF(Single.NaN, Single.NaN)
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        pen1.MiterLimit = 1.5
    End Sub
    Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
        Select Case e.Button
            Case Windows.Forms.MouseButtons.Left
                If Not Single.IsNaN(last_point.X) Then
                    grpath.AddLine(last_point, New PointF(e.X, e.Y))
                End If
                last_point = New PointF(e.X, e.Y)
            Case Windows.Forms.MouseButtons.Right
                If grpath.PointCount <> 0 Then
                    thecol.Add(grpath)
                    grpath = New GraphicsPath
                End If
                last_point = New PointF(Single.NaN, Single.NaN)
                Invalidate()
        End Select
    End Sub
    Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        If Not Single.IsNaN(last_point.X) Then
            Dim temp_grpath As GraphicsPath = grpath.Clone
            temp_grpath.AddLine(last_point, New PointF(e.X, e.Y))
            Gr.DrawPath(pen1, temp_grpath)
            Invalidate()
        End If
    End Sub
    Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        For Each obj As GraphicsPath In thecol
            Gr.DrawPath(pen1, obj)
        Next
    End Sub
End Class

Не могу избавиться от мерцания.
Если у кого есть желание посмотрите на досуге. Задача очень интересная и очень важная. Иначе какое нормальное приложение можно вообразить с таким мерцанием, непонятно.
перцилакус такой маленький а уже знает что такое хорошо а что такое плохо

percilacus
Начинающий
Начинающий
 
Сообщения: 15
Зарегистрирован: 12.07.2009 (Вс) 18:13

Re: Перерисовка, Refresh(),Invalidate()

Сообщение percilacus » 23.08.2009 (Вс) 19:41

Немного уменьшил мерцание введя в тело процедуры статик переменную, тем самым пореже вызывая злополучный Invalidate
Код: Выделить всё
    Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        Static i As Integer : i += 1 : If i > 5 Then i = 0
        If Not Single.IsNaN(last_point.X) Then
            Dim temp_grpath As GraphicsPath = grpath.Clone
            temp_grpath.AddLine(last_point, New PointF(e.X, e.Y))
            Gr.DrawPath(pen1, temp_grpath)
            If i=5 Then Invalidate()
        End If
    End Sub

Как же тогда, скажем, в AutoCad e не мерцает совсем? Пусть он сделан не на бейсике, но способ значит имеется! А потому и в бейсике должен иметься
перцилакус такой маленький а уже знает что такое хорошо а что такое плохо

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Перерисовка, Refresh(),Invalidate()

Сообщение MIT » 23.08.2009 (Вс) 20:11

Я тебе выше писал что надо сделать, что бы избавиться от мерцания, зачем ерундой заниматься?
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

Alec
Бывалый
Бывалый
 
Сообщения: 275
Зарегистрирован: 31.08.2008 (Вс) 0:15
Откуда: Ростов-на-Дону

Re: Перерисовка, Refresh(),Invalidate()

Сообщение Alec » 23.08.2009 (Вс) 21:54

А зачем прорисовывать все? Мерцание возникает из-за стирания области прорисовки. Попробуй объявлять при MouseMove недействительной только ту область, которая изменилась, ну и соответственно прорисовывать только ее.
Иногда лучше вовремя остановиться...
И начать заново!

Dmitry81
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 52
Зарегистрирован: 20.06.2009 (Сб) 0:43
Откуда: Украина, Запорожье

Re: Перерисовка, Refresh(),Invalidate()

Сообщение Dmitry81 » 23.08.2009 (Вс) 23:44

Никто и не говорит, что надо перерисовывать. РИСУЕМ на Bitmape, который переменная (ну или буфер). А в конце отображем его на нужном контроле. И мерцания не будет.
А вот если рисовать НЕПОСРЕДСТВЕННО на контроле, то тогда жди безбожных тормозов.
А.Эйнштейн: Есть две бесконечные вещи - вселенная и человеческая глупость. Хотя, насчет вселенной я сомневаюсь...

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Перерисовка, Refresh(),Invalidate()

Сообщение MIT » 23.08.2009 (Вс) 23:49

Dmitry81 писал(а):тогда жди безбожных тормозов
Если руки прямые, то ни единого тормоза не будет (если речь не идет про реалтайм-блюр или что-то подобное).
Dmitry81 писал(а):И мерцания не будет
Да ну да прям?
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

Dmitry81
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 52
Зарегистрирован: 20.06.2009 (Сб) 0:43
Откуда: Украина, Запорожье

Re: Перерисовка, Refresh(),Invalidate()

Сообщение Dmitry81 » 24.08.2009 (Пн) 0:06

Или вот: левой кнопкой назначаем стартовую точку, удерживая правую - рисуем веера.
Код: Выделить всё
Public Class Form1
    Dim P1 As Point
    Dim P2 As Point
    Dim pen As New Pen(Color.Black, 1)
    Dim MyGrafix As System.Drawing.Graphics = Me.CreateGraphics
    Private Sub Form1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Left Then
            P1.X = e.X
            P1.Y = e.Y
        End If
    End Sub

    Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Right Then
            P2.X = e.X
            P2.Y = e.Y
            MyGrafix.DrawLine(Me.pen, Me.P1, P2)
        End If
    End Sub
End Class

Или еще: рисует как карандаш в Пейнте.
Код: Выделить всё
Public Class Form1
    Dim P1 As Point
    Dim P2 As Point
    Dim pen As New Pen(Color.Black, 1)
    Dim MyGrafix As System.Drawing.Graphics = Me.CreateGraphics
    Private Sub Form1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
        P1.X = e.X
        P1.Y = e.Y
    End Sub

    Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left Then
            P2.X = e.X
            P2.Y = e.Y
            Me.MyGrafix.DrawLine(Me.pen, P1, P2)
            P1 = P2
        End If
    End Sub
End Class

И заметьте - НИКАКИХ тормозов.
А.Эйнштейн: Есть две бесконечные вещи - вселенная и человеческая глупость. Хотя, насчет вселенной я сомневаюсь...

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Перерисовка, Refresh(),Invalidate()

Сообщение MIT » 24.08.2009 (Пн) 0:34

Я, конечно, извиняюсь, но это ерунда, а не код. Для кого (и для чего) тогда придумали OnPaint?
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

Joo
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 762
Зарегистрирован: 14.08.2008 (Чт) 11:55
Откуда: Казахстан

Re: Перерисовка, Refresh(),Invalidate()

Сообщение Joo » 24.08.2009 (Пн) 5:59

MIT писал(а):Я, конечно, извиняюсь, но это ерунда, а не код. Для кого (и для чего) тогда придумали OnPaint?

Как ни странно это код ;-) причем нормально работающий, я лично в данном случае поступил так-же, ну или почти так-же )
"Им будет не просто, тем кто полагается на истину авторитета, вместо того чтобы полагаться на авторитет Истины"
Джеральд Месси, Египтолог

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Перерисовка, Refresh(),Invalidate()

Сообщение MIT » 24.08.2009 (Пн) 9:47

Нормально? А что будет при обновлении окна (и без мышедвижений)?
Да и использование Me.CreateGraphics довольно непредсказуемая затея.
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

Dmitry81
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 52
Зарегистрирован: 20.06.2009 (Сб) 0:43
Откуда: Украина, Запорожье

Re: Перерисовка, Refresh(),Invalidate()

Сообщение Dmitry81 » 24.08.2009 (Пн) 10:29

Нормальная затея. И потом, я что, должен был за 5 минут выложить готовый на 100% кусок кода, а еще лучше такой себе универсальный модуль... Я дал информацию к размышлению. К тому же код действительно работает, а уж обновление формы (после ее сворачивания, перекрытия чем-то иным...) можно и самому прикрутить.
А.Эйнштейн: Есть две бесконечные вещи - вселенная и человеческая глупость. Хотя, насчет вселенной я сомневаюсь...

MIT
Мега гуру
Мега гуру
Аватара пользователя
 
Сообщения: 2211
Зарегистрирован: 17.09.2006 (Вс) 22:46

Re: Перерисовка, Refresh(),Invalidate()

Сообщение MIT » 24.08.2009 (Пн) 11:01

Да делай как хочешь, зачем делать как полагается, когда всегда есть вариант "через задницу" :wink:
Все, я ушел.
Изображение
You can change your face, but can`t change your mind. No matter what you do.
Создайте еще более понятный интерфейс и мир создаст еще более тупого юзера. (с) Баш

Dmitry81
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 52
Зарегистрирован: 20.06.2009 (Сб) 0:43
Откуда: Украина, Запорожье

Re: Перерисовка, Refresh(),Invalidate()

Сообщение Dmitry81 » 24.08.2009 (Пн) 11:09

Ну так покажи, КАК полагается!
А.Эйнштейн: Есть две бесконечные вещи - вселенная и человеческая глупость. Хотя, насчет вселенной я сомневаюсь...

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Re: Перерисовка, Refresh(),Invalidate()

Сообщение Nord777 » 24.08.2009 (Пн) 11:34

MIT писал(а):Да и использование Me.CreateGraphics довольно непредсказуемая затея.
И чем же, по твоему, она непредсказуема?
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

percilacus
Начинающий
Начинающий
 
Сообщения: 15
Зарегистрирован: 12.07.2009 (Вс) 18:13

Re: Перерисовка, Refresh(),Invalidate()

Сообщение percilacus » 24.08.2009 (Пн) 18:32

MIT писал(а):Я тебе выше писал что надо сделать, что бы избавиться от мерцания, зачем ерундой заниматься?

Ну пробовал я и двойную буферизацию хот я в ней и ничего не понимаю, и Control.SetStyle со всеми его пришлепками как ты указывал, но ничего не получается. Если сможешь, исправь код и выложи работающий и будет тебе счастье
перцилакус такой маленький а уже знает что такое хорошо а что такое плохо


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 75

    TopList  
cron