![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Canvas does not allow drawing [Win2k]
Darklight © (2005-03-11 15:51:00)Через некотороевремя работы приложения возникает следующая ошибка:
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.
Компьютер очень мощный с большим количеством памяти (оперативной, видео...).
Анонимщик1 (2005-03-15 11:01:00) [1]Darklight
VTune слишком крут для твоей (видимо, не очень сложной) проблемы.
programania
Извини, но разгребать кашу в твоей голове сил, наверное, нет ни у кого. Кроме стандартных пожеланий читай MSDN и Рихтера у меня для тебя ничего больше нет.
programania (2005-03-14 20:50:00) [2]>wicked ©
>бред...
Возможно, но Именно так работает приведенный пример
при многократном нажатии на button1
>Анонимщик1
>Ты же своим ProcessMessages насильно выбираешь и обрабатываешь сообщение из очереди
Я просто показал что повторное выполнение события обычная вещь
и если выводить на экран какими-то системными процедурами
то никто не гарантирует что произойдет то же самое.
>Но ведь тогда пришлось бы синхронизировать функции, вызванные в контексте одного (скажем, главного)
>потока, в плане разделения ресурсов. Ты сам-то так когда-нибудь делал? Короче, думай, что говоришь.
Я просто не допускаю повторного выполнения кода.
Иначе могут выскакивать произвольные ошибки в произвольное время. И говорю я на основе своего горького опыта:
Хотя никто не запрещает делать в Button1Click, MouseMove все что угодно,
но если возникают случайные ошибки мне не раз помогало
вынесение обработки в timer.
Darklight (2005-03-14 19:11:00) [3][12] Что значит обломись?
VTune не нужен?
Почему?
Анонимщик1 (2005-03-14 14:59:00) [4]Обломись, VTune тебе не нужен
Анонимщик1 (2005-03-14 14:57:00) [5]Посмотреть можно хотя бы с помощью диспетчера задач, только нужно выбрать столбцы нужные.
И см., например, http://www.delphikingdom.com/tower/index.asp?CategoryID=6
WondeRu (2005-03-14 14:51:00) [6]VTune
Darklight (2005-03-14 14:16:00) [7]Какой?
Никода о них не слышал?
Анонимщик1 (2005-03-14 13:33:00) [8]Тогда посмотри какой-нибудь утилитой утечку графических ресурсов.
Darklight (2005-03-14 13:20:00) [9]Полностью согласен с [6] и [7]
Нет других потоков.
Классы только мои и обычные борлондовские (типа TObjecList)
Приложение - типа графического редактора.
Визуализационная часть достаточно простая, но на канве битмапа производится наложенная отрисовка большого количества примитивов и выводится текст.
Анонимщик1 (2005-03-14 11:52:00) [10]programania
Ты же своим ProcessMessages насильно выбираешь и обрабатываешь сообщение из очереди - код бы глянул. Ну, хорошо, предположим на секунду, что ты прав. Но ведь тогда пришлось бы синхронизировать функции, вызванные в контексте одного (скажем, главного) потока, в плане разделения ресурсов. Ты сам-то так когда-нибудь делал? Короче, думай, что говоришь.
Darklight
Ты уверен, что приложение однопоточное? Что оно из себя представляет? Какие классы (особенно не свои и не-борландовские) используешь?
wicked (2005-03-14 10:53:00) [11]
> Верно, одно из них будет остановлено в случайном месте
> и если второе это тоже самое onMouseMove то тот же код
> начнет рисовать недорисованный canvas, а это ни к чему
> хорошему не приведет.
бред...
programania (2005-03-12 23:22:00) [12]>В однопоточных приложениях два события не могут выполняться одновременно.
Верно, одно из них будет остановлено в случайном месте
и если второе это тоже самое 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 по времени.
События запускаются и преключаются внешними причинами
потоков им не надо, но запускаться и работать
они обязаны когда эти причины произойдут,
а все остальное будет стоять пока не закончится
последнее возникшее или не возникнет новое.
Darklight (2005-03-12 11:23:00) [13][1] Попробую!
[2] BM - Bitmap создаётся ОДИН раз по собитию onCreate на форме и уничтожается ОДИН раз по событию onDestroy на форме и вообще является переменной формы.
[3] В однопоточных приложениях два события не могут выполняться одновременно. Если отрабатывает событие onTime (перерисовывает изображение), и есть движение мыши на PaintBoxm - е, то пока не отработае onTime событие onMouseMove не возникнет! И наоборот. Ttimer не создаёт нового потока для обработки событий!
programania (2005-03-11 23:41:00) [14]>Данный код написан в обработчике событий onMouseMove
Может он начинает выполняться, когда еще не кончился
предыдущий вывод, тогда может быть что угодно.
Надо помечать что выполняется и обходить.
MBo (2005-03-11 17:31:00) [15]проблема, скорее всего, не в этом коде, а в подготовке и неосвобождении битмапов - выжираются ресурсы GDI
WondeRu (2005-03-11 17:17:00) [16]попробуй:
self.PB.Canvas.Lock;
try
...
здесь рисуем!!!
..
finally
self.PB.Canvas.UnLock;
end;