Как стать автором
Обновить

Windows 7 & DWN: знаете ли вы, что не все окна должны подчиняться Flip3D и Aero Peek

Время на прочтение4 мин
Количество просмотров3.7K
Вы, наверняка, знаете, что в Vista и Windows 7 существует функция Flip3D, а в Windows 7 еще и Aero Peek.

Aero Peek Flip3D

Но вы, наверняка, не знаете, что можно заставить ваше окно (приложение) не подчиняться правилам для всех окон в данных возможностях Windows. Для этого следует изучить Desktop Window Manager API.

Итак, с чего начать? Как всегда, если мы пишем приложение на .net (WinForms или WPF), нам нужно проимпортировать необходимые методы. Стоит заметить, что в случае WinForms получить HWND окна очень просто, для этого есть свойство Form::Handle, в случае же WPF можно воспользоваться классом WindowInteropHelper, так чтобы получить HWND главного окна можно написать так:

  1. IntPtr hwnd = new WindowInteropHelper(Application.Current.MainWindow).Handle;
* This source code was highlighted with Source Code Highlighter.


Вернемся теперь к необходимым функциям. Первая функция на которую стоит обратить внимание – это DwmIsCompositionEnabled, она нам позволяет определить включен ли Aero Glass на компьютере:

  1. public partial class FormSample : Form
  2. {
  3.   [DllImport("dwmapi.dll", PreserveSig = false)]
  4.   public static extern bool DwmIsCompositionEnabled();
  5.   public FormSample()
  6.   {
  7.     InitializeComponent();
  8.     if (Environment.OSVersion.Version.Major < 6)
  9.     {
  10.       // Dwm не работает, старая версия Windows
  11.     }
  12.     else if (!DwmIsCompositionEnabled())
  13.     {
  14.       // Aero Glass и Aero 3D отключены (не поддерживаются)
  15.     }
  16.     else
  17.     {
  18.       // Aero Glass и Aero 3D работают
  19.     }
  20.   }
  21. }
* This source code was highlighted with Source Code Highlighter.


Отлично, теперь мы знаем когда можно “играться” с Dwm, следующая функция, которая поможет нам работать с Dwn – это DwmSetWindowAttribute. Это уже основная функция, при помощи которой мы можем управлять нашим окном и говорить системе как его следует отображать.

Например, действие первое. Задача, мы хотим сделать такое приложение, которое отображается даже тогда, когда пользователь включает режим Aero Peek (действие, похожее на гаджет). Представьте на вашем мониторе куча запущенных окон, вам лень искать необходимое окно при помощи WinKey+Tab, а хочется увидеть нужные окна при помощи WinKey+Space – это может быть и обычный мессенджер, и какой-то ваш профайлер, при помощи которого вы следите за работой чего либо, ну и многое другое. Так, например, вот в этой статье “Joel 'Jaykul' Bennett — Fun with PInvoke and Aero Peek“ описывается как можно сделать это с популярным мессенджером Miranda (с этой статьи меня и заинтересовал Dwn и какие возможности он еще предоставляет). Правда в данной статье используются флаги DwmNCRenderingPolicy, которые на самом деле пригодны для установления значений при использовании флага DWMWA_NCRENDERING_POLICY, а не DWMWA_EXCLUDED_FROM_PEEK. Для обычной формы это можно сделать так:

  1. public partial class FormSample : Form
  2. {
  3.   [Flags]
  4.   public enum DwmWindowAttribute
  5.   {
  6.     ExcludedFromPeek = 12
  7.   }
  8.   [DllImport("dwmapi.dll", PreserveSig = false)]
  9.   public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
  10.   public static void RemoveFromAeroPeek(IntPtr hwnd)
  11.   {
  12.     int attrValue = 1; // TRUE
  13.     DwmSetWindowAttribute(hwnd, (int)DwmWindowAttribute.ExcludedFromPeek, ref attrValue, sizeof(int));
  14.   }
  15.   public FormSample()
  16.   {
  17.     InitializeComponent();
  18.     // Делаем видимым при Aero Peek
  19.     RemoveFromAeroPeek(Handle);
  20.   }
  21. }
* This source code was highlighted with Source Code Highlighter.


Результат будет таким (это чтобы было более понятно о чем я вообще пишу):

Remove Aero Peek Result

Так же можно заставить свое окно не подчиняться правилам Aero 3D (это когда используем WinKey+Tab для переключения между окнами). Для этого нужно рассмотреть атрибут DWMWA_FLIP3D_POLICY, для него можно установить значения “Обычное поведение”, “Показывать поверх 3D”, “Показывать за 3D”, правда у меня работало либо “обычное поведение”, либо “показывать за 3D”, поверх не получилось сделать.

  1. public partial class FormSample : Form
  2. {
  3.   [Flags]
  4.   public enum DwmWindowAttribute
  5.   {
  6.     Flip3DPolicy = 8
  7.   }
  8.   // Flip 3D policies
  9.   public enum Flip3DPolicy
  10.   {
  11.     Default = 0,
  12.     ExcludeBelow,
  13.     ExcludeAbove
  14.   }
  15.   [DllImport("dwmapi.dll", PreserveSig = false)]
  16.   public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
  17.   public static void SetFlip3DPolicy(IntPtr hwnd)
  18.   {
  19.     int attrValue = (int)Flip3DPolicy.ExcludeBelow;
  20.     DwmSetWindowAttribute(hwnd, (int)DwmWindowAttribute.Flip3DPolicy, ref attrValue, sizeof(int));
  21.   }
  22.   public FormSample()
  23.   {
  24.     InitializeComponent();
  25.     SetFlip3DPolicy(Handle);
  26.   }
  27. }
* This source code was highlighted with Source Code Highlighter.


Результат следующий:

 Set 3DFlip Policy Result

Как это можно использовать – уже сложнее представить. Ну…, мое дело рассказать :) Удачи!

Progg it
Теги:
Хабы:
Всего голосов 43: ↑33 и ↓10+23
Комментарии28

Публикации

Истории

Работа

.NET разработчик
49 вакансий

Ближайшие события

15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань