рд╢рд╛рдпрдж рдЖрдк рдПрдХ рдмрд╛рд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЪрд╛рд╣рддреЗ рдереЗ рдХрд┐ рдЖрдкрдХрд╛ рдЖрд╡реЗрджрди рд╡реИрд╢реНрд╡рд┐рдХ рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреБрдЫ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛред рдФрд░ рд╢рд╛рдпрдж рдЖрдкрдХреЛ WPF рддрдХрдиреАрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдкрд╕рдВрдж рд╣реИред рдлрд┐рд░ рдпрд╣ рд╡рд┐рд╖рдп рдЖрдкрдХреЗ рд▓рд┐рдП рд╣реИред
рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ рд╕рдордЭрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рд╡рд┐рдВрдбреЛрдЬ рдореЗрдВ рд╣реЙрдЯрдХреА рддрдВрддреНрд░ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХреЛрдИ WPF рд╡рд┐рдзрд┐рдпрд╛рдВ рдирд╣реАрдВ рд╣реИрдВ рдЬреЛ рд╕реАрдзреЗ рдЙрдирдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреА рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рд╣рдореЗрдВ WinAPI рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рд╣рдореЗрдВ рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдХрд╛рд░реНрдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред
рд╣реЙрдЯрдХреА рдкрдВрдЬреАрдХрд░рдг:
BOOL WINAPI RegisterHotKey( __in_opt HWND hWnd, __in int id, __in UINT fsModifiers, __in UINT vk );
рд╣реЙрдЯрдХреА рд╣рдЯрд╛рдирд╛:
BOOL WINAPI UnregisterHotKey( __in_opt HWND hWnd, __in int id );
рд╣реЙрдЯрдХреА рдХреА рдкрд╣рдЪрд╛рди рдФрд░ рдЙрд╕рдХреЗ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ (рдкрд░рдорд╛рдгреБ) рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрджреНрд╡рд┐рддреАрдп рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХрд╛ рдкрдВрдЬреАрдХрд░рдг:
ATOM GlobalAddAtom( LPCTSTR lpString )
рдФрд░, рддрджрдиреБрд╕рд╛рд░, рдкрд░рдорд╛рдгреБ рдХреЛ рд╣рдЯрд╛рдирд╛:
ATOM WINAPI GlobalDeleteAtom( __in ATOM nAtom )
рджрд░рдЕрд╕рд▓, рддрдВрддреНрд░ рд╕реНрд╡рдпрдВ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ - рд╣реЙрдЯрдХреА рдкрд╣рдЪрд╛рди рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░реЗрдВ рдФрд░ рдкрд░рд┐рдгрд╛рдореА рдкрд░рдорд╛рдгреБ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣реЙрдЯрдХреА рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░реЗрдВред рдЬрдм рдЖрдк рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рддреЗ рд╣реИрдВ, рддреЛ рд╣реЙрдЯрдХреА рдФрд░ рдкрд░рдорд╛рдгреБ рдХреЗ рдкрдВрдЬреАрдХрд░рдг рдХреЛ рд╣рдЯрд╛ рджреЗрдВ - рдмрд╕ред рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИред рдЕрдм рд╣рдо рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВред
C # рдореЗрдВ, рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕рдВрдмрдВрдзрд┐рдд dll рд╕реЗ рдирд┐рд░реНрдпрд╛рдд рдХрд░реЗрдВ:
[DllImport("User32.dll")] public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk); [DllImport("User32.dll")] public static extern bool UnregisterHotKey(IntPtr hWnd, int id); [DllImport("kernel32.dll")] public static extern Int16 GlobalAddAtom(string name); [DllImport("kernel32.dll")] public static extern Int16 GlobalDeleteAtom(Int16 nAtom);
рдПрдХ рдЫреЛрдЯреА рд╕реА рд╕рдорд╕реНрдпрд╛ рдпрд╣рд╛рдБ рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИ - WndProc рдХреЙрд▓ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ WPF рдореЗрдВ, рд╡рд┐рдВрдбреЛрдЬ рдлреЙрд░реНрдо рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЖрдк рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╡рд┐рдВрдбреЛ рдореЗрдВ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЕрдзрд┐рднрд╛рд░ рдирд╣реАрдВ рдбрд╛рд▓ рд╕рдХрддреЗред рд▓реЗрдХрд┐рди рдЖрдк рдирд┐рдореНрди рдкреНрд░рдХрд╛рд░ рд╕реЗ WndProc рдХреЙрд▓ рдХреЛ рд╕рдВрднрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ:
public HotkeysRegistrator(Window window) { _windowHandle = new WindowInteropHelper(window).Handle; HwndSource source = HwndSource.FromHwnd(_windowHandle); source.AddHook(WndProc); } private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled) { if (msg == 0x0312) {
рд╣рдо рд╣реЙрдЯрдХреАрдЬрд╝ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреВрд░реА рддрд░рд╣ рд╕реЗ рддреИрдпрд╛рд░ рд╣реИрдВред рд╣рдорд╛рд░реА рдХрдХреНрд╖рд╛ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрди рд╡рд┐рдзрд┐:
private Dictionary<Int16, Action> _globalActions = new Dictionary<short, Action>(); public bool RegisterGlobalHotkey(Action action, Keys commonKey, params ModifierKeys[] keys) { uint mod = keys.Cast<uint>().Aggregate((current, modKey) => current | modKey); short atom = GlobalAddAtom("OurAmazingApp" + (_globalActions.Count + 1)); bool status = RegisterHotKey(_windowHandle, atom, mod, (uint)commonKey); if (status) { _globalActions.Add(atom, action); } return status; }
рдФрд░ WndProc рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди:
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled) { if (msg == 0x0312) { short atom = Int16.Parse(wparam.ToString()); if (_globalActions.ContainsKey(atom)) { _globalActions[atom](); } } return IntPtr.Zero; }
рдЕрдм, рдХрд▓рд╛рдИ рдХреА рдПрдХ рдЪрдВрдЪрд▓рддрд╛ рдХреЗ рд╕рд╛рде, рд╣рдо рдЕрдВрдд рдореЗрдВ рдХреБрдЫ рдкрдВрдЬреАрдХреГрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
RegisterGlobalHotkey(() => MessageBox.Show("!"), Keys.G, ModifierKeys.Alt, ModifierKeys.Control)
рдЖрдирдиреНрджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд▓реНрджреА рдордд рдХрд░реЛ, рдЖрд╡реЗрджрди рдХреЗ рдЬреАрд╡рди рдХреЗ рдЕрдВрдд рдореЗрдВ рд╣рдорд╛рд░реЗ рд╣реЙрдЯрдХреАрдЬ рдХреЛ рдЕрдкрдВрдЬреАрдХреГрдд рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реЛрдЧрд╛ рддрд╛рдХрд┐ рд╡реЗ рдЕрдиреНрдп рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд╕рд╛рде рд╣рд╕реНрддрдХреНрд╖реЗрдк рди рдХрд░реЗрдВред рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рдХрд╣рд╛ рдЧрдпрд╛ рд╣реИ, рдпрд╣ рдкреНрд░рдХреНрд░рд┐рдпрд╛ UnregisterHotKey рдФрд░ GlobalDeleteAtom рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рдпрд╣ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
public void UnregisterHotkeys() { foreach(var atom in _globalActions.Keys) { UnregisterHotKey(_windowHandle, atom); GlobalDeleteAtom(atom); } }
рд╕рдм рдХреБрдЫ, рдЖрдк рдЖрдирдиреНрджрд┐рдд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ - рд╕рдм рдХреБрдЫ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдФрд░ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИред
UPD: OS рд╕реНрддрд░ рдкрд░ "рд╣реЙрдЯрдХреАрдЬрд╝" рд╡реИрд╢реНрд╡рд┐рдХ рдХрд╛ рдЬрд┐рдХреНрд░ рдХрд░рддреЗ рд╣реБрдП, рдФрд░ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╕реНрддрд░ рдкрд░ рдирд╣реАрдВUPD2:рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЗ рд▓рд┐рдП
рдзрдиреНрдпрд╡рд╛рдж Karabasoff :
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);