Блокируется вывод графической информации

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Блокируется вывод графической информации

Сообщение ger_kar » 03.06.2016 (Пт) 21:14

Встретился с интересным глюком, при котором, если рисовать в PictureBox (а также пробовал непосредственно на форме) при помощи WinApi функций, после первой отрисовки например (как в примере) в событии Form_Load блокируется вывод новой графики (графика не обновляется). Т.е. при обработке события загрузки формы, все прекрасно рисуется, а в дальнейшем при обработке событий мыши уже нет, хотя, если применить один из встроенных в VB графических методов или Refresh, то все опять работает как надо. Вот пример
GDITest.rar
(3.51 Кб) Скачиваний: 139

Если в процедуре LstDrawTextLine обе строки P.Refresh P.PSet (1, 1) закомментированны, то ни шиша не работает вывод графики, для реакции на события мыши. Но стоит убрать комментарий с одной из строк и все оживает. В чем может быть причина такого поведения?
Бороться и искать, найти и перепрятать

The trick
Постоялец
Постоялец
 
Сообщения: 775
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Блокируется вывод графической информации

Сообщение The trick » 03.06.2016 (Пт) 22:17

Потому что у тебя Autoredraw = True. При таком раскладе все GDI функции работают с контекстом в памяти при вызове Refresh перерисовывается из него в окно.
UA6527P

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Блокируется вывод графической информации

Сообщение ger_kar » 04.06.2016 (Сб) 1:47

Хорошо, пусть будет так, но Refresh достаточно тяжелая операция, если посмотреть в отладчике, а тот же Pset достаточно легкая, и тем не менее этот встроенный метод сразу модифицирует отображаемую графику. Другие встроенные графические методы тоже. Значит можно обновить выводимую информацию и без вызова Refresh, как это делает сам VB. Только вот вопрос как?
Бороться и искать, найти и перепрятать

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Блокируется вывод графической информации

Сообщение ger_kar » 04.06.2016 (Сб) 6:52

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

The trick писал(а):Потому что у тебя Autoredraw = True. При таком раскладе все GDI функции работают с контекстом в памяти при вызове Refresh перерисовывается из него в окно.
По идее такая перерисовка же должна происходить при каждой обработке сообщения WM_PAINT, может просто посылать окну такое сообщение?
Бороться и искать, найти и перепрятать

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Блокируется вывод графической информации

Сообщение ger_kar » 04.06.2016 (Сб) 7:19

Вобщем событие WM_PAINT не помогло, равно, как и вызов функции UpdateWindow, зато помог вызов функции
Call RedrawWindow(hWnd, ByVal 0&, 0, RDW_INVALIDATE)
которая сначала помечает область недействительной, а потом сама засылает WM_PAINT. Но вопрос все равно остается открытым, VB6 при вызове, например того же Pset, ничего такого не вызывает (RedrawWindow) и хотелось бы узнать, как это делает сам VB6.
Бороться и искать, найти и перепрятать

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Блокируется вывод графической информации

Сообщение Mikle » 04.06.2016 (Сб) 10:49

PSet - это внутренний псевдометод VB6, при его применении, когда AutoRedraw = True, выставляется флаг, что необходимо выполнить Refresh. На форме ничего сразу не рисуется, а рисуется по приходу DoEvents либо по окончание работы процедуры-обработчика события.
Напиши такую процедуру:
Код: Выделить всё
Private Sub Form_Click()
  Dim x As Long, y As Long

  For y = 0 To 500
'    DoEvents
    For x = 0 To 800
      PSet (x, y)
    Next x
  Next y
End Sub

При AutoRedraw = True квадрат будет появляться сразу весь, а не попиксельно, после окончания работы Sub Form_Click(), если снять ремарку с DoEvents, то рисоваться будет построчно.
Что тебе мешает отказаться от AutoRedraw = True?

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Блокируется вывод графической информации

Сообщение ger_kar » 04.06.2016 (Сб) 11:03

При AutoRedraw = True можно перерисовывать только одну нужную область, а не рисовать все. С ним гораздо удобнее, нежели обрабатывать событие Paint.
Бороться и искать, найти и перепрятать

The trick
Постоялец
Постоялец
 
Сообщения: 775
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Блокируется вывод графической информации

Сообщение The trick » 04.06.2016 (Сб) 12:13

Mikle писал(а):при его применении, когда AutoRedraw = True, выставляется флаг, что необходимо выполнить Refresh

Если быть точнее вызывается InvalidateRect с указанием всей клиентской области.
UA6527P

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Блокируется вывод графической информации

Сообщение ger_kar » 04.06.2016 (Сб) 15:53

The trick писал(а):Если быть точнее вызывается InvalidateRect с указанием всей клиентской области.
Ну, если вызвать Refresh, то да, такая функция вызывается, но при обработке вызова Pset, такая функция не вызывается (имеется ввиду сам метод Pset ), и вызывается InvalidateRect рантаймом уже после возврата из обработчика Pset. Поэтому видимо сначала выставляется флаг внутри рантайма, а уже он впоследствии вызывает InvalidateRect
Бороться и искать, найти и перепрятать

The trick
Постоялец
Постоялец
 
Сообщения: 775
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Блокируется вывод графической информации

Сообщение The trick » 04.06.2016 (Сб) 17:23

ger_kar писал(а):
The trick писал(а):Если быть точнее вызывается InvalidateRect с указанием всей клиентской области.
Ну, если вызвать Refresh, то да, такая функция вызывается, но при обработке вызова Pset, такая функция не вызывается (имеется ввиду сам метод Pset ), и вызывается InvalidateRect рантаймом уже после возврата из обработчика Pset. Поэтому видимо сначала выставляется флаг внутри рантайма, а уже он впоследствии вызывает InvalidateRect

InvalidateRect вызывается после каждого вызова Pset.
UA6527P

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Блокируется вывод графической информации

Сообщение ger_kar » 04.06.2016 (Сб) 17:45

Я думаю вызов RedrawWindow будет хорошей альтернативой, ну или, как вариант можно и Refresh дергать, но если рисование будет полностью на Win API, то вызов API функции будет предпочтительнее. Тогда можно будет писать универсальные процедуры, которые вообще никак не будут зависеть от контролов VB. Вот все и прояснилось, спасибо. Теперь меня интересует вопрос, как реализовать свой AutoRedraw. Пока этот момент видится в общих чертах так: Создавать контекст посредством CreateCompatibleDC, рисовать на нем и обрабатывая сообщение WM_PAINT копировать в контекст экрана для отображения.
Бороться и искать, найти и перепрятать

The trick
Постоялец
Постоялец
 
Сообщения: 775
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Блокируется вывод графической информации

Сообщение The trick » 04.06.2016 (Сб) 18:17

ger_kar писал(а):Теперь меня интересует вопрос, как реализовать свой AutoRedraw. Пока этот момент видится в общих чертах так: Создавать контекст посредством CreateCompatibleDC, рисовать на нем и обрабатывая сообщение WM_PAINT копировать в контекст экрана для отображения.

Ну да. Нужно еще при ресайзе создавать битмап в памяти такого же размера. Можешь вот тут посмотреть как я делал.
http://www.cyberforum.ru/blogs/354370/blog2672.html
UA6527P

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Блокируется вывод графической информации

Сообщение ger_kar » 04.06.2016 (Сб) 19:31

Спасибо, хорошие контролы, мне понравились, буду изучать их устройство
Бороться и искать, найти и перепрятать


Вернуться в Visual Basic 1–6

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

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

    TopList