Вы, наверняка, знаете, что в Vista и Windows 7 существует функция Flip3D, а в Windows 7 еще и Aero Peek.
Но вы, наверняка, не знаете, что можно заставить ваше окно (приложение) не подчиняться правилам для всех окон в данных возможностях Windows. Для этого следует изучить Desktop Window Manager API.
Итак, с чего начать? Как всегда, если мы пишем приложение на .net (WinForms или WPF), нам нужно проимпортировать необходимые методы. Стоит заметить, что в случае WinForms получить HWND окна очень просто, для этого есть свойство Form::Handle, в случае же WPF можно воспользоваться классом WindowInteropHelper, так чтобы получить HWND главного окна можно написать так:
Вернемся теперь к необходимым функциям. Первая функция на которую стоит обратить внимание – это DwmIsCompositionEnabled, она нам позволяет определить включен ли Aero Glass на компьютере:
Отлично, теперь мы знаем когда можно “играться” с 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. Для обычной формы это можно сделать так:
Результат будет таким (это чтобы было более понятно о чем я вообще пишу):
Так же можно заставить свое окно не подчиняться правилам Aero 3D (это когда используем WinKey+Tab для переключения между окнами). Для этого нужно рассмотреть атрибут DWMWA_FLIP3D_POLICY, для него можно установить значения “Обычное поведение”, “Показывать поверх 3D”, “Показывать за 3D”, правда у меня работало либо “обычное поведение”, либо “показывать за 3D”, поверх не получилось сделать.
Результат следующий:
Как это можно использовать – уже сложнее представить. Ну…, мое дело рассказать :) Удачи!
Но вы, наверняка, не знаете, что можно заставить ваше окно (приложение) не подчиняться правилам для всех окон в данных возможностях Windows. Для этого следует изучить Desktop Window Manager API.
Итак, с чего начать? Как всегда, если мы пишем приложение на .net (WinForms или WPF), нам нужно проимпортировать необходимые методы. Стоит заметить, что в случае WinForms получить HWND окна очень просто, для этого есть свойство Form::Handle, в случае же WPF можно воспользоваться классом WindowInteropHelper, так чтобы получить HWND главного окна можно написать так:
- IntPtr hwnd = new WindowInteropHelper(Application.Current.MainWindow).Handle;
* This source code was highlighted with Source Code Highlighter.
Вернемся теперь к необходимым функциям. Первая функция на которую стоит обратить внимание – это DwmIsCompositionEnabled, она нам позволяет определить включен ли Aero Glass на компьютере:
- public partial class FormSample : Form
- {
- [DllImport("dwmapi.dll", PreserveSig = false)]
- public static extern bool DwmIsCompositionEnabled();
- public FormSample()
- {
- InitializeComponent();
- if (Environment.OSVersion.Version.Major < 6)
- {
- // Dwm не работает, старая версия Windows
- }
- else if (!DwmIsCompositionEnabled())
- {
- // Aero Glass и Aero 3D отключены (не поддерживаются)
- }
- else
- {
- // Aero Glass и Aero 3D работают
- }
- }
- }
* 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. Для обычной формы это можно сделать так:
- public partial class FormSample : Form
- {
- [Flags]
- public enum DwmWindowAttribute
- {
- ExcludedFromPeek = 12
- }
- [DllImport("dwmapi.dll", PreserveSig = false)]
- public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
- public static void RemoveFromAeroPeek(IntPtr hwnd)
- {
- int attrValue = 1; // TRUE
- DwmSetWindowAttribute(hwnd, (int)DwmWindowAttribute.ExcludedFromPeek, ref attrValue, sizeof(int));
- }
- public FormSample()
- {
- InitializeComponent();
- // Делаем видимым при Aero Peek
- RemoveFromAeroPeek(Handle);
- }
- }
* This source code was highlighted with Source Code Highlighter.
Результат будет таким (это чтобы было более понятно о чем я вообще пишу):
Так же можно заставить свое окно не подчиняться правилам Aero 3D (это когда используем WinKey+Tab для переключения между окнами). Для этого нужно рассмотреть атрибут DWMWA_FLIP3D_POLICY, для него можно установить значения “Обычное поведение”, “Показывать поверх 3D”, “Показывать за 3D”, правда у меня работало либо “обычное поведение”, либо “показывать за 3D”, поверх не получилось сделать.
- public partial class FormSample : Form
- {
- [Flags]
- public enum DwmWindowAttribute
- {
- Flip3DPolicy = 8
- }
- // Flip 3D policies
- public enum Flip3DPolicy
- {
- Default = 0,
- ExcludeBelow,
- ExcludeAbove
- }
- [DllImport("dwmapi.dll", PreserveSig = false)]
- public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
- public static void SetFlip3DPolicy(IntPtr hwnd)
- {
- int attrValue = (int)Flip3DPolicy.ExcludeBelow;
- DwmSetWindowAttribute(hwnd, (int)DwmWindowAttribute.Flip3DPolicy, ref attrValue, sizeof(int));
- }
- public FormSample()
- {
- InitializeComponent();
- SetFlip3DPolicy(Handle);
- }
- }
* This source code was highlighted with Source Code Highlighter.
Результат следующий:
Как это можно использовать – уже сложнее представить. Ну…, мое дело рассказать :) Удачи!