Рисование пользовательских кнопок в Windows Vista / 7 Aero Titlebar - PullRequest
10 голосов
/ 07 ноября 2010

Я нашел этот вопрос на StackOverflow . По сути, пользователь хотел нарисовать пользовательские кнопки на заголовке.

Я попробовал код и понял, что он работает в Vista / 7, только когда Aero отключен. У меня вопрос, есть ли способ рисовать пользовательские кнопки на заголовке , когда Aero включен?

Кроме того, есть ли способ чтения информации из текущей темы, чтобы я мог стилизовать свои кнопки в соответствии с уже существующими.


Обновление

Вот скриншот с моего компьютера, демонстрирующий вышеуказанную концепцию. Я получил дополнительные кнопки заголовков после установки DisplayFusion.
Notepad2 showing additional buttons.

И я знаю, что DisplayFusion - это программа .NET, потому что она открывается в .NET Reflector. Недостатком является то, что программа запутана. Не то чтобы я хотел декомпилировать программу или что-то еще; Я просто хочу добавить кнопку в заголовок, чтобы сделать что-то еще (например, свернуть в системный трей).
Ниже приведен скриншот, подтверждающий, что программа представляет собой приложение .NET.
.NET Reflector showing DisplayFusion

Ответы [ 3 ]

4 голосов
/ 12 июня 2012

Я провел некоторые исследования в этой области, поскольку также реализовал это в своем собственном решении для нескольких мониторов. Способ, которым DisplayFusion и TeamViewer реализовали это, заключается в наложении пользовательской формы на нужное окно, содержащее кнопки. Вы можете использовать Spy ++, чтобы подтвердить это.

Это общая идея:

  1. Напишите хук DLL для получения уведомлений при создании, удалении, активации, изменении или изменении размера окна.
  2. Создайте прозрачную форму, используя прозрачный ключ или используя alpha-PNG и GDI + решение и смоделируйте кнопку (кнопки), нарисовав ее самостоятельно.
  3. При создании / удалении окна вы показываете / скрываете форму заголовка кнопки для нужного окна.
  4. В сообщениях изменения размера / положения окна вы изменяете форму кнопки заголовка.
  5. При активации окна вы устанавливаете положение Z окна так, чтобы оно находилось поверх желаемого окна.

Получение и установка позиции Z с помощью API GetWindow и SetWindowPos.
Помните, что DLL должна быть написана на родном языке. Однако вы можете использовать что-то подобное, чтобы обойти эту проблему: Использование оконных сообщений для реализации глобальных системных хуков в C #

А вот и мой результат:

enter image description here

4 голосов
/ 14 января 2011

До тех пор, пока вы готовы перерисовать все содержимое строки заголовка, вы можете использовать метод DwmExtendFrameIntoClientArea API-интерфейса DWM, который включает установку окна без заголовка, позволяя DWM рисовать свое стекло в полезной области. создать новое пространство, которое выглядит как заголовок заголовка, но на самом деле находится в вашей клиентской области, так что вы можете рисовать на нем кнопки.

Недостатком этого метода является то, что вам придется делать стандартные кнопки, если вы хотите их. Свернуть, Развернуть и Закрыть не проблема для воссоздания (хотя вы обнаружите, что кнопка максимизации - это кнопка переключения с внешним видом, основанным на состоянии), но вы можете столкнуться с проблемой при воссоздании кнопки в верхнем левом углу. Конечно, вам также придется переписать свой заголовок, но я не могу представить, что у вас возникнут какие-либо проблемы с этим.

Что касается чтения данных текущей темы, чтобы перестроить ваши кнопки как их, извините, но я ничего об этом не знаю. Я бы предложил использовать прозрачность при построении кнопок на заголовке и использовать полупрозрачные эффекты свечения и так далее. Таким образом, вы сможете сохранить фон стекла и просто изменить его внешний вид, наложив полупрозрачный цвет. Кроме того, если вы сделаете это таким образом, то смещенные зеркальные блики на стекле будут двигаться естественным образом, тогда как, если вы просто получили цвета их тем, вы обнаружите, что либо вы не получили доступа к их отражениям, либо они заново воссоздали внутри пространство ваших кнопок. Конечно, только мои два цента - если вы можете найти способ сделать вашу тему цвета и так далее, во что бы то ни стало.

Однако есть одно предостережение - есть еще один поток StackOverflow (/2016969/net-framework-4-0-i-risovanie-na-vypuske-aero-glass#2016971), который описывает проблему с методом DWM API DwmExtendFrameIntoClientArea, поэтому на вашем месте я бы прочитал это, прежде чем пытаться найти решение.

0 голосов
/ 13 ноября 2015

Хорошо, системные хуки являются прямым подходом для получения информации об измененных положениях окна, и Предложение Джелле с прозрачной формой очень хорошее Но вы можете использовать менее инвазивный метод для получения информации об окнах рабочего стола, используя user32.dll

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(HandleRef hWnd, out RECT lpRect);

Дескрипторы окна, которые вы можете получить, используя EnumDesktopWindows

[DllImport("user32.dll", EntryPoint = "EnumDesktopWindows", 
ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDelegate lpEnumCallbackFunction, IntPtr lParam);

Пример этого вы можете получить из потока получение списка всех приложений в c-sharp

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...