
В Windows при переключении языка с помощью ALT + SHIFT (не наоборот) поверх всех окон появляется окно с отображением выбранного языка. В WPF-приложении понадобилось реализовать такое же окно: Я реализовал окно со свойством Topmost=true , чтобы оно всегда было поверх всех окон. Но есть проблема — при открытии этого окна оно сворачивает все полноэкранные приложения.
То есть, если я открою его в любой полноэкранной игре, то окно игры свернется. В то же время с окном переключения раскладки Windows этого не происходит. Насколько я понимаю, в Windows используется не окно, а что-то вроде оверлея, типа Discord. Но Discord ищет запущенную игру, в то время как окно Windows может быть нарисовано поверх любых окон. Как я могу реализовать такое же окно? Желательно без использования библиотек DirectX, чтобы этот оверлей работал не только для конкретных окон
Отслеживать
задан 21 мая 2022 в 7:51
5,463 2 2 золотых знака 9 9 серебряных знаков 32 32 бронзовых знака
Как открыть доступ поверх всех окон для различных приложений на андроид 10
Когда я раньше писал читы для игр, то пользовался отрисовкой каких-либо сущностей с помощью directX. Можете попробовать загуглить «DirectX Overlay»
21 мая 2022 в 8:52
Нашёл вот такую статейку — guidedhacking.com/threads/c-direct-x-overlay-with-setup.15295. Думаю, она поможет прояснить эту тему
21 мая 2022 в 8:54
В WinForms достаточно задавать значение TopMost = true; в таймере. Такое окно будет поверх всех и не будет мешать полноэкранным приложениям. Но для реакции на Esc нужен хук, скорее всего.
11 сен 2022 в 12:32
11 сен 2022 в 18:26
11 сен 2022 в 18:49
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Поскольку оверлей DirectX должен отрисовываться для конкретного окна, а мне нужна реализация этого окошка поверх вообще всех окон, я решил отказаться от идеи отрисовки оверлея.
По сути решение оказалось на поверхности. Нашел его по подсказке Alexander Petrov .
Первое, что нужно сделать — это задать окну свойство Topmost=»True» , чтобы окно всегда было поверх остальных окон. А также ShowInTaskbar=»False» , чтобы окно не сворачивало полноэкранные приложения появляясь на панели задач при открытии.
При этом ни в коем случае нельзя активировать его, то есть вызывать Focus() и Activate() , чтобы окно не перехватывало фокус у других окон.
В целом это работает, но если случайно нажать на окно мышью — оно все равно получит фокус. Чтобы избежать этого, можно переопределить метод OnSourceInitialized() и запретить окну получать фокус. Решение нашел здесь.
protected override void OnSourceInitialized(EventArgs e) < base.OnSourceInitialized(e); var helper = new WindowInteropHelper(this); SetWindowLong(helper.Handle, GWL_EXSTYLE, GetWindowLong(helper.Handle, GWL_EXSTYLE) | WS_EX_NOACTIVATE); >private const int GWL_EXSTYLE = -20; private const int WS_EX_NOACTIVATE = 0x08000000; [DllImport(«user32.dll»)] public static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); [DllImport(«user32.dll»)] public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
В первоначальной версии вопроса я также отметил, что окну нужен фокус, чтобы срабатывало событие KeyDown для отслеживания нажатия некоторых клавиш. С отключением фокуса окна событие KeyDown использовать не получится. Вместо этого можно использовать глобальные горячие клавиши, через пакет NHotkey.Wpf (можно установить через NuGet )
Как закрепить окно поверх всех окон в Windows 2021 | Pinwin, Deskpins
Источник: ru.stackoverflow.com