Создание региона

Тема в разделе "WASM.BEGINNERS", создана пользователем Sturgeon, 9 июл 2007.

  1. Sturgeon

    Sturgeon New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2006
    Сообщения:
    111
    Здравствуйте!
    У меня вопрос по созданию региона. В уроках к масму есть пример. В нем используется .RGN файл, созданный с помощью сторонней утилиты.
    А недавно я наткнулся на интересную реализацию. Как регион (имеется ввиду регион любой формы) создается в самой программе. Принцип вроде я понял. Имеется какой-то цвет, и в цикле обходятся все точки фона. Если точка фона имеет нужный цвет, то она делается прозрачной.
    Но проблема в том, что полученный екзешник тормозит. То есть окно создается с задержкой, и при перемещении окна наблюдаются тормоза.
    Может быть кто-то сталкивался с этим или сам писал что-то подобное. Объясните в чем пролема? Где тормоза?
     
  2. DarkWanderer

    DarkWanderer New Member

    Публикаций:
    0
    Регистрация:
    11 июл 2006
    Сообщения:
    333
    Адрес:
    Барнаул.
    У меня так вообще не работает. Чистая область без ничего цвета окна, даже screen можно не выкладывать.
    А чтоб откомпилить пришлось искать LWA_COLORKEY, LWA_ALPHA, WS_EX_LAYERED.
    Выкладывайте всегда бинарники.
     
  3. Sturgeon

    Sturgeon New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2006
    Сообщения:
    111
    Да я вроде думаю: зачем лишний вес качать. Хоть и немного, но все же.
    Чего-то не аттачится. Экзешник залил сюда:
    http://slil.ru/24611087
     
  4. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    Представленный вами исходник интересен разве что своей путаницей с Layered...
    (И кстати: окно и с регионом, и с WS_EX_LAYERED - это гарантированные тормоза).

    Выкиньте из исходника WS_EX_LAYERED и SetLayeredWindowAttributes - и останется только задержка при создании окна.
    Эта задержка неизбежна для примененного алгоритма создания региона.
    Но она была бы менее неприятной, если бы в это время не мозолил глаза серый рект окна.

    Так вот: смею предположить, что в гипотетическом исходном исходнике WS_EX_LAYERED и был средством маскировки.
    В аттаче - правка в этом духе (там, где стоит ;;;).

    Да, и не надо закрывать окно по WM_RBUTTONDOWN, с неизбежным контекстным поп-апом. Аккуратнее - WM_RBUTTONUP.
     
  5. Sturgeon

    Sturgeon New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2006
    Сообщения:
    111
    Это не я напутал, честное слово!:)
    Скорее всего так оно и есть. У меня в архиве (откуда качал, сейчас не вспомню. Возможно что и с ВАСМа) Так вот, в архиве два исходника. Один как раз для Layered, а второй тот что я прицепил вверху. Единственное что я сделал это заменил картинку. Ну и размер окна, соответственно. В оригинале показывалась картинка-заставка к RadAsm. Может быть знакомый исходник?
    За помощь большое спасибо! Еще, если можно, пару вопросов.
    Чем такой способ лучше или хуже, того, при котором используются .RGN файлы? И что такое .RGN файлы? Последовательность команд, которые создают регион или что-то еще?
     
  6. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    Скажем, при "разметке цветом" - для 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), и запускать клавишей.
     
  7. Sturgeon

    Sturgeon New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2006
    Сообщения:
    111
    Большое спасибо за исходник. И еще большее спасибо за ответы! Потихонечку буду разбираться.
     
  8. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    Sturgeon
    Это до кучи, в аттаче сорц и ехе
     
  9. Sturgeon

    Sturgeon New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2006
    Сообщения:
    111
    Mikl__ Маленький вопросец.
    Мне пока сложно разбираться в чужих исходниках. Тем более, что у тебя стиль написания сильно отличается от Изцелиона, по которому я и учусь. Не мог бы ты в двух словах прокомментировать вот что:
    Во всех примерах, которые здесь предлагались ранее, главное окно имеет стиль WS_POPUP. В принципе, это понятно, так как если окно будет содержать заголовок, то весь регион сместится вверх как раз на ширину заголовка. А у тебя главное окно создается со стилем WS_OVERLAPPEDWINDOW+WS_VISIBLE. Но при этом регион такой как положено. Каким образом это достигнуто?
     
  10. mc black

    mc black Member

    Публикаций:
    0
    Регистрация:
    19 янв 2005
    Сообщения:
    213
    Адрес:
    Russia, N.Novgorod
    Пример не качал, но вероятная причина - регион нарисован ниже, чем заголовок.
     
  11. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
  12. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    Sturgeon
    Регион собирается из горизонтальных полос с цветом отличным от цвета фона (цвет точки с координатами 0,0). Сам регион, как правильно заметил mc black, действительно рисуется на 30 точек ниже (высота заголовка) и на 4 точки правее (ширина рамки)
    Код (Text):
    1.         mov i,30    ;Y=30
    2. a1: mov j,4     ;X=4
    3. a2: mov ecx,j
    4.     inc j
    5.     cmp [esi],edi   ;pixel == TransPixel ? в edi цвет фона картинки
    6.         jz short a3
    7.         test eax,eax    ;eax != 0 ?
    8.         jnz short a4
    9.         mov eax,ecx ;eax=j
    10.         jmp short a4    ;if(pixel != TransPixel && eax == 0)  eax=j;
    11. a3:     test eax,eax    ;eax == 0 ?
    12.         jz short a4
    13.     mov edx,i       ;if(pixel == TransPixel && eax > 0)
    14.         inc edx
    15.         push edx    ;edx=i+1
    16.         push ecx    ;ecx=j-1
    17.         push i
    18.     inc eax
    19.         push eax
    20.         call _imp__CreateRectRgn@16 ;hRgn=CreateRectRgn(eax,i,j-1,i+1);
    21.         push RGN_OR
    22.         push eax    ;HRGN
    23.         push ebp    ;ResRgn
    24.         push ebp    ;ResRgn
    25.         call _imp__CombineRgn@16 ;CombineRgn(ResRgn,ResRgn,hRgn,RGN_OR);
    26.     xor eax,eax ;eax = 0
    27. a4:     add esi,bpp;переходим к следующей точке картинки,
    28. ;в памяти они расположены линейно, byte per pixel   bpp = bi.bmBitsPixel /8 бит;
    29.         cmp byte ptr j,bmpWidth+4
    30.         jb short a2
    31.         inc i
    32.     cmp byte ptr i,bmpHeight+30
    33.         jb short a1
    34. ;-------------------------------------------------------------
    35.     push 1      ;bRedraw
    36.         push ebp    ;ResRgn
    37.         push hWnd
    38.         call _imp__SetWindowRgn@12
     
  13. Sturgeon

    Sturgeon New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2006
    Сообщения:
    111
    Mikl__
    Теперь вроде более понятно стало. Благодарю за подробные разъяснения.

    Спасибо всем, кто помог мне еще немножко продвинуться в изучение ассемблера!
     
  14. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    Sturgeon, Mikl__
    А что это там красненькое снизу и на ушках ? :)
    [​IMG]
     
  15. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    kero
    Я уже писал, при создании региона, он сдвигается на 30 точек вниз (высота заголовка) и на 4 точки вправо (толщина рамки). Числа подобраны, видимо на вашей машине высота заголовка меньше, поэтому и получился такой эффект...
    [​IMG]
     
  16. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    Это-то понятно :) (У меня на XP выставлена "классическая" тема).

    Но это пример к другому вопросу: вопросу о выборе между

    1) WS_OVWRLAPPEDWINDOW+WS+VISIBLE
    и
    2) WS_POPUP+WS_VISIBLE (причем без бордерных WS_EX-стилей),
    чтоб без HTCAPTION, HTBORDER, HTMENU, а только с HTCLIENT
    (ну, разве что еще и WS_SYSMENU / HTSYSMENU, если нужна таскбарная кнопка с контекстным меню).

    Зачем считать точки, если можно не считать ? :)
     
  17. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    kero
    оффтоп
    к сожалению, я сперва делаю, а потом думаю, попробую на этот раз с WS_POPUP+WS_VISIBLE
     
  18. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    kero
    WS_POPUP не получается. Сделал с WS_OVERLAPPEDWINDOW и использовал SetWindowLong что б не было рамки, а так как WS_OVERLAPPEDWINDOW без WS_VISIBLE пришлось добавлять ShowWindow и UpdateWindow. Зато никаких "красных ушей" ни в "классической" теме, ни в теме "Windows XP". Исправленный сорц и exe в аттаче
     
  19. Sturgeon

    Sturgeon New Member

    Публикаций:
    0
    Регистрация:
    17 окт 2006
    Сообщения:
    111
    В смысле не получается? Стиль главного окна должен быть помимо WS_POPUP еще и WS_EX_TOOLWINDOW or WS_EX_TOPMOST. Вроде так. Хотя я могу и ошибиться.
     
  20. S_Alex

    S_Alex Alex

    Публикаций:
    0
    Регистрация:
    27 авг 2004
    Сообщения:
    561
    Адрес:
    Ukraine
    Если загрузку картинки перенести в начало кода, там где идет регистрация стиля окна.
    То тогда можно избавиться от обслуживания WM_PAINT. Код становится просто лишним.

    Код (Text):
    1. ; -->   LOAD IMAGE FROM EXECUTABLE (RESOURCE)
    2.     invoke  BitmapFromResource,hInstance,2000
    3.     mov     hBackground, eax
    4. ; -->   USE THAT BITMAP AS WINDOW BACKGROUND
    5.     invoke  CreatePatternBrush,eax
    6.     mov   wc.hbrBackground,eax
    А по поводу создания региона то там самое пормознутое место это GetPixel.
    Нужно придумать быструю альтернативу.

    Проверял так:
    Регион расширялся по-пиксельно, если пиксель соответствует то добавим, если нет то нет.
    Так вот, если убрать GetPixel и сказать что нужно добавлять все пискелы, то скорость создания региона всё равно увеличивается в 6 раз.

    3054, ms
    561, ms

    Вывод тормоз - это GetPixel. Убери его и всё будет ОК!