Win32, прозрачные окошки
А не пойдет сделать вот так:
1. Вместо линий - массив точек (линия) - последние растворяются, при мышке добавляются новые.
2. Выводим все на GetDC (0) по таймеру.
3. Прозрачность считаешь сам для каждой точки - благо формула проста как две копейки Цвет1 - (1 - УРовень_Альфы) * Цвет2 (по каждой составляющей разумеется).
4. Как получить быстро определенной точки, точно не скажу - но что то кажется через тот же нулевой контекст.
? Вроде не сильно должно тормозить. Хотя на большом разрешении GDI будет козни строить.
P.S. Не сильно бред надеюсь написал
херня будет, если что-нибудь будет скролится - поверх которого так рисовать
во-первых - все то же мелькание - я рисую по таймеру, в перерывах окно снизу рисует тоже что-то, получается плохо;
во-вторых - если делать по таймеру, то будут зря жраться ресурсы даже в случае, если окна снизу ничего не перерисовывают.
Вообще, первый вариант неплох, если добиться отсутствия мелькания, но пока не получалось Там сначала на основной канве стирание происходит в DC в памяти, на новое окно линия тоже наносится на DC в памяти, потом из памяти все копируется на экран, и все-таки выходит криво (
Никаких отдельных канв не создается, при начале рисования делается окно, которому вслед за движениями мыши устанавливается постоянно добавляющийся регион посредством SetWindowRgn, дорисованная линия добавляется к уже существующему региону посредством CombineRegion. Таким способом мельканий в принципе нет.Почему бы просто не наращивать окно по некоторому прямоугольнику, который вмещает всю линию? Проблемы с прорисовкой надо решать через рисование и копирование в memory dc, плюс грамотной обработкой WM_ERASEBACKGROUND
Минусы: при рисовании сложных линий сильно возрастает нагрузка процессора, в итоге все заканчивается сообщением, что невозможно получить текущий регион окна (наверное, какие-то ограничения на количество вершин в регионе стоит, что-ли). Кроме того, даже если рисовать несложные короткие линии, не показывается более двух таких окон одновременно, как и во 2-м случае, почему - хз.
А могу ли я нарастить окно, чтобы при этом не перерисовывались окна под наращенной областью? Мне кажется, мелькания в основном из-за этого возникают.
А могу ли я нарастить окно, чтобы при этом не перерисовывались окна под наращенной областью? Мне кажется, мелькания в основном из-за этого возникают.Думаю, что не можешь. А что, под прозрачными окнами другие окна тоже перерисовываются?
http://support.microsoft.com/kb/q135865/ Может быть, делать некоторый рисунок прямо на экране, а затем контролировать его?
Вот какая-то идея: Кстати, провел сегодня тесты на слабом компьютере, с достойной производительностью работал только первые вариант, остальные два тормозили ужасно.
Второй вариант - как раз то, что я делаю - создание прозрачного popup окна поверх всего и рисование на нем.
Между прочим, сегодня первый вариант даже почти не мелькал... Раз на раз не приходится, блин. А еще на разных компах разные глюки, иногда такое бывает... А ось вроде одна - XP SP2. И как они ее до такого состояния доводят...
В ней, правда, след довольно специфический: во-первых, не исчезает пока не отпустишь кнопку, во-вторых, рисуется довольно системного вида ксорящим голубеньким цветом, то есть возможно там что-то специфическое используется, которое всегда так выглядит.
Первый вариант, описанный тамЯ точно не разбирался в твоих вариантах, но микрософт в примерах рисует и стрирает с помощью XOR-ов, без всяких дополнительных окон. Таким образом, изменяется только часть экрана под рисунком, а окна под этим делом не перерисовываются.
В ней, правда, след довольно специфический: во-первых, не исчезает пока не отпустишь кнопку, во-вторых, рисуется довольно системного вида ксорящим голубеньким цветом, то есть возможно там что-то специфическое используется, которое всегда так выглядит.StrokeIt рисует жёлтым. Это не важно на самом деле.
спай++ и попытайся заценить, какие апи она юзаетХм, это ж не дебаггер, разве он такое умеет?
Я точно не разбирался в твоих вариантах, но микрософт в примерах рисует и стрирает с помощью XOR-ов, без всяких дополнительных окон. Таким образом, изменяется только часть экрана под рисунком, а окна под этим делом не перерисовываются.Мне так кажется, что если окно под прямоугольником будет что-то рисовать, то все это полетит в тартарары.
Мне так кажется, что если окно под прямоугольником будет что-то рисовать, то все это полетит в тартарары.Там точно описано решение, которое не летит. Так работает drag&drop в винде. Впрочем, ты можешь совместить невидимое окно и XOR-ы.
Да ну, брось, там же тупо XOR накладывается на XOR. Если между этими моментами что-то нарисуется поверх, то при движении прямоугольника будут оставаться следы, что иногда и происходит при выделении иконок на рабочем столе.
Да ну, брось, там же тупо XOR накладывается на XOR. Если между этими моментами что-то нарисуется поверх, то при движении прямоугольника будут оставаться следы, что иногда и происходит при выделении иконок на рабочем столе.Если что-то нарисуется поверх, то оно потом перерисуется и всё будет в порядке. Я же написал: попробуй сочетать XOR и невидимое окно. Ты явно делаешь что-то не так, если у тебя графика мигает.
Сразу можно добавить, что идеала ты не добьёшься. Можно только сделать так, чтобы всё выглядело прилично и не тормозило.
Оставить комментарий
erotic
День добрый.Если кто программирует под Win32, помогите, пожалуйста.
Ситуация такая: надо при нажатии на кнопку мыши вслед за курсором рисовать след определенной толщины, цвета и полупрозрачности поверх всех окон. Когда отпускаю кнопку, след некоторое время еще висит, потом постепенно растворяется.
Я пытался реализовать тремя способами, но все они с недостатками, вот они:
1. Поверх всех окон ставится окно на весь экран с WS_EX_LAYERED и LWA_COLORKEY, т.е. оно прозрачное, пока на нем ничего не нарисовано, кроме того выставлена прозрачность (LWA_ALPHA). При нажатии на кнопку мыши по окну рисуются линии определенной толщины вслед за курсором, когда кнопка отпускается - вычисляется минимальный прямоугольник, содержащий нарисованное, создается такого размера окно (такого же типа, как которое уже существует в него копируется все нарисованное, первоначальная канва очищается и готова к рисованию заново. Окно, в которое было скопировано нарисованное, передается таймеру, по прошествии какого-то времени оно постепенно растворяется.
Минусы такого подхода в том, что когда происходит создание второго окна, бывают мелькания, иногда довольно заметные, хотя зависит от того, как перерисовывает изображение окно, которое находится под линией.
2. Для каждого нового рисования создается новая канва по типу как в случае 1, только без всяких копирований, просто когда очередная линия нарисована, окно сразу передается таймеру.
Минусы - почему-то после второй, иногда третьей линии винда новые окна больше не показывает, пока не исчезнут предыдущие. Это точно не ошибка программы, код показа окна точно вызывается, но окна не видать
3. Никаких отдельных канв не создается, при начале рисования делается окно, которому вслед за движениями мыши устанавливается постоянно добавляющийся регион посредством SetWindowRgn, дорисованная линия добавляется к уже существующему региону посредством CombineRegion. Таким способом мельканий в принципе нет.
Минусы: при рисовании сложных линий сильно возрастает нагрузка процессора, в итоге все заканчивается сообщением, что невозможно получить текущий регион окна (наверное, какие-то ограничения на количество вершин в регионе стоит, что-ли). Кроме того, даже если рисовать несложные короткие линии, не показывается более двух таких окон одновременно, как и во 2-м случае, почему - хз.
Есть еще вариант сделать через DirectDraw, но, насколько я узнал, DDraw не поддерживает напрямую полупрозрачное наложение.
Еще пробовал через OpenGL, рисуя прямо на GetDC(HWND_DESKTOP но в этом случае тоже не поддерживается прозрачность
У кого-нибудь есть идеи?