Вы, наверняка, знаете, что в 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