Работа с Desktop Window Manager в Assembler, Assembler Mindset, Blog
Започвайки с Windows Vista, Desktop Window Manager, известен още като Desktop Manager, се появи като част от системата. Този компонент предоставя визуалните ефекти и функции на интерфейса Windows Aero, като полупрозрачни заглавни ленти на прозорци, Aero Peek, Flip3D и миниатюри на прозорци на живо в лентата на задачите, когато задържите курсора на мишката върху него. За да взаимодействат с Desktop Window Manager, разработчиците на програми разполагат с цял набор от API функции, днес ще научим как да работим с някои от тези функции.
За да започнете с Desktop Window Manager, първо трябва да проверите на коя операционна система работи приложението, след което да се уверите, че DWM е наличен. Всички функции са импортирани от библиотекаdwmapi.dll. За да проверите дали DWM е активиран във вашата система, просто използвайте функцията DwmIsCompositionEnabled. Можете да го включите или изключите с функцията DwmEnableComposition. Моля, обърнете внимание, че е наличен само до Windows 7, на по-стари системи Desktop Manager е винаги активен, не може да бъде спрян и извикването наDwmEnableCompositionс всякакви параметри винаги ще върне успешен резултат. Нека видим какво може да се направи с Desktop Window Manager.
- структураDWM_BLURBEHIND
- dwFlagsdd?
- fEnabledd?
- hRgnBlurdd?
- fTransitionOnMaximizeddd?
- завършва
- DWM_BB_ENABLE = 0x00000001
- DWM_BB_BLURREGION = 0x00000002
- DWM_BB_TRANSITIONONMAXIMIZED = 0x00000004
- ; Активирайте ефекта на размазване
- mov[bb. dwFlags], DWM_BB_ENABLE
- mov[bb. fEnable] ,TRUE
- mov[bb. fTransitionOnMaximized],FALSE
- mov[bb. hRgnBlur], 0
- извикванеDwmEnableBlurBehindWindow, [hwnddlg], bb
Важна забележка. За да работи ефектът, прозорецът трябва да е черен, иначе ще се окаже пълна глупост. За целта се обръщаме към една от предишните статии. Тук няма да дублирам този материал, вижте напълно работещия пример в прикачения изходен код.
- структураПОЛЕТА
- cxLeftW >dd?
- cxRightW >dd?
- cyTopHeightdd?
- cyBottomHeightdd?
- завършва
- ; Активирайте ефекта на размазване
- mov[bb. dwFlags], DWM_BB_ENABLE
- mov[bb. fEnable] ,TRUE
- mov[bb. fTransitionOnMaximized],FALSE
- mov[bb. hRgnBlur], 0
- извикванеDwmEnableBlurBehindWindow, [hwnddlg], bb
- ; Задайте отрицателна подложка за "стъклен" прозорец
- mov[ полета . cyBottomHeight] , - 1
- извикванеDwmExtendFrameIntoClientArea, [hwnddlg], полета
Не забравяйте да зададете черен фон на прозореца, преди да приложите всички тези ефекти.
- ; Вземете дръжката на прозореца на конзолата
- извикванеGetConsoleWindow
- ; Активирайте ефекта на размазване
- mov[bb. dwFlags], DWM_BB_ENABLE
- mov[bb. fEnable] ,TRUE
- mov[bb. hRgnBlur],NULL
- извикванеDwmEnableBlurBehindWindow,eax, bb
- 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
Можете да промените атрибутите на прозореца с помощта на функцията DwmSetWindowAttribute и съответно да получите зададените атрибути с помощта на функцията DwmGetWindowAttribute.
- mov[attrValue], 1
- извикванеDwmSetWindowAttribute, [hwnddlg], DWMWA_EXCLUDED_FROM_PEEK, attrValue, 4
Ако сега натиснете комбинацията Win + Space или задържите курсора на мишката върху бутона „покажи работния плот“, тогава от всички прозорци ще останат само контурите и нашият прозорец ще се покаже, сякаш нищо не се е случило. Това поведение на windows е нестандартно за системата, така че трябва да се използва само когато наистина е необходимо.
- DWMFLIP3D_EXCLUDEBELOW=1
- DWMFLIP3D_EXCLUDEABOVE=2
- mov[ attrValue ], DWMFLIP3D_EXCLUDEABOVE
- извикванеDwmSetWindowAttribute, [hwnddlg], DWMWA_FLIP3D_POLICY, attrValue, 4
Според резултатите от тестването, при настройване на параметъраDWMFLIP3D_EXCLUDEABOVE, след избиране на всеки прозорец чрез Flip3D, атрибутът „върху всички прозорци“ принудително се присвоява на прозореца на нашето приложение. С опциятаDWMFLIP3D_EXCLUDEBELOWпозицията на прозореца не се променя.
- ; Структура за работа с визуализации
- структураDWM_THUMBNAIL_PROPERTIES
- dwFlagsdd?
- rcDestination RECT
- rcSource RECT
- непрозрачностdb?
- fVisibledd?
- fSourceClientAreaOnlydd?
- завършва
- DWM_TNP_RECTDESTINATION = 0x00000001
- DWM_TNP_RECTSOURCE = 0x00000002
- DWM_TNP_OPACITY = 0x00000004
- DWM_TNP_VISIBLE =0x00000008
- DWM_TNP_SOURCECLIENTAREAONLY=0x00000010
- ; Вземете дръжка на работния плот
- извикванеFindWindow, szProgman, 0
- ; Е, или някакъв добре познат прозорец на друго приложение
- ; mov eax,0x00030802
- ; Свържете нашия прозорец с визуализацията на оригиналния прозорец
- извикванеDwmRegisterThumbnail, [hwnddlg],eax, hThumb
- moveax, [ hThumb ]
- ; Показване на "живо" визуализация на изходния прозорец на нашия прозорец
- mov[реквизити. dwFlags] , \
- DWM_TNP_VISIBLE + DWM_TNP_OPACITY + DWM_TNP_RECTDESTINATION
- mov[реквизити. fSourceClientAreaOnly ] ,FALSE
- mov[реквизити. fVisible] ,ВЯРНО
- mov[реквизити. непрозрачност] , 200
- извикванеGetClientRect, [hwnddlg], подпорки. rcDestination
- извикванеDwmUpdateThumbnailProperties, [ hThumb ], подпори
След куп прозорци не са необходими допълнителни действия от наша страна. Всички промени, настъпили в главния прозорец, незабавно ще бъдат излъчени в прозореца за визуализация. За да разбиете куп прозорци, използвайте функцията DwmUnregisterThumbnail.
- WM_SENDICONICTHUMBNAILBITMAP=0x0323
- ; Задайте атрибути на прозореца
- mov[attrValue], 1
- извикванеDwmSetWindowAttribute, [hwnddlg], \
- DWMWA_HAS_ICONIC_BITMAP, attrValue, 4
- извикванеDwmSetWindowAttribute, [hwnddlg], \
- DWMWA_FORCE_ICONIC_REPRESENTATION, attrValue, 4
- ; Задаване на визуализация
- cmp[ msg ] , WM_SENDICONICTHUMBNAILBITMAP
- je. палец
- . . .
- . . .
- . . .
- . палец:
- ; Заявени размери на миниатюрни изображения
- moveax, [lparam]
- andeax, 0FFFFh
- ; EAX = Височина
- moveax, [lparam]
- shreax, 16
- ; EAX = Ширина
- ; Задайте свой собствен преглед
- извикванеGetModuleHandle, 0
- извикванеLoadImage,eax, 1, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION
- извикванеDwmSetIconicThumbnail, [hwnddlg],eax, 0
Изображението може да бъде заредено от диск или, както в този пример, получено от файлови ресурси. Ако е необходимо, трябва да се коригира до желания размер. Ако изображението поне в една от координатите е по-голямо от заявения размер, то няма да бъде показано. Важно е изображението да има дълбочина на цвета от 32 бита, в противен случай то също няма да бъде показано на визуализацията.
Приложението съдържа примери за програми с изходен код, които реализират всички ефекти и функции, описани в статията.
Примерни програми с изходен код (FASM)