Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Упражнение 2. Имитация полноэкранного режима с отключением системных клавиш






Иногда может потребоваться перевести монитор в полноэкранный режим, чтобы получить стиль игровых программ или старого доброго DOS. Обычно в таком случае отключают и курсор, а все управление программой перекладывают на клавиатуру. Из существующих вариантов переключения в полноэкранный режим наиболее простой, это настроить окно window так:

window.WindowStyle = WindowStyle.None; window.ResizeMode = ResizeMode.NoResize;

Но такой способ не убирает панель задач и не блокирует появление меню Пуск, которое также включает панель задач.

Есть более сложный способ, приведенный в " https://www.swart.ws/2009/03/kiosk-full-screen-wpf-applications.html", но он имеет те же недостатки.

Для достижения полной иллюзии режима FullScreen следует отключить системные клавиши, вызывающие панель задач и меню Пуск, и самый эффективный (на мой взгляд) способ приведен в " https://www.sql.ru/Forum/actualthread.aspx? tid=632552", которым мы и воспользуемся в данном упражнении.

Из приведенного в статье https://support.microsoft.com/kb/126449/ru сочетания клавиш мы воспользуемся только следующими вариантами:

  • CTRL + ESC: открытие меню Пуск.
  • Клавиша WIN: открытие меню Пуск.
  • ALT + ESC: показать панель задач и переключать развернутые окна.
  • ALT + TAB: переключение между программами.

Этого будет достаточно, чтобы поддерживать полноэкранный режим и одновременно не блокировать остальную функциональность клавиатуры.

  • Добавьте к решению командой File/Add/New Project новый проект с именем FullScreen и назначьте его стартовым


увеличить изображение

  • В панели Solution Explorer добавьте к корню проекта FullScreen новую папку Images командой контекстного меню Add/New Folder
  • В панели Solution Explorer командой Add/Existing Item контекстного меню для папки Images скопируйте в нее файл flower2.jpg из прилагаемого каталога Source
  • Определите в интерфейсной части окна следующий код
< Window x: Class=" FullScreen.Window1" xmlns=" https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns: x=" https://schemas.microsoft.com/winfx/2006/xaml" Title=" Window1" Height=" 300" Width=" 300" Background=" Green" Loaded=" Window_Loaded" KeyDown=" Window_KeyDown" KeyUp=" Window_KeyDown" > < Window.ContextMenu> < ContextMenu> < MenuItem Name=" changeScreen" Click=" MenuItem_Click" /> < /ContextMenu> < /Window.ContextMenu> < DockPanel> < Menu Name=" menu" DockPanel.Dock=" Top" > < MenuItem Header=" File" > < MenuItem Header=" Open" /> < MenuItem Header=" Save" /> < MenuItem Header=" SaveAs" /> < MenuItem Header=" Exit" /> < /MenuItem> < MenuItem Header=" Edit" > < MenuItem Header=" Cut" /> < MenuItem Header=" Copy" /> < MenuItem Header=" Paste" /> < /MenuItem> < /Menu> < Image Source=" Images/flower2.jpg" Stretch=" Uniform" /> < /DockPanel> < /Window>

Для настройки окна и его элементов мы применили синтаксис атрибута, а для создания каркаса контекстного меню - синтаксис тега свойства (свойства зависимости, присоединенные свойства). Атрибут Stretch элемента Image может принимать следующие значения:

  • None - изображение масштабируется до естественного размера и в области просмотра справа внизу видно столько, сколько поместилось
  • Fill - изображение масштабируется по всей области просмотра без соблюдения пропорций
  • Uniform - изображение масштабируется с соблюдением пропорций, чтобы полностью поместиться в область просмотра
  • UniformToFill - изображение масштабируется с соблюдением пропорций так, чтобы в область просмотра полностью вместился хотя бы один размер, а для другой стороны видно столько, сколько поместилось

Теперь необходимо создать обработчики для событий, выделеных в листинке, в файле присоединенного кода Window1.xaml.cs. Для этого:

  • Найдите в разметке файла Window1.xaml атрибуты событий
    • Loaded=" Window_Loaded"
    • KeyDown=" Window_KeyDown"
    • KeyUp=" Window_KeyDown"
    • Click=" MenuItem_Click"
  • В любом месте каждого из этих атрибутов щелкните правой кнопкой мыши и выполните команду Navigate to Event Handler.

 

Оболочка создаст обработчики с указанными именами, а если обработчик уже существует, то перейдет к нему.

  • Заполните файл поддержки разметки Window1.xaml.cs следующим кодом
using System; using System.Collections.Generic; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace FullScreen{ public partial class Window1: Window { // Объявляем как поля для видимости в функциях bool fullScreen = false; // Состояние экрана WindowStyle windowStyle; WindowState windowState; ResizeMode resizeMode; public Window1() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { // Запоминаем начальные параметры окна windowState = this.WindowState; windowStyle = this.WindowStyle; resizeMode = System.Windows.ResizeMode.CanResizeWithGrip; this.ResizeMode = resizeMode; changeScreen.Header = " FullScreen"; } private void MenuItem_Click(object sender, RoutedEventArgs e) { FullScreen(); } private void FullScreen() { if (! fullScreen)// Переходим в полноэкранный режим { if (this.WindowState == WindowState.Maximized) { // Чтобы скрыть панель задач и не было мерцания this.Hide(); this.WindowState = WindowState.Normal; } App.Current.MainWindow.WindowStyle = WindowStyle.None; // Без заголовка App.Current.MainWindow.Topmost = true; // На передний план App.Current.MainWindow.WindowState = WindowState.Maximized; // Развернуть App.Current.MainWindow.ResizeMode = ResizeMode.NoResize; // Неизменяемое menu.Visibility = Visibility.Collapsed; // Скрываем меню HookSystemKeys.FunHook(); // Запрещаем системные клавиши this.Visibility = Visibility.Visible; fullScreen = true; changeScreen.Header = " WindowScreen"; } else // Восстанавливаем оконный режим { this.WindowStyle = windowStyle; this.Topmost = false; this.WindowState = windowState; this.ResizeMode = resizeMode; menu.Visibility = Visibility.Visible; // Показываем меню HookSystemKeys.FunUnHook(); // Освобождаем системные клавиши fullScreen = false; changeScreen.Header = " FullScreen"; } } private void Window_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Escape) this.Close(); } }}

В приведенном коде используется класс HookSystemKeys, который нам нужно подключить к приложению и который взят из " https://www.sql.ru/Forum/actualthread.aspx? tid=632552" (там же и описан).

  • Добавьте к текущему проекту FullScreen командой Project/Add New Item новый файл с именем HookSystemKeys.cs


увеличить изображение

  • Заполните файл HookSystemKeys.cs так
using System; using System.Diagnostics; using System.Runtime.InteropServices; // Для перечисления Keys using System.Windows.Forms; namespace FullScreen{ // Отключение системной клавиши // https://www.sql.ru/Forum/actualthread.aspx? tid=632552 class HookSystemKeys { private const int WH_KEYBOARD_LL = 13; private const int WM_KEYUP = 257; // Отпускание любой клавиши private static LowLevelKeyboardProc _proc = HookCallback; private static IntPtr _hookID = IntPtr.Zero; // Поддержка флагов состояния системных клавиш static bool CtrlKey, AltKey, WinKey; private static void StateKey(int vkCode, IntPtr wParam) { switch ((Keys)vkCode) { case Keys.LControlKey: case Keys.RControlKey: if (wParam == (IntPtr)WM_KEYUP) CtrlKey = false; else CtrlKey = true; break; case Keys.LMenu: case Keys.RMenu: if (wParam == (IntPtr)WM_KEYUP) AltKey = false; else AltKey = true; break; case Keys.LWin: case Keys.RWin: if (wParam == (IntPtr)WM_KEYUP) WinKey = false; else WinKey = true; break; } } // Общедоступная упаковка оригинала public static void FunHook() { _hookID = SetHook(_proc); } public static void FunUnHook() { UnhookWindowsHookEx(_hookID); } private static IntPtr SetHook(LowLevelKeyboardProc proc) { using (Process curProcess = Process.GetCurrentProcess()) using (ProcessModule curModule = curProcess.MainModule) { return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0); } } private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { int vkCode = Marshal.ReadInt32(lParam); StateKey(vkCode, wParam); if (WinKey // Системная || CtrlKey & & (Keys)vkCode == Keys.Escape // Ctrl+Esc || AltKey & & (Keys)vkCode == Keys.Escape // Alt+Esc || AltKey & & (Keys)vkCode == Keys.Tab) // Alt+Tab { return (IntPtr)1; } else return CallNextHookEx(_hookID, nCode, wParam, lParam); } [DllImport(" user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId); [DllImport(" user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool UnhookWindowsHookEx(IntPtr hhk); [DllImport(" user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); [DllImport(" kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr GetModuleHandle(string lpModuleName); }}
  • Командой Project/Add Reference добавьте к проекту ссылку на библиотеку System.Windows.Forms.dll, в которой находится перечисление Keys кодов клавиш

 

  • Запустите проект FullScreen и испытайте построенную нами имитацию полноэкранного режима

Оконный и полноэкранный (уменьшенный масштаб) режимы будут выглядеть так

 

 

Главное меню мы создали для примера, чтобы показать, что его можно отключать в полноэкранном режиме. Переключение режимов выполняется вызовом контекстного меню по щелчку правой кнопки мыши на окне приложения. В полноэкранном режиме отключаются нежелательные для нас системные клавиши, которые могли бы привести к сбою режима:

  • CTRL + ESC: открытие меню Пуск.
  • Клавиша WIN: открытие меню Пуск.
  • ALT + ESC: показать панель задач и переключать развернутые окна.
  • ALT + TAB: переключение между программами.

В оконном режиме функциональность системных клавиш восстанавливается.

Для полного сходства можно было бы отключить мышь, но тогда все управление окном нужно будет возложить на клавиатуру. В нашем приложении мы для закрытия окна использовали клавишу Esc. Закрыть окно можно и системной комбинацией Alt+F4, которую мы не отключали. Осталась активной комбинация Alt+Space, вызывающая системное меню приложения.

Мы использовали в классе HookSystemKeys перечисление System.Windows.Forms.Keys библиотечной сборки System.Windows.Forms, а в обработчике Window_KeyDown - перечисление System.Windows.Input.Key библиотечной сборки WindowsBase.dll. Это разные перечисления и их нельзя путать.

  • Попробуйте разобраться с кодом

Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.009 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал