Работа с 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.

  1. структураDWM_BLURBEHIND
  2. dwFlagsdd?
  3. fEnabledd?
  4. hRgnBlurdd?
  5. fTransitionOnMaximizeddd?
  6. завършва
  7. DWM_BB_ENABLE = 0x00000001
  8. DWM_BB_BLURREGION = 0x00000002
  9. DWM_BB_TRANSITIONONMAXIMIZED = 0x00000004
  1. ; Активирайте ефекта на размазване
  2. mov[bb. dwFlags], DWM_BB_ENABLE
  3. mov[bb. fEnable] ,TRUE
  4. mov[bb. fTransitionOnMaximized],FALSE
  5. mov[bb. hRgnBlur], 0
  6. извикванеDwmEnableBlurBehindWindow, [hwnddlg], bb

Важна забележка. За да работи ефектът, прозорецът трябва да е черен, иначе ще се окаже пълна глупост. За целта се обръщаме към една от предишните статии. Тук няма да дублирам този материал, вижте напълно работещия пример в прикачения изходен код.

  1. структураПОЛЕТА
  2. cxLeftW >dd?
  3. cxRightW >dd?
  4. cyTopHeightdd?
  5. cyBottomHeightdd?
  6. завършва
  1. ; Активирайте ефекта на размазване
  2. mov[bb. dwFlags], DWM_BB_ENABLE
  3. mov[bb. fEnable] ,TRUE
  4. mov[bb. fTransitionOnMaximized],FALSE
  5. mov[bb. hRgnBlur], 0
  6. извикванеDwmEnableBlurBehindWindow, [hwnddlg], bb
  7. ; Задайте отрицателна подложка за "стъклен" прозорец
  8. mov[ полета . cyBottomHeight] , - 1
  9. извикванеDwmExtendFrameIntoClientArea, [hwnddlg], полета

Не забравяйте да зададете черен фон на прозореца, преди да приложите всички тези ефекти.

  1. ; Вземете дръжката на прозореца на конзолата
  2. извикванеGetConsoleWindow
  3. ; Активирайте ефекта на размазване
  4. mov[bb. dwFlags], DWM_BB_ENABLE
  5. mov[bb. fEnable] ,TRUE
  6. mov[bb. hRgnBlur],NULL
  7. извикванеDwmEnableBlurBehindWindow,eax, bb
  1. DWMWA_NCRENDERING_ENABLED = 1
  2. DWMWA_NCRENDERING_POLICY = 2
  3. DWMWA_TRANSITIONS_FORCEDISABLED = 3
  4. DWMWA_ALLOW_NCPAINT=4
  5. DWMWA_CAPTION_BUTTON_BOUNDS = 5
  6. DWMWA_NONCLIENT_RTL_LAYOUT = 6
  7. DWMWA_FORCE_ICONIC_REPRESENTATION = 7
  8. DWMWA_FLIP3D_POLICY = 8
  9. DWMWA_EXTENDED_FRAME_BOUNDS = 9
  10. DWMWA_HAS_ICONIC_BITMAP = 10
  11. DWMWA_DISALLOW_PEEK=11
  12. DWMWA_EXCLUDED_FROM_PEEK = 12
  13. DWMWA_CLOAK = 13
  14. DWMWA_CLOAKED = 14
  15. DWMWA_FREEZE_REPRESENTATION = 15
  16. DWMWA_LAST = 16

Можете да промените атрибутите на прозореца с помощта на функцията DwmSetWindowAttribute и съответно да получите зададените атрибути с помощта на функцията DwmGetWindowAttribute.

  1. mov[attrValue], 1
  2. извикванеDwmSetWindowAttribute, [hwnddlg], DWMWA_EXCLUDED_FROM_PEEK, attrValue, 4

Ако сега натиснете комбинацията Win + Space или задържите курсора на мишката върху бутона „покажи работния плот“, тогава от всички прозорци ще останат само контурите и нашият прозорец ще се покаже, сякаш нищо не се е случило. Това поведение на windows е нестандартно за системата, така че трябва да се използва само когато наистина е необходимо.

  1. DWMFLIP3D_EXCLUDEBELOW=1
  2. DWMFLIP3D_EXCLUDEABOVE=2
  1. mov[ attrValue ], DWMFLIP3D_EXCLUDEABOVE
  2. извикванеDwmSetWindowAttribute, [hwnddlg], DWMWA_FLIP3D_POLICY, attrValue, 4

Според резултатите от тестването, при настройване на параметъраDWMFLIP3D_EXCLUDEABOVE, след избиране на всеки прозорец чрез Flip3D, атрибутът „върху всички прозорци“ принудително се присвоява на прозореца на нашето приложение. С опциятаDWMFLIP3D_EXCLUDEBELOWпозицията на прозореца не се променя.

  1. ; Структура за работа с визуализации
  2. структураDWM_THUMBNAIL_PROPERTIES
  3. dwFlagsdd?
  4. rcDestination RECT
  5. rcSource RECT
  6. непрозрачностdb?
  7. fVisibledd?
  8. fSourceClientAreaOnlydd?
  9. завършва
  10. DWM_TNP_RECTDESTINATION = 0x00000001
  11. DWM_TNP_RECTSOURCE = 0x00000002
  12. DWM_TNP_OPACITY = 0x00000004
  13. DWM_TNP_VISIBLE =0x00000008
  14. DWM_TNP_SOURCECLIENTAREAONLY=0x00000010
  1. ; Вземете дръжка на работния плот
  2. извикванеFindWindow, szProgman, 0
  3. ; Е, или някакъв добре познат прозорец на друго приложение
  4. ; mov eax,0x00030802
  5. ; Свържете нашия прозорец с визуализацията на оригиналния прозорец
  6. извикванеDwmRegisterThumbnail, [hwnddlg],eax, hThumb
  7. moveax, [ hThumb ]
  8. ; Показване на "живо" визуализация на изходния прозорец на нашия прозорец
  9. mov[реквизити. dwFlags] , \
  10. DWM_TNP_VISIBLE + DWM_TNP_OPACITY + DWM_TNP_RECTDESTINATION
  11. mov[реквизити. fSourceClientAreaOnly ] ,FALSE
  12. mov[реквизити. fVisible] ,ВЯРНО
  13. mov[реквизити. непрозрачност] , 200
  14. извикванеGetClientRect, [hwnddlg], подпорки. rcDestination
  15. извикванеDwmUpdateThumbnailProperties, [ hThumb ], подпори

След куп прозорци не са необходими допълнителни действия от наша страна. Всички промени, настъпили в главния прозорец, незабавно ще бъдат излъчени в прозореца за визуализация. За да разбиете куп прозорци, използвайте функцията DwmUnregisterThumbnail.

  1. WM_SENDICONICTHUMBNAILBITMAP=0x0323
  1. ; Задайте атрибути на прозореца
  2. mov[attrValue], 1
  3. извикванеDwmSetWindowAttribute, [hwnddlg], \
  4. DWMWA_HAS_ICONIC_BITMAP, attrValue, 4
  5. извикванеDwmSetWindowAttribute, [hwnddlg], \
  6. DWMWA_FORCE_ICONIC_REPRESENTATION, attrValue, 4
  1. ; Задаване на визуализация
  2. cmp[ msg ] , WM_SENDICONICTHUMBNAILBITMAP
  3. je. палец
  4. . . .
  5. . . .
  6. . . .
  7. . палец:
  8. ; Заявени размери на миниатюрни изображения
  9. moveax, [lparam]
  10. andeax, 0FFFFh
  11. ; EAX = Височина
  12. moveax, [lparam]
  13. shreax, 16
  14. ; EAX = Ширина
  15. ; Задайте свой собствен преглед
  16. извикванеGetModuleHandle, 0
  17. извикванеLoadImage,eax, 1, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION
  18. извикванеDwmSetIconicThumbnail, [hwnddlg],eax, 0

Изображението може да бъде заредено от диск или, както в този пример, получено от файлови ресурси. Ако е необходимо, трябва да се коригира до желания размер. Ако изображението поне в една от координатите е по-голямо от заявения размер, то няма да бъде показано. Важно е изображението да има дълбочина на цвета от 32 бита, в противен случай то също няма да бъде показано на визуализацията.

Приложението съдържа примери за програми с изходен код, които реализират всички ефекти и функции, описани в статията.

Примерни програми с изходен код (FASM)