Работа с Desktop Window Manager на Ассемблере
Работа с Desktop Window Manager на Ассемблере
Начиная с Windows Vista, в составе системы появился Desktop Window Manager, он же Диспетчер рабочего стола. Этот компонент обеспечивает визуальные эффекты и возможности интерфейса Windows Aero, например, такие как полупрозрачные заголовки окон, Aero Peek, Flip3D и живые миниатюры окон на таскбаре при наведении на него мышкой. Для взаимодействия с Desktop Window Manager разработчикам программ предоставляется целый набор функций API, с некоторыми из этих функций мы сегодня научимся работать.
Чтобы начать работу с Desktop Window Manager, надо сперва проверить, на какой операционной системе запущено приложение, затем убедиться, что DWM доступен. Все функции импортируются из библиотеки dwmapi.dll. Чтобы проверить, включен ли в системе DWM, достаточно воспользоваться функцией DwmIsCompositionEnabled. Включить или выключить можно функцией DwmEnableComposition. Обратите внимание, что она доступна только до Windows 7, на более старших системах Диспетчер рабочего стола активен всегда, остановить его нельзя, а вызов DwmEnableComposition с любыми параметрами всегда будет возвращать успешный результат. Давайте посмотрим, что можно сделать при помощи Desktop Window Manager.
Окно с эффектом Blur
Начнем с эффекта размытия. Несмотря на то, что визуально он немного похож на эффект прозрачности, это, скорее эффект "мутного стекла". Он применяется к любому видимому окну при помощи функции DwmEnableBlurBehindWindow. В FASM предварительно надо описать структуру параметров и значения флагов для работы с этой функцией:
Code (Assembler) : Убрать нумерацию
- struct DWM_BLURBEHIND
- dwFlags dd ?
- fEnable dd ?
- hRgnBlur dd ?
- fTransitionOnMaximized dd ?
- ends
- DWM_BB_ENABLE = 0x00000001
- DWM_BB_BLURREGION = 0x00000002
- DWM_BB_TRANSITIONONMAXIMIZED = 0x00000004
Code (Assembler) : Убрать нумерацию
- ; Включить эффект размытия
- mov [bb.dwFlags],DWM_BB_ENABLE
- mov [bb.fEnable],TRUE
- mov [bb.fTransitionOnMaximized],FALSE
- mov [bb.hRgnBlur],0
- invoke DwmEnableBlurBehindWindow,[hwnddlg],bb
Окно с эффектом "стекла"
Интересное дополнение к эффекту размытия - задание боковых отступов окна, на которые эффект будет распространяться. Отступы могут быть как одинаковые, так и разные с любой стороны окна. Это делается при помощи функции DwmExtendFrameIntoClientArea. Определяем структуру:
Code (Assembler) : Убрать нумерацию
- struct MARGINS
- cxLeftWidth dd ?
- cxRightWidth dd ?
- cyTopHeight dd ?
- cyBottomHeight dd ?
- ends
Code (Assembler) : Убрать нумерацию
- ; Включить эффект размытия
- mov [bb.dwFlags],DWM_BB_ENABLE
- mov [bb.fEnable],TRUE
- mov [bb.fTransitionOnMaximized],FALSE
- mov [bb.hRgnBlur],0
- invoke DwmEnableBlurBehindWindow,[hwnddlg],bb
- ; Установить отрицательный отступ для "стеклянного" окна
- mov [margins.cyBottomHeight],-1
- invoke DwmExtendFrameIntoClientArea,[hwnddlg],margins
Консольное окно с эффектом Blur
Эффект размытия можно применять даже к консольным окнам. Что хорошо, тут даже не придется изгаляться с цветом окна - консолька по умолчанию и так черного цвета.
Code (Assembler) : Убрать нумерацию
- ; Получить хэндл консольного окна
- invoke GetConsoleWindow
- ; Включить эффект размытия
- mov [bb.dwFlags],DWM_BB_ENABLE
- mov [bb.fEnable],TRUE
- mov [bb.hRgnBlur],NULL
- invoke DwmEnableBlurBehindWindow,eax,bb
Code (Assembler) : Убрать нумерацию
- DWMWA_NCRENDERING_ENABLED = 1
- DWMWA_NCRENDERING_POLICY = 2
- DWMWA_TRANSITIONS_FORCEDISABLED = 3
- DWMWA_ALLOW_NCPAINT = 4
- DWMWA_CAPTION_BUTTON_BOUNDS = 5
- DWMWA_NONCLIENT_RTL_LAYOUT = 6
- DWMWA_FORCE_ICONIC_REPRESENTATION = 7
- DWMWA_FLIP3D_POLICY = 8
- DWMWA_EXTENDED_FRAME_BOUNDS = 9
- DWMWA_HAS_ICONIC_BITMAP = 10
- DWMWA_DISALLOW_PEEK = 11
- DWMWA_EXCLUDED_FROM_PEEK = 12
- DWMWA_CLOAK = 13
- DWMWA_CLOAKED = 14
- DWMWA_FREEZE_REPRESENTATION = 15
- DWMWA_LAST = 16
Окно исключено из Aero Peek
Например, чтобы исключить окно из Aero Peek, достаточно вызвать следующий код:
Code (Assembler) : Убрать нумерацию
- mov [attrValue],1
- invoke DwmSetWindowAttribute,[hwnddlg],DWMWA_EXCLUDED_FROM_PEEK,attrValue,4
Окно исключено из Flip3D
Установка следующего флага "выбьет" окно из обработки Flip3D (трехмерный переключатель окон, вызываемый комбинацией Win+Tab) и расположит поверх "колоды" листаемых окон.
Code (Assembler) : Убрать нумерацию
- DWMFLIP3D_EXCLUDEBELOW = 1
- DWMFLIP3D_EXCLUDEABOVE = 2
Code (Assembler) : Убрать нумерацию
- mov [attrValue],DWMFLIP3D_EXCLUDEABOVE
- invoke DwmSetWindowAttribute,[hwnddlg],DWMWA_FLIP3D_POLICY,attrValue,4
Трансляция рабочего стола на окно приложения
Самая интересная, на мой взгляд, функция Desktop Window Manager - возможность транслировать в режиме реального времени содержимое любого окна в другое. Например, вы можете в своем окне отобразить "живую" миниатюру рабочего стола. Любые изменения, сделанные на рабочем столе, будут сразу же отображены в вашем приложении. Как всегда, начинаем с описания необходимых структур и констант:
Code (Assembler) : Убрать нумерацию
- ; Структура для работы с превьюшками
- struct DWM_THUMBNAIL_PROPERTIES
- dwFlags dd ?
- rcDestination RECT
- rcSource RECT
- opacity db ?
- fVisible dd ?
- fSourceClientAreaOnly dd ?
- ends
- DWM_TNP_RECTDESTINATION = 0x00000001
- DWM_TNP_RECTSOURCE = 0x00000002
- DWM_TNP_OPACITY = 0x00000004
- DWM_TNP_VISIBLE = 0x00000008
- DWM_TNP_SOURCECLIENTAREAONLY = 0x00000010
Code (Assembler) : Убрать нумерацию
- ; Получить хэндл рабочего стола
- invoke FindWindow,szProgman,0
- ; Ну или какой-нибудь известный хэндл окна другого приложения
- ; mov eax,0x00030802
- ; Связать наше окно с превьюшкой исходного окна
- invoke DwmRegisterThumbnail,[hwnddlg],eax,hThumb
- mov eax,[hThumb]
- ; Отобразить "живую" превьюшку исходного окна на нашем окне
- mov [props.dwFlags],\
- DWM_TNP_VISIBLE+DWM_TNP_OPACITY+DWM_TNP_RECTDESTINATION
- mov [props.fSourceClientAreaOnly],FALSE
- mov [props.fVisible],TRUE
- mov [props.opacity],200
- invoke GetClientRect,[hwnddlg],props.rcDestination
- invoke DwmUpdateThumbnailProperties,[hThumb],props
Пользовательский thumbnail для приложения
Последняя функция Desktop Window Manager, о которой хотелось бы сегодня рассказать, это работа с превьюшкой окна приложения на панели задач. Как вы знаете, если навести курсор на панель задач, то там появятся миниатюры окон. Так вот, вместо уменьшенного изображения окна, туда можно поместить любое другое изображение. Начинаем с константы:
Code (Assembler) : Убрать нумерацию
- WM_SENDICONICTHUMBNAILBITMAP = 0x0323
Code (Assembler) : Убрать нумерацию
- ; Установить атрибуты окна
- mov [attrValue],1
- invoke DwmSetWindowAttribute,[hwnddlg],\
- DWMWA_HAS_ICONIC_BITMAP,attrValue,4
- invoke DwmSetWindowAttribute,[hwnddlg],\
- DWMWA_FORCE_ICONIC_REPRESENTATION,attrValue,4
Code (Assembler) : Убрать нумерацию
- ; Установить превьюшку
- cmp [msg],WM_SENDICONICTHUMBNAILBITMAP
- je .thumb
- ...
- ...
- ...
- .thumb:
- ; Размеры запрашиваемого изображения для превьюшки
- mov eax,[lparam]
- and eax,0FFFFh
- ; EAX = Высота
- mov eax,[lparam]
- shr eax,16
- ; EAX = Ширина
- ; Установить собственную превьюшку
- invoke GetModuleHandle,0
- invoke LoadImage,eax,1,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION
- invoke DwmSetIconicThumbnail,[hwnddlg],eax,0
В приложении примеры программ с исходными текстами, реализующие все описанные в статье эффекты и функции.
Просмотров: 3730 | Комментариев: 6
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(07.07.2018 в 20:36):
Да мне как-то пофиг чо там налепили в Windows 10 и почему под этой недосистемой не работает. Пример написан и работает под Windows 7, остальное мне не интересно.
Илья
(07.07.2018 в 20:30):
Здравствуйте, пример не работает под win10. Не могли бы вы обновить статью?; Желательно добавив пример custom title-bar.
ManHunter
(25.02.2018 в 15:27):
Самое время перейти на нормальный антивирус.
казявка
(21.10.2017 в 05:10):
из скачанного архива антивирус сразу же послал в карантин 4 файла :
http://funkyimg.com/i/2ywNx.png
http://funkyimg.com/i/2ywNx.png
Андрей
(02.03.2017 в 18:20):
Спасибо за статью.
Оффтоп. Добавь в окна эффект мутных окон-)
Оффтоп. Добавь в окна эффект мутных окон-)
brute
(02.03.2017 в 10:02):
выглядит круто! Надо будет на PB повторить..
Добавить комментарий
Заполните форму для добавления комментария