Как стать автором
Обновить

Комментарии 14

Вы не совсем поняли, данный метод позволяет использовать именно глобальные горячие клавиши — глобальные на уровне операционной системы, а не приложения
спаибо
Суровато.

Присоединяюсь к вопросу насчёт команд. Там это вроде примерно так (VS под рукой нет) делается:
window.InputBindings.Add(new KeyBinding(YourCommand, Key.G, ModifierKeys.Control | ModifierKeys.Alt));

+ поддержка в разметке, отсутствие завязки на WinAPI.

Ещё не нашел отличий между последним и пред-пред-последним листингом. Наверное там должно быть что-то другое.
Честно говоря, как прочитал заголовок, то сразу подумал именно про KeyBinding. Был немного удивлен содержимым. Присоединяюсь к вопросу: Зачем?
насчёт комманд ответил выше, по поводу листингов — сейчас поправлю, спасибо
Считал что достаточно внимательно прочитал пост вместе с листингами, но почему-то не дошло что речь идёт про глобальные в смысле «в пределах ОС». Судя по комментариям не только я :)

Тогда «makes sense», спасибо за статью. Странно что в .net этого нет.

Всем, кто предлагает использовать комманды — большой минус. Даже из заголовка ясно, что имеются ввиду хоткеи на уровне ОС, а не на уровне приложения.

Юзабельная реализация обработки глобальных хоткеев в WPF здесь. Проект здесь.
Тут появляется одна небольшая проблема — обработка вызовов WndProc. Дело в том, что в WPF, в отличие от Windows Forms, нельзя просто перегрузить эту функцию в окне приложения.
Сам недавно с этим столкнулся. Можно передавать в RegisterHotkey первым параметром передавать нуль, тогда сообщения будут транслироваться вызвавшему RegisterHotkey потоку.
Эх… На пару деньков раньше бы…
При использовании RegisterHotKey и GlobalAddAtom начинаются проблемы как только приложение начинает жить только в виде маленькой иконки глубоко в трее. В таком случае спасают только хуки.

[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);

// запуск отлова
private static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (var curProcess = Process.GetCurrentProcess())
{
using (var curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
}
}
}

// отлов и, при необходимости, обработка хоткея
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
var vkCode = (Keys)Marshal.ReadInt32(lParam);
switch (vkCode)
{
case Keys.MediaNextTrack:
{
break;
}
}
}

return CallNextHookEx(hookId, nCode, wParam, lParam);
}
А какие именно проблемы? К сожалению, я сейчас на работе и не могу проверить поведение в этой ситуации.
Никогда не вызывается WndProc.
а, точно) Вечером дополню топик. Большое спасибо
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории