Как зарегистрировать один или несколько глобальных горячих клавиш для одного ключа в Winforms

Есть несколько способов добавить HotKeys в ваше приложение WinForms, например, библиотеку NHotkey, однако многие из них требуют добавления специфического нажатия клавиш (например, Alt + Ctrl + F8) для выполнения и работают только тогда, когда форма сфокусирована, что не является правильный способ продолжить работу с Global HotKeys. Как любитель компьютеров, мне нравится, когда все очень просто в использовании, и я использую множество приложений, например, для записи экрана, например camtasia, который использует полезную функцию HotKey, которая позволяет запускать или приостанавливать текущий процесс записи, просто нажав F9 или F10. Заинтересовавшись такой функцией, я начал исследовать ее, пока не нашел хорошее решение для добавления таких горячих клавиш в приложение WinForms, и я хочу поделиться этим решением с вами сегодня.

Добавление одного HotKey

Чтобы продолжить прикрепление одного HotKey для одного ключа, вам нужно будет импортировать в качестве первого шага модуль InteropServices в верхней части вашего класса. Это позволит вам импортировать метод RegisterHotKey user32.dll Windows. Этот метод используется для регистрации вашей горячей клавиши глобально и в соответствии с той, которая нажата, выполните какое-то действие. В качестве первого аргумента метод ожидает дескриптор окна, с которым связан элемент управления, а именно Form.Handle, затем в качестве второго аргумента уникальный идентификатор, который идентифицирует ваш HotKey в вашем собственном приложении. Этот идентификатор может быть тем, который вам нужен, если это целое число. В качестве третьего аргумента укажите 0x0000, чтобы указать нулевое значение в качестве модификатора, и, наконец, KeyCode of Key, который будет вызывать этот HotKey при нажатии. Ожидается, что этот аргумент будет целым числом, поэтому вы можете проверьте список кодов ключей на официальном сайте MSDN или просто принудительно преобразуйте перечисление Keys в Windows Forms, более удобное для разработчиков, как чистые коды. В качестве последнего шага вам нужно переопределить функцию WndProc user32.dll в вашем коде, чтобы вы могли ловить, когда нажата горячая клавиша.

В этом примере мы прикрепим MessageBox, когда пользователь нажимает F9 за пределами нашей формы:

using System.Windows.Forms;
using System;
using System.Diagnostics;
using System.Threading;
using System.Drawing.Printing;
// 1. Import the InteropServices type
using System.Runtime.InteropServices;
namespace Sandbox
{
public partial class Form1 : Form
{
// 2. Import the RegisterHotKey Method
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
public Form1()
{
InitializeComponent();
// 3. Register HotKey
// Set an unique id to your Hotkey, it will be used to
// identify which hotkey was pressed in your code to execute something
int UniqueHotkeyId = 1;
// Set the Hotkey triggerer the F9 key
// Expected an integer value for F9: 0x78, but you can convert the Keys.KEY to its int value
// See: https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
int HotKeyCode = (int)Keys.F9;
// Register the "F9" hotkey
Boolean F9Registered = RegisterHotKey(
this.Handle, UniqueHotkeyId, 0x0000, HotKeyCode
);
// 4. Verify if the hotkey was succesfully registered, if not, show message in the console
if (F9Registered)
{
Console.WriteLine("Global Hotkey F9 was succesfully registered");
}
else
{
Console.WriteLine("Global Hotkey F9 couldn't be registered !");
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
protected override void WndProc(ref Message m)
{
// 5. Catch when a HotKey is pressed !
if (m.Msg == 0x0312)
{
int id = m.WParam.ToInt32();
// MessageBox.Show(string.Format("Hotkey #{0} pressed", id));
if (id == 1)
{
MessageBox.Show("F9 Was pressed !");
}
}
base.WndProc(ref m);
}
}
}

Добавление нескольких горячих клавиш

Кроме того, в некоторых случаях вашему приложению требуется более одной горячей клавиши для запуска нескольких действий. Вы можете легко добиться этого поведения, просто увеличивая идентификатор HotKey для каждого присоединенного HotKey. Как мы описали ранее, метод RegisterHotKey ожидает уникальный идентификатор в качестве второго аргумента, который вам нужно предоставить вручную. В следующем примере мы добавим 2 глобальных горячих клавиши, а именно F9 и F10, используя в качестве идентификатора для каждой клавиши 1 и 2 соответственно (увеличение до 3, 4, 5 и т. Д., Если подключено больше горячих клавиш). Когда эти клавиши нажаты, появится простое окно сообщения, предупреждающее о нажатии горячей клавиши:

using System.Windows.Forms;
using System;
using System.Diagnostics;
using System.Threading;
using System.Drawing.Printing;
// 1. Import the InteropServices type
using System.Runtime.InteropServices;
namespace Sandbox
{
public partial class Form1 : Form
{
// 2. Import the RegisterHotKey Method
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
public Form1()
{
InitializeComponent();
// 3. Register HotKeys
// Set an unique id to your Hotkey, it will be used to
// identify which hotkey was pressed in your code to execute something
int FirstHotkeyId = 1;
// Set the Hotkey triggerer the F9 key
// Expected an integer value for F9: 0x78, but you can convert the Keys.KEY to its int value
// See: https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
int FirstHotKeyKey = (int)Keys.F9;
// Register the "F9" hotkey
Boolean F9Registered = RegisterHotKey(
this.Handle, FirstHotkeyId, 0x0000, FirstHotKeyKey
);
// Repeat the same process but with F10
int SecondHotkeyId = 2;
int SecondHotKeyKey = (int)Keys.F10;
Boolean F10Registered = RegisterHotKey(
this.Handle, SecondHotkeyId, 0x0000, SecondHotKeyKey
);
// 4. Verify if both hotkeys were succesfully registered, if not, show message in the console
if (!F9Registered)
{
Console.WriteLine("Global Hotkey F9 couldn't be registered !");
}
if (!F10Registered)
{
Console.WriteLine("Global Hotkey F10 couldn't be registered !");
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
protected override void WndProc(ref Message m)
{
// 5. Catch when a HotKey is pressed !
if (m.Msg == 0x0312)
{
int id = m.WParam.ToInt32();
// MessageBox.Show(string.Format("Hotkey #{0} pressed", id));
// 6. Handle what will happen once a respective hotkey is pressed
switch (id)
{
case 1:
MessageBox.Show("F9 Key Pressed ! Do something here ... ");
break;
case 2:
MessageBox.Show("F10 Key Pressed ! Do something here ... ");
break;
}
}
base.WndProc(ref m);
}
}
}

Отменить регистрацию HotKey

Возможно, ваш HotKey может работать на каком-то этапе вашего приложения, то есть, если пользователь меняет представление или что-то особенное происходит в вашем приложении, этот HotKey больше не должен быть доступен. Вы можете отменить регистрацию идентификатора, просто запустив метод UnregisterHotKey в том же контексте и установив в качестве второго аргумента идентификатор зарегистрированного HotKey:

Заметка

Иногда лучше иметь логический флаг, который разрешает выполнение некоторого кода или не соответствует статусу вашего приложения, а не отменяет регистрацию HotKey. Однако полезно знать, как их отменить.

using System.Windows.Forms;
using System;
using System.Diagnostics;
using System.Threading;
using System.Drawing.Printing;
// 1. Import the InteropServices type
using System.Runtime.InteropServices;
namespace Sandbox
{
public partial class Form1 : Form
{
// 2. Import the RegisterHotKey Method
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
// 3. Import the UnregisterHotKey Method
[DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
public Form1()
{
InitializeComponent();
// 4. Register the "F9" hotkey
int UniqueHotkeyId = 1;
int HotKeyCode = (int)Keys.F9;
Boolean F9Registered = RegisterHotKey(
this.Handle, UniqueHotkeyId, 0x0000, HotKeyCode
);
if (F9Registered)
{
Console.WriteLine("Global Hotkey F9 was succesfully registered");
}
else
{
Console.WriteLine("Global Hotkey F9 couldn't be registered !");
}
// 5. Unregister F9 HotKey
Boolean F9UnRegistered = UnregisterHotKey(this.Handle, UniqueHotkeyId);
if (F9UnRegistered)
{
Console.WriteLine("Global Hotkey F9 was succesfully UNregistered");
}
else
{
Console.WriteLine("Global Hotkey F9 couldn't be UNregistered !");
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0312)
{
int id = m.WParam.ToInt32();
// MessageBox.Show(string.Format("Hotkey #{0} pressed", id));
if (id == 1)
{
// This will never happen because we have registered the hotkey !
MessageBox.Show("F9 Was pressed !");
}
}
base.WndProc(ref m);
}
}
}
Ссылка на основную публикацию
Adblock
detector