Странное поведение TPaintBox
Модератор: Модераторы
Странное поведение TPaintBox
Здравствуйте всем!
Я сделал псевдокнопки на основе TPaintBox, которые меняют свой вид при прохождении над
ними указателя мыши. Все вроде бы работает нормально, но при определенных обстоятельствах,
совершенно бессистемно, из-за чего не могу второй день определить причину, прорисовка
моих псевдокнопок происходит на канвасе формы, то есть при перемещении указателя мыши
над псевдокнопками они перерисовываются совершенно в другом месте, хотя и в определенном.
Происходит это не всегда и не со всеми кнопками.
Реакция на нажатие на кнопку сохраняется, то есть кнопка в исходной позиции сохраняется, перерисовка
не осуществляется, а прорисовывается еще один экземпляр кнопки, который является только картинкой,
но не самой кнопкой. На прилагаемом рисунке можно разглядеть эту ситуацию. Сами кнопки располагаются
в нижней части окна, а дополнительная прорисовка выше и левее.
Может, у кого есть соображения по этому поводу?
Я сделал псевдокнопки на основе TPaintBox, которые меняют свой вид при прохождении над
ними указателя мыши. Все вроде бы работает нормально, но при определенных обстоятельствах,
совершенно бессистемно, из-за чего не могу второй день определить причину, прорисовка
моих псевдокнопок происходит на канвасе формы, то есть при перемещении указателя мыши
над псевдокнопками они перерисовываются совершенно в другом месте, хотя и в определенном.
Происходит это не всегда и не со всеми кнопками.
Реакция на нажатие на кнопку сохраняется, то есть кнопка в исходной позиции сохраняется, перерисовка
не осуществляется, а прорисовывается еще один экземпляр кнопки, который является только картинкой,
но не самой кнопкой. На прилагаемом рисунке можно разглядеть эту ситуацию. Сами кнопки располагаются
в нижней части окна, а дополнительная прорисовка выше и левее.
Может, у кого есть соображения по этому поводу?
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Andrew55
Код нужен, однако, мала-мала...
Код нужен, однако, мала-мала...
Да код, однако, не мала-мала.
Я думаю, что, может, есть общие соображения на этот счет, в смысле принципиальном.
Есть псевдокнопка, которая представляет собой, по сути, TPaintBox, для которого расписаны
процедуры перерисовки на его канвасе градиентной заливки и вывода текста в зависимости
от того, находится ли на нем указатель мыши, произведено ли нажатие на "кнопку" и отработка
события Click. Так почему происходит прорисовка дублирующего изображения не в месте
расположения компонента TPaintBox, а в другой позиции формы?
Кстати, на форме также находится компонент, сделанный на основе TPaintBox, и предназначенный
для рисования графиков (напоминающий TAChart).
Размещал мои "кнопки" на голой форме. В этом случае ложные прорисовки никогда не возникают.
Я думаю, что, может, есть общие соображения на этот счет, в смысле принципиальном.
Есть псевдокнопка, которая представляет собой, по сути, TPaintBox, для которого расписаны
процедуры перерисовки на его канвасе градиентной заливки и вывода текста в зависимости
от того, находится ли на нем указатель мыши, произведено ли нажатие на "кнопку" и отработка
события Click. Так почему происходит прорисовка дублирующего изображения не в месте
расположения компонента TPaintBox, а в другой позиции формы?
Кстати, на форме также находится компонент, сделанный на основе TPaintBox, и предназначенный
для рисования графиков (напоминающий TAChart).
Размещал мои "кнопки" на голой форме. В этом случае ложные прорисовки никогда не возникают.
Общие соображения - где-то путаются объекты.
- dunin
- энтузиаст
- Сообщения: 634
- Зарегистрирован: 02.05.2007 13:18:11
- Откуда: Тољя††и
- Контактная информация:
{$telepathy mode on}
Для получения эффекта: нажимаем на левую (основную) кнопку мыши на псевдокнопке внизу - тянем мышь на график - отпускаем кнопку мыши и получаем ненужную псевдокнопку на графике?
Так? Не?
Для получения эффекта: нажимаем на левую (основную) кнопку мыши на псевдокнопке внизу - тянем мышь на график - отпускаем кнопку мыши и получаем ненужную псевдокнопку на графике?
Так? Не?
Нет, просто при перемещении указателя мыши, без нажатия кнопок мыши, по псевдокнопкам происходит
прорисовка ложного изображения. Любое событие, требующее перерисовки формы, убирает ложные
изображения, но если опять перемещать указатель мыши по псевдокнопкам, ложные изображения
снова появляются.
прорисовка ложного изображения. Любое событие, требующее перерисовки формы, убирает ложные
изображения, но если опять перемещать указатель мыши по псевдокнопкам, ложные изображения
снова появляются.
- Sergei I. Gorelkin
- энтузиаст
- Сообщения: 1409
- Зарегистрирован: 24.07.2005 14:40:41
- Откуда: Зеленоград
Скорее, криво работает сохранение/восстановление состояния канвы и/или преобразование координат. Т.к. PaintBox рисует на канве родителя, процесс происходит примерно так:
1) Сохранить состояние Form.Canvas
2) Переместить начало координат из (0,0) в (PaintBox.Left, PaintBox.Top)
3) Задать регион отсечения, ограничив его значениями (PaintBox.Width, PaintBox.Height)
4) Вызвать PaintBox.Paint
5) Восстановить состояние Form.Canvas, в том числе исходный регион отсечения и начало координат.
Если в результате выполнения этих шагов начало координат "не вернется" в точку (0,0), то следующий компонент может быть нарисован в неправильном месте...
1) Сохранить состояние Form.Canvas
2) Переместить начало координат из (0,0) в (PaintBox.Left, PaintBox.Top)
3) Задать регион отсечения, ограничив его значениями (PaintBox.Width, PaintBox.Height)
4) Вызвать PaintBox.Paint
5) Восстановить состояние Form.Canvas, в том числе исходный регион отсечения и начало координат.
Если в результате выполнения этих шагов начало координат "не вернется" в точку (0,0), то следующий компонент может быть нарисован в неправильном месте...
Сергей, а почему может "криво работать"?
У меня точно такая же проблема. Только я рисую не кнопки, а итемы в TListbox. И именно при перемещении мыши над итемом он рисуется в другом месте и в другом компоненте. Причину я нашел - в событии WMMouseMove значение Self.Canvas.Handle не всегда действительно и бывает даже вообще из другого визуального компонента. Дальнейший поиск баги захлебнулся в дебрях LCL и виджетов. То есть исправить это я не смог и забил на отрисовку по MouseEnter/MouseMove/MouseLeave. Повторяемость была странной - даже откомпилированный .exe то показывал багу, то нет, но чаще показывал.
А как сделать так, чтобы вызов собственной отрисовки не попал между пунктами 1-5 что написал Sergei I. Gorelkin?
А как сделать так, чтобы вызов собственной отрисовки не попал между пунктами 1-5 что написал Sergei I. Gorelkin?
Жаль, что все оказывается так непросто. Думалось, что это я сам где-то ошибся. В кои века
собрался написать свой компонент, и такой облом. Жаль.
Интересно, что баги, о которых я писал, проявляются почти всегда при статусе формы wsMaximized
и почти никогда при других статусах.
собрался написать свой компонент, и такой облом. Жаль.
Интересно, что баги, о которых я писал, проявляются почти всегда при статусе формы wsMaximized
и почти никогда при других статусах.
Было бы полезно (для проекта Lazarus и его пользователей) создать минимальный пример, иллюстрирующий проблему. Буквально отрисовка прямоугольника на в единственном PaintBox, плюс пошаговая инструкция, как гарантированно с помощью этого примера увидеть баг. Всё это можно закинуть в багтрекер, и тогда станет возможным его исправление.
Будет ли это полезно вам - решайте.
P.S.
Ещё, если версия Lazarus старая, можно попробовать обновиться до последнего стабильного снапшота -- http://www.hu.freepascal.org/lazarus/ , lazarus fixes (0.9.29).
Будет ли это полезно вам - решайте.
P.S.
Ещё, если версия Lazarus старая, можно попробовать обновиться до последнего стабильного снапшота -- http://www.hu.freepascal.org/lazarus/ , lazarus fixes (0.9.29).
Кстати, на форме также находится компонент, сделанный на основе TPaintBox, и предназначенный
для рисования графиков (напоминающий TAChart).
А зачем, если не секрет? Почему бы не взять собственно TAChart?
Odyssey писал(а):как гарантированно с помощью этого примера увидеть баг
В том то и дело, что указанный баг вылезает совершенно непредсказуемо, а это
самое неприятное в нашем деле. Была бы стабильность - ухватили бы его за
хвост. Да и обнаружил я ошибку совершенно случайно, думал, что мой проект
завершен, а потом при, наверное, сотом прогоне обнаружил, что "кнопки"
рисуются совершенно не там, где они размещены. Два дня провозился,
но так ничего и не понял, поэтому временно в проблемных местах
вернулся к использованию стандартных кнопок.
К тому же, как я уже писал, при размещении псевдокнопок на голой форме премещение
по ним мыши ни разу не привело к ошибке. Практически никогда также не проявляется,
если окно не максимизировано. Но если будет время, повожусь еще.
Добавлено спустя 4 минуты 57 секунд:
Ask писал(а):А зачем, если не секрет? Почему бы не взять собственно TAChart?
Функционал смещен в нужную для меня сторону.
Функционал смещен в нужную для меня сторону.
Я, собственно, почему спрашиваю -- мне как разработчику интересно знать, чего пользователям не хватает --
может, Я добавлю
Здравствуйте, Ask.
Мы с Вами уже немного соприкасались по поводу TAChart, но тогда я ушел от общения,
сказав, что поразбираюсь с этим компонентом. Правда, может я тупой, но так и не нашел
возможности осуществления градиентной заливки фона графика. Кроме того, меня не
устраивает для масштабирования только "резиновая" линия.
Поэтому я сделал следующее.
1. Возможность градиентной заливки (максимум шестью цветами) как фона графика, так
и фона LeftAxis, BotAxis и Title. На мой взгляд, градиентная заливка не только улучшает
вид графика чисто эстетически, но делает его в ряде случае более выразительным.
2. Масштабирование графика (от 1 и выше) как по вертикали, так и по горизонтали.
В моем случае я для этого использовал (видно на картинке) трек-бары.
3. Скроллинг графика по обеим осям координат. Скроллинг производится как с использованием
скролл-баров, так и перемещением указателя мыши при нажатой левой кнопке.
Скролл-бары не внедрены в компонент, но связываются с ним путем предварительной
инициализации. Перемещение указателя мыши воздействует на скролл-бары.
4. Отображение на одной из панелей статус-бара (на картинках отсутствует) текущего значения
в принятой системе координат положения указателя мыши. Производится это внешними средствами
по отношению к компоненту, а в компоненте для этого имеются функции обратного пересчета
позиции указателя мыши в значения системы координат. Иногда бывает полезно, наведя
указатель мыши в некоторую точку графика, узнать текущее значение в данной точке.
С наилучшими пожеланиями.
А.Захаров.
Мы с Вами уже немного соприкасались по поводу TAChart, но тогда я ушел от общения,
сказав, что поразбираюсь с этим компонентом. Правда, может я тупой, но так и не нашел
возможности осуществления градиентной заливки фона графика. Кроме того, меня не
устраивает для масштабирования только "резиновая" линия.
Поэтому я сделал следующее.
1. Возможность градиентной заливки (максимум шестью цветами) как фона графика, так
и фона LeftAxis, BotAxis и Title. На мой взгляд, градиентная заливка не только улучшает
вид графика чисто эстетически, но делает его в ряде случае более выразительным.
2. Масштабирование графика (от 1 и выше) как по вертикали, так и по горизонтали.
В моем случае я для этого использовал (видно на картинке) трек-бары.
3. Скроллинг графика по обеим осям координат. Скроллинг производится как с использованием
скролл-баров, так и перемещением указателя мыши при нажатой левой кнопке.
Скролл-бары не внедрены в компонент, но связываются с ним путем предварительной
инициализации. Перемещение указателя мыши воздействует на скролл-бары.
4. Отображение на одной из панелей статус-бара (на картинках отсутствует) текущего значения
в принятой системе координат положения указателя мыши. Производится это внешними средствами
по отношению к компоненту, а в компоненте для этого имеются функции обратного пересчета
позиции указателя мыши в значения системы координат. Иногда бывает полезно, наведя
указатель мыши в некоторую точку графика, узнать текущее значение в данной точке.
С наилучшими пожеланиями.
А.Захаров.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
