Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Системное программирование и WinAPI > TransparentBlt выдает ошибку |
Автор: GremlinProg 3.1.2009, 19:28 | ||||||
обнаружил недокументированную заплатку в функции TransparentBlt как я сейчас понимаю, она была сделана для предотвращения утечки, о которой говорится в MSDN:
ошибку обнаружил при реализации потокового наложения слоев:
blt - метод, который накладывает разнородные слои из списка devlist в исходный hdc через ключ прозрачности clr_transparent при этом, размеры слоев градуируются с заданным шагом, например: если минимальный размер ячейки слоя составляет 20 пикселей, то ширина и высота битмапов, выбираемых в контексты списка devlist, всегда кратны 20 пикселам hdc не градуируется таким образом, т.е., к примеру, если в hdc выбран битмап размером 25 x 47, то в списке devlist все битмапы 20 x 40, т.е. в devlist размеры округляются в меньшую сторону в реальной работе, если вызвать blt(hdc,0,0,25,47,0,0), то TransparentBlt на всех слоях возвращается с ошибкой "неверный параметр", соответственно, на hdc ничего не выводится уже не знал в чем проблема, грешил на совместимость девайсов, пока не попробовал вместо TransparentBlt вызывать BitBlt, т.е. просто копирование слоев, а не наложение предположение о несовместимости девайсов сразу отпало, поскольку BitBlt работает коректно проверил результат работы blt с DstCx и DstCy - меньшими, либо равными размерам битмапов в devlist, т.е. (DstCx <= 20) && (DstCy <= 40) после этого и TransparentBlt заработал как надо вобщем, код c TransparentBlt пришлось модифицировать следующим образом:
GetClipBox дает позицию и размеры битмапа в девайсе, а DstCx и DstCy корректируются перед выводом такое и раньше бывало, но я не пробовал использовать TransparentBlt на дискретной сетке, чтобы четко определить, в чем подвох пишите, если будут опровержения или подтверждения по теме чтобы не быть голословным, нужно несколько мнений, подкрепленных практикой ссылка на документацию: http://msdn.microsoft.com/en-us/library/ms532303(VS.85).aspx |
Автор: Earnest 6.1.2009, 18:16 |
Сталкивалась с тем, что StretchBlt тоже врет при выходе за границы. Видимо, код масштабирования там кривоват... Тоже пришлось проверять и корректировать границы. Подробностей уже не помню, но не думаю, чтобы это было связано с ошибкой утечки памяти, на которую ты сослался... Не в первый раз сталкиваюсь с тем, что функции ГУИ работают по принципу "шаг вправо, шаг влево - расстрел". Ну очень недружелюбны ко всякого рода неточностям... |
Автор: GremlinProg 6.1.2009, 19:23 |
думаешь в масштабировании дело ну, вариант, в принципе я просто не нашел ни одного упоминания на какие-либо ограничения по координатам в документации, поэтому и предположил меня вообще удивляет наличие самой функции масштабирования в TransparentBlt, и отсутствие аналога BitBlt по ключу прозрачности масштабирование в любом случае задействует больше ресурсов, чем копирование у меня, по крайней мере, здесь масштабирование не используется, наложение битмапов производится один в один если TransparentBlt и StretchBlt создают таки в памяти дубль битмапа, чтобы интерполировать видимые участки, то утечка так же возможна на сколько я понимаю, TransparentBlt, по крайней мере создает маску прозрачности, что вполне логично может привести к вариантам кэширования или хэширования масок для ускорения повторного рисования (у борланда такое наблюдается, хотя там просто хэширование данных GDI-объектов), отсюда и могут вылезать проблемы с потерей каких-либо отдельных ресурсов |
Автор: GremlinProg 6.1.2009, 20:37 | ||
это похоже на танцы с виртуальной памятью: виртуальный блок - локальный, а фактический - в видеопамяти я пробовал закрепить dib в физической памяти(VirtualLock) и ничего из этого не получилось, пишет вроде как "регион уже закреплен", т.е. это точно не свопируемая память, хотя вполне может и правда закреплен самой CreateDibSection, например, если производится эмуляция ) |
Автор: Earnest 6.1.2009, 20:50 | ||
Да, я тоже пришла к такому выводу - по крайней мере, на время выполнения операции. Знаешь, я со временем пришла к мысли, что если хочешь сделать что-то полезное, то лучше не погружаться во внутренний мир болота, а прыгать по кочкам, и черт с ним, с их химическим составом. Иначе за деревьями леса не увидишь... Иногда, конечно, приходится нырять в тину, если по другому не получается, но потом я сразу забываю подробности погружения - до следующего ![]() А может, это просто мне лень стало со временем, во всех этих багах копаться... |
Автор: GremlinProg 6.1.2009, 21:05 | ||
на счет погружения - верно, но пытливый моск рукам покоя не дает я просто считал, что баг в самой TransparentBlt, а тут - всего лишь учет границ функция-то удобная, как раз, чтобы не погружаться в тину: SRCINVERT, SRCPAINT и т.п., опять же - маску создавать не надо странно, что в документации об этом ни слова Добавлено через 13 минут и 29 секунд кстати, в тему о прозрачности:
это не мое, один из источников http://www.codeguru.com/cpp/g-m/bitmap/article.php/c1753, т.е. это как раз простой вариант прозрачности через BitBlt, хоть и аппаратно-зависимый, надо будет посмотреть, что быстрее и, возможно, составить триггер, если TransparentBlt таки формирует маску |
Автор: GremlinProg 6.1.2009, 21:59 | ||
к сожалению, мой жифорс такого не поддерживает |
Автор: Earnest 6.1.2009, 22:46 |
Я тоже про это не слышала... интересно... наверное, это использование новых возможностей железа... Но когда нужно поддерживать невесть какие машины, а прозрачность - далеко не главный вопрос, на первое место выходит простота кода. Его и так столько, что с ума сойти... Кстати, интересно, есть ли баг с утечкой маски в TransparentBlt - там ведь только о Win95\98 говорится... Надо бы проверить: кажется, были непонятные утечки ресурсов, и TransparentBlt кое-где используется. Вот выйдет народ на работу, озадачу кого-нибудь, у кого моск не такой ленивый как у меня... |