MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Баги при работе с клавиатурными хуками"
Answer 1028145
Потому что вы не написали правильный код для блокировки этих сочетаний клавиш. Начать с того, что VK для нажатия клавиши ALT в хуке - на самом деле не
Keys.Alt
, аKeys.LMenu
илиKeys.RMenu
. Но даже если поменять VK на правильный, все равно условиеif (objKeyInfo.key == Keys.Alt || objKeyInfo.key == Keys.Tab)
никак не может соответствовать "блокировать сочетание клавиш Alt+Tab" - вы блокируете вместо этого любые нажатия клавиш Alt и Tab!Правильно это делается так:
using System; using System.Runtime.InteropServices; using System.ComponentModel; using System.Windows.Forms; namespace KeyboardHookSample { class Program { static KeyHooker k; static void Main(string[] args) { k = new KeyHooker(); k.Start(); Console.CancelKeyPress += Console_CancelKeyPress; Console.WriteLine("Hook installed..."); Application.Run(); } private static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e) { k.Stop(); Application.Exit(); } } [StructLayout(LayoutKind.Sequential)] public class KBDLLHOOKSTRUCT { public uint vkCode; public uint scanCode; public uint flags; public uint time; public UIntPtr dwExtraInfo; } sealed class KeyHooker : IDisposable { //объявления типов, констант и функций Windows API delegate IntPtr KeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); const int WH_KEYBOARD_LL = 13; const int HC_ACTION = 0; const int WM_KEYDOWN = 0x0100; const int WM_SYSKEYDOWN = 0x0104; const uint LLKHF_ALTDOWN = 0x20; [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] static extern IntPtr SetWindowsHookEx(int idHook, KeyboardProc lpfn, IntPtr hInstance, int threadId); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool UnhookWindowsHookEx(IntPtr hhk); [DllImport("kernel32.dll")] private static extern IntPtr LoadLibrary(string dllToLoad); IntPtr _hookID = IntPtr.Zero; //начинает отслеживание событий клавиатуры public void Start() { if (disposed) throw new ObjectDisposedException("KeyLogger"); if (_hookID != IntPtr.Zero) return; _hookID = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookCallback, IntPtr.Zero, 0); if (_hookID == IntPtr.Zero) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error, "Failed to install hook! Error: " + error.ToString()); } } //останавливает отслеживание событий клавиатуры public void Stop() { if (disposed) return; if (_hookID == IntPtr.Zero) return; UnhookWindowsHookEx(_hookID); _hookID = IntPtr.Zero; } //вызывается Windows при нажатии клавиши IntPtr KeyboardHookCallback(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode >= 0 && (wParam == (IntPtr)WM_KEYDOWN || wParam == (IntPtr)WM_SYSKEYDOWN)) { KBDLLHOOKSTRUCT khs = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT)); uint vkCode = khs.vkCode; if ((khs.flags & LLKHF_ALTDOWN) != 0 && vkCode == (uint)Keys.Tab) { return (IntPtr)1; //Cancel Alt+Tab } } return CallNextHookEx(_hookID, nCode, wParam, lParam); } bool disposed = false; public void Dispose() { if (disposed) return; Stop(); disposed = true; GC.SuppressFinalize(this); } ~KeyHooker() { Dispose(); } } }
Также следует помнить, что блокировку системных сочетаний клавиш нужно применять с осторожностью. Если полноэкранное приложение блокирует сочетания клавиш Alt+Tab и Ctrl+Alt+Delete, то в случае его зависания система становится полностью неработоспособной - ничего не остается, кроме как перезагружать системник кнопкой Reset.
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.