|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
Опции темы | Поиск в этой теме |
23.01.2011, 11:20 | #1 |
Пользователь
Регистрация: 09.05.2009
Сообщений: 25
|
Проблемы с рисованием в Canvas из отдельного потока
Значится так...
Работаю в BDS 2006, C++ Builder. Рисую на канвасе картинку, которая динамически создается при работе программы. Что бы прорисовка работала не зависимо от моих действий над формой, рисую в отдельном потоке. Если ничего не трогать, все работает отлично, но если, скажем, начать шевелить мышкой, то через некоторое рандомное время картинка перестает перерисовываться. Поток продолжает работать, все счетчики пересчитываются, никаких екзепшенов не посылается, просто не перерисовывается канвас. Провел кучу экспериментов, что бы хоть как-то вычислить событие, после которого возникает косяк (ну, там, при наведении курсора на канвас или нажатие кнопки), никаких причинно-следственных связей не обнаружил. Немного кода: Консруктор класса Demonstration Код:
Код:
Код:
Код:
Иногда мне кажется, что компилятор просто игнорирует все мои комментарии. (с) Bash.org.ru
Последний раз редактировалось Koshmarovsky; 23.01.2011 в 11:23. |
23.01.2011, 11:44 | #2 |
Пользователь
Регистрация: 09.05.2009
Сообщений: 25
|
Опытным путем было выяснено, что косяк возникает при каких-либо действиях с формой, например при движении курсора над ней. Однако от случая к случаю можно с полминуты жимкать на все кнопки и сворачивать-разворачивать окно, и все будет ок, а бывает, что при сдвиге курсора на пиксел картинка замирает (даже если окно не активно). Если курсор в область формы не попадает, все работает.
Иногда мне кажется, что компилятор просто игнорирует все мои комментарии. (с) Bash.org.ru
Последний раз редактировалось Koshmarovsky; 23.01.2011 в 11:47. |
23.01.2011, 12:32 | #3 |
Пользователь
Регистрация: 09.05.2009
Сообщений: 25
|
Дописал прогу малость. Если поток перезапустить (старый снести, новый начать), все снова работает нормально. До поры до времени...
Иногда мне кажется, что компилятор просто игнорирует все мои комментарии. (с) Bash.org.ru
|
23.01.2011, 12:50 | #4 |
Пользователь
Регистрация: 09.05.2009
Сообщений: 25
|
Ан нет! Поток пересоздавать необязательно, можно просто битмап новый сделать в классе Frap... Вот такую функцию написал и на кнопку назначил:
Код:
Иногда мне кажется, что компилятор просто игнорирует все мои комментарии. (с) Bash.org.ru
|
23.01.2011, 13:03 | #5 |
Старожил
Регистрация: 28.01.2009
Сообщений: 21,000
|
а другой поток вообще не должен рисовать
максимум обновлять переменные по которым главный поток сможет перерисовать все как надо, ну и дать главному потоку знать что пора перерисоватся. Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел. Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите. |
23.01.2011, 13:11 | #6 |
Пользователь
Регистрация: 09.05.2009
Сообщений: 25
|
Усмысле?
Не должен - в смысле не будет работать, или в смысле не стоит так делать? Рисовать-то он рисует. Временно сделал так: создаю новый pBitmap каждый раз в функции Draw(), использую, и удаляю. Все работает, на быстродействии никак не сказалось. Но это опять таки костыль, хотя получше, чем предыдущий. Проблем в том, что pBitmap перестает правильно фунциклировать... Хотя указатель на него никуда не девается (ставил BreakPoint, проверял). В чем может быть причина?
Иногда мне кажется, что компилятор просто игнорирует все мои комментарии. (с) Bash.org.ru
|
23.01.2011, 18:21 | #7 |
Старожил
Регистрация: 03.01.2011
Сообщений: 2,508
|
Frap::Draw() следует вызывать через Synchronize().
Т.к. у вас свой поток, а не потомок от TThread, то вместо Synchronize() синхронизируйте 2 потока через 2 события, например. Смысл в том, что вся работа с VCL должна выполняться только из главного потока, иначе будут лезть глюки, описанные в вашем первом сообщении. Кстати, интересно как у вас Demonstration::ThreadLoop() будет работать, ведь при выходе из неё стек очистится на 4 лишних байта.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
|
23.01.2011, 18:49 | #8 | |
Старожил
Регистрация: 28.01.2009
Сообщений: 21,000
|
Цитата:
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел. Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите. |
|
23.01.2011, 19:07 | #9 |
Старожил
Регистрация: 03.01.2011
Сообщений: 2,508
|
Блин, логично )
Ну или надежда на while(1) и TerminateThread()..
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Проблемы с рисованием на TStringGrid | megachuhancer | Общие вопросы Delphi | 10 | 09.02.2011 04:36 |
Многопоточность. Ведение логов из каждого потока. Проблемы | Человек_Борща | Общие вопросы Delphi | 3 | 07.01.2011 18:22 |
Как узнать номер потока из самого потока? | GaMeSTeR | Помощь студентам | 0 | 03.12.2010 09:50 |
Thread. проблемы с работой потока. Моментально исчезают созданные в потоке формы. | Casper-SC | Общие вопросы .NET | 3 | 24.04.2010 12:28 |
Проблема с рисованием на canvas`e Timage (Delphi) | Dalagardi | Помощь студентам | 9 | 25.03.2010 20:55 |