Текущий архив: 2005.07.11;
Скачать: CL | DM;
ВнизCanvas does not allow drawing Найти похожие ветки
← →
Darklight © (2005-03-11 15:51) [0]Через некотороевремя работы приложения возникает следующая ошибка:
Canvas does not allow drawing
Код:
self.PB.Canvas.Draw(0,0,BM);
Расшифровка:
slef - TFrame
PB - TPaintBox
BM - TBitmap
Вывод изображений идёт ТОЛЬКО в один PB
Других элементов, содержащих картинки нет. PB развёрнут почти на всю форму (фрейм).
Данный код написан в обработчике событий onMouseMove
Так же ещё есть, похожий код, выводящий изображения в обработчике onTimer, но там ошибка не возникает!
BM - некоторое изображение - подготавливаемое отдельно.
Наряду с возникновением ошибки выводимое изображенпе (или PB, т.к. BM по размеру и посодержимому с ним совпадает и служит лишь буфером для предотвращения мерацания) начинает СКАКАТЬ ПО ВСЕМУ ЭКРАНУ, а некоторые выводимые элементы изображения не выводятся или даже МЕНЯЮТ ЦВЕТ!!!
BM формируется в ручную при помощи рисования на канве!
Перепробывал много способов ничего не помогает!
Если данную строку заремить и выводить изображение только по таймеру, то всё ОК!
Событие возникает периодически и обычно после продолжительной работы ОДНОГО экземпляра приложения. Система windows 2000.
Компьютер очень мощный с большим количеством памяти (оперативной, видео...).
← →
WondeRu © (2005-03-11 17:17) [1]попробуй:
self.PB.Canvas.Lock;
try
...
здесь рисуем!!!
..
finally
self.PB.Canvas.UnLock;
end;
← →
MBo © (2005-03-11 17:31) [2]проблема, скорее всего, не в этом коде, а в подготовке и неосвобождении битмапов - выжираются ресурсы GDI
← →
programania © (2005-03-11 23:41) [3]>Данный код написан в обработчике событий onMouseMove
Может он начинает выполняться, когда еще не кончился
предыдущий вывод, тогда может быть что угодно.
Надо помечать что выполняется и обходить.
← →
Darklight © (2005-03-12 11:23) [4][1] Попробую!
[2] BM - Bitmap создаётся ОДИН раз по собитию onCreate на форме и уничтожается ОДИН раз по событию onDestroy на форме и вообще является переменной формы.
[3] В однопоточных приложениях два события не могут выполняться одновременно. Если отрабатывает событие onTime (перерисовывает изображение), и есть движение мыши на PaintBoxm - е, то пока не отработае onTime событие onMouseMove не возникнет! И наоборот. Ttimer не создаёт нового потока для обработки событий!
← →
programania © (2005-03-12 23:22) [5]>В однопоточных приложениях два события не могут выполняться одновременно.
Верно, одно из них будет остановлено в случайном месте
и если второе это тоже самое onMouseMove то тот же код
начнет рисовать недорисованный canvas, а это ни к чему
хорошему не приведет.
>пока не отработае onTime событие onMouseMove не возникнет!
С таким убеждением вас ждут сюрпризы, когда
переменные будут внезапно меняться вроде как сами по себе.
А как же тогда по вашему можно остановить работающую программу
нажатием кнопки?
Вот пример показывает что все события запускается независимо
от того закончилась ли обработка предыдущего:
procedure TForm1.Button1Click(Sender: TObject);
var i:dWord;
begin
i:=GetTickCount+20000;
while GetTickCount<i do begin
label1.caption:=intTostr((i-GetTickCount) div 1000);
application.processMessages;
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
label1.top:=label1.top+20;
end;
>Ttimer не создаёт нового потока для обработки событий
Потоки это участки кода переключаемые windows по времени.
События запускаются и преключаются внешними причинами
потоков им не надо, но запускаться и работать
они обязаны когда эти причины произойдут,
а все остальное будет стоять пока не закончится
последнее возникшее или не возникнет новое.
← →
wicked © (2005-03-14 10:53) [6]
> Верно, одно из них будет остановлено в случайном месте
> и если второе это тоже самое onMouseMove то тот же код
> начнет рисовать недорисованный canvas, а это ни к чему
> хорошему не приведет.
бред...
← →
Анонимщик1 (2005-03-14 11:52) [7]programania
Ты же своим ProcessMessages насильно выбираешь и обрабатываешь сообщение из очереди - код бы глянул. Ну, хорошо, предположим на секунду, что ты прав. Но ведь тогда пришлось бы синхронизировать функции, вызванные в контексте одного (скажем, главного) потока, в плане разделения ресурсов. Ты сам-то так когда-нибудь делал? Короче, думай, что говоришь.
Darklight
Ты уверен, что приложение однопоточное? Что оно из себя представляет? Какие классы (особенно не свои и не-борландовские) используешь?
← →
Darklight © (2005-03-14 13:20) [8]Полностью согласен с [6] и [7]
Нет других потоков.
Классы только мои и обычные борлондовские (типа TObjecList)
Приложение - типа графического редактора.
Визуализационная часть достаточно простая, но на канве битмапа производится наложенная отрисовка большого количества примитивов и выводится текст.
← →
Анонимщик1 (2005-03-14 13:33) [9]Тогда посмотри какой-нибудь утилитой утечку графических ресурсов.
← →
Darklight © (2005-03-14 14:16) [10]Какой?
Никода о них не слышал?
← →
WondeRu © (2005-03-14 14:51) [11]VTune
← →
Анонимщик1 (2005-03-14 14:57) [12]Посмотреть можно хотя бы с помощью диспетчера задач, только нужно выбрать столбцы нужные.
И см., например, http://www.delphikingdom.com/tower/index.asp?CategoryID=6
← →
Анонимщик1 (2005-03-14 14:59) [13]Обломись, VTune тебе не нужен
← →
Darklight © (2005-03-14 19:11) [14][12] Что значит обломись?
VTune не нужен?
Почему?
← →
programania © (2005-03-14 20:50) [15]>wicked ©
>бред...
Возможно, но Именно так работает приведенный пример
при многократном нажатии на button1
>Анонимщик1
>Ты же своим ProcessMessages насильно выбираешь и обрабатываешь сообщение из очереди
Я просто показал что повторное выполнение события обычная вещь
и если выводить на экран какими-то системными процедурами
то никто не гарантирует что произойдет то же самое.
>Но ведь тогда пришлось бы синхронизировать функции, вызванные в контексте одного (скажем, главного)
>потока, в плане разделения ресурсов. Ты сам-то так когда-нибудь делал? Короче, думай, что говоришь.
Я просто не допускаю повторного выполнения кода.
Иначе могут выскакивать произвольные ошибки в произвольное время. И говорю я на основе своего горького опыта:
Хотя никто не запрещает делать в Button1Click, MouseMove все что угодно,
но если возникают случайные ошибки мне не раз помогало
вынесение обработки в timer.
← →
Анонимщик1 (2005-03-15 11:01) [16]Darklight
VTune слишком крут для твоей (видимо, не очень сложной) проблемы.
programania
Извини, но разгребать кашу в твоей голове сил, наверное, нет ни у кого. Кроме стандартных пожеланий читай MSDN и Рихтера у меня для тебя ничего больше нет.
Страницы: 1 вся ветка
Текущий архив: 2005.07.11;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.041 c