Здравствуйте! У меня вопрос по созданию региона. В уроках к масму есть пример. В нем используется .RGN файл, созданный с помощью сторонней утилиты. А недавно я наткнулся на интересную реализацию. Как регион (имеется ввиду регион любой формы) создается в самой программе. Принцип вроде я понял. Имеется какой-то цвет, и в цикле обходятся все точки фона. Если точка фона имеет нужный цвет, то она делается прозрачной. Но проблема в том, что полученный екзешник тормозит. То есть окно создается с задержкой, и при перемещении окна наблюдаются тормоза. Может быть кто-то сталкивался с этим или сам писал что-то подобное. Объясните в чем пролема? Где тормоза?
У меня так вообще не работает. Чистая область без ничего цвета окна, даже screen можно не выкладывать. А чтоб откомпилить пришлось искать LWA_COLORKEY, LWA_ALPHA, WS_EX_LAYERED. Выкладывайте всегда бинарники.
Да я вроде думаю: зачем лишний вес качать. Хоть и немного, но все же. Чего-то не аттачится. Экзешник залил сюда: http://slil.ru/24611087
Представленный вами исходник интересен разве что своей путаницей с Layered... (И кстати: окно и с регионом, и с WS_EX_LAYERED - это гарантированные тормоза). Выкиньте из исходника WS_EX_LAYERED и SetLayeredWindowAttributes - и останется только задержка при создании окна. Эта задержка неизбежна для примененного алгоритма создания региона. Но она была бы менее неприятной, если бы в это время не мозолил глаза серый рект окна. Так вот: смею предположить, что в гипотетическом исходном исходнике WS_EX_LAYERED и был средством маскировки. В аттаче - правка в этом духе (там, где стоит ;;. Да, и не надо закрывать окно по WM_RBUTTONDOWN, с неизбежным контекстным поп-апом. Аккуратнее - WM_RBUTTONUP.
Это не я напутал, честное слово! Скорее всего так оно и есть. У меня в архиве (откуда качал, сейчас не вспомню. Возможно что и с ВАСМа) Так вот, в архиве два исходника. Один как раз для Layered, а второй тот что я прицепил вверху. Единственное что я сделал это заменил картинку. Ну и размер окна, соответственно. В оригинале показывалась картинка-заставка к RadAsm. Может быть знакомый исходник? За помощь большое спасибо! Еще, если можно, пару вопросов. Чем такой способ лучше или хуже, того, при котором используются .RGN файлы? И что такое .RGN файлы? Последовательность команд, которые создают регион или что-то еще?
Скажем, при "разметке цветом" - для Layered никакой процедуры типа MakeRegion не требуется, просто либо SetLayeredWindowAttributes(*,crKey,*,LWA_COLORKEY*), либо UpdateLayeredWindow(*,*,*,*,*,*,crKey,*,ULW_COLORKEY). Однако Layered окнам однозначно противопоказано быть большими, - заметно тормозят. Ну и т.д. В общем, изучите - сами решите Если в двух словах - разбиение региона на прямоугольники. Почитайте в MSDN о структурах RGNDATA, RGNDATAHEADER, XFORM, о связанных с ними GetRegionData, ExtCreateRegion. В аттаче - утилитка с исходником, как пример кода с этими API. При запуске утилитки создаются: BMP-файл - снапшот окна под курсором, ОКНО-снапшот (т.е. "копия") того же окна, тех же размеров и с теми же координатами, а если окно с регионом - то и RGN-файл, BMP-файл "LastMask" - графический портрет структуры RGNDATA, и он же рисуется в левом верхнем углу десктопа. Кроме того, на окно-снапшот можно драгдропить BMP- и RGN- файлы, в результате чего окно-снапшот принимает их образ и форму. Ну и еще кое-какие фичи с Ctrl/Shift/Alt + double-click. Короче, надо создать ярлык с ассоциацией (например - F11 key), и запускать клавишей.
Mikl__ Маленький вопросец. Мне пока сложно разбираться в чужих исходниках. Тем более, что у тебя стиль написания сильно отличается от Изцелиона, по которому я и учусь. Не мог бы ты в двух словах прокомментировать вот что: Во всех примерах, которые здесь предлагались ранее, главное окно имеет стиль WS_POPUP. В принципе, это понятно, так как если окно будет содержать заголовок, то весь регион сместится вверх как раз на ширину заголовка. А у тебя главное окно создается со стилем WS_OVERLAPPEDWINDOW+WS_VISIBLE. Но при этом регион такой как положено. Каким образом это достигнуто?
Sturgeon Регион собирается из горизонтальных полос с цветом отличным от цвета фона (цвет точки с координатами 0,0). Сам регион, как правильно заметил mc black, действительно рисуется на 30 точек ниже (высота заголовка) и на 4 точки правее (ширина рамки) Код (Text): mov i,30 ;Y=30 a1: mov j,4 ;X=4 a2: mov ecx,j inc j cmp [esi],edi ;pixel == TransPixel ? в edi цвет фона картинки jz short a3 test eax,eax ;eax != 0 ? jnz short a4 mov eax,ecx ;eax=j jmp short a4 ;if(pixel != TransPixel && eax == 0) eax=j; a3: test eax,eax ;eax == 0 ? jz short a4 mov edx,i ;if(pixel == TransPixel && eax > 0) inc edx push edx ;edx=i+1 push ecx ;ecx=j-1 push i inc eax push eax call _imp__CreateRectRgn@16 ;hRgn=CreateRectRgn(eax,i,j-1,i+1); push RGN_OR push eax ;HRGN push ebp ;ResRgn push ebp ;ResRgn call _imp__CombineRgn@16 ;CombineRgn(ResRgn,ResRgn,hRgn,RGN_OR); xor eax,eax ;eax = 0 a4: add esi,bpp;переходим к следующей точке картинки, ;в памяти они расположены линейно, byte per pixel bpp = bi.bmBitsPixel /8 бит; cmp byte ptr j,bmpWidth+4 jb short a2 inc i cmp byte ptr i,bmpHeight+30 jb short a1 ;------------------------------------------------------------- push 1 ;bRedraw push ebp ;ResRgn push hWnd call _imp__SetWindowRgn@12
Mikl__ Теперь вроде более понятно стало. Благодарю за подробные разъяснения. Спасибо всем, кто помог мне еще немножко продвинуться в изучение ассемблера!
kero Я уже писал, при создании региона, он сдвигается на 30 точек вниз (высота заголовка) и на 4 точки вправо (толщина рамки). Числа подобраны, видимо на вашей машине высота заголовка меньше, поэтому и получился такой эффект...
Это-то понятно (У меня на XP выставлена "классическая" тема). Но это пример к другому вопросу: вопросу о выборе между 1) WS_OVWRLAPPEDWINDOW+WS+VISIBLE и 2) WS_POPUP+WS_VISIBLE (причем без бордерных WS_EX-стилей), чтоб без HTCAPTION, HTBORDER, HTMENU, а только с HTCLIENT (ну, разве что еще и WS_SYSMENU / HTSYSMENU, если нужна таскбарная кнопка с контекстным меню). Зачем считать точки, если можно не считать ?
kero WS_POPUP не получается. Сделал с WS_OVERLAPPEDWINDOW и использовал SetWindowLong что б не было рамки, а так как WS_OVERLAPPEDWINDOW без WS_VISIBLE пришлось добавлять ShowWindow и UpdateWindow. Зато никаких "красных ушей" ни в "классической" теме, ни в теме "Windows XP". Исправленный сорц и exe в аттаче
В смысле не получается? Стиль главного окна должен быть помимо WS_POPUP еще и WS_EX_TOOLWINDOW or WS_EX_TOPMOST. Вроде так. Хотя я могу и ошибиться.
Если загрузку картинки перенести в начало кода, там где идет регистрация стиля окна. То тогда можно избавиться от обслуживания WM_PAINT. Код становится просто лишним. Код (Text): ; --> LOAD IMAGE FROM EXECUTABLE (RESOURCE) invoke BitmapFromResource,hInstance,2000 mov hBackground, eax ; --> USE THAT BITMAP AS WINDOW BACKGROUND invoke CreatePatternBrush,eax mov wc.hbrBackground,eax А по поводу создания региона то там самое пормознутое место это GetPixel. Нужно придумать быструю альтернативу. Проверял так: Регион расширялся по-пиксельно, если пиксель соответствует то добавим, если нет то нет. Так вот, если убрать GetPixel и сказать что нужно добавлять все пискелы, то скорость создания региона всё равно увеличивается в 6 раз. 3054, ms 561, ms Вывод тормоз - это GetPixel. Убери его и всё будет ОК!