.NET 3.x Исключение при блоке клавиши Win - C#
Формулировка задачи:
Вообщем понадобилось мне отключить клавишу Win (в разумных целях), так вот при нажатие первый раз блочит, при повторном, выдает исключение, и всё накрывается разом)
Сам класс:
Исключение:
Есть ли у кого нибудь рабочий пример: или же как бороться..?
Листинг программы
- using System;
- using System.Runtime.InteropServices;
- using System.Windows.Forms;
- using System.Diagnostics;
- internal class WinBlock
- {
- [StructLayout(LayoutKind.Sequential)]
- private struct KBDLLHOOKSTRUCT
- {
- public Keys key;
- public int scanCode;
- public int flags;
- public int time;
- public IntPtr extra;
- }
- private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- private static extern IntPtr SetWindowsHookEx(int id, LowLevelKeyboardProc callback, IntPtr hMod, uint dwThreadId);
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- private static extern bool UnhookWindowsHookEx(IntPtr hook);
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- private static extern IntPtr CallNextHookEx(IntPtr hook, int nCode, IntPtr wp, IntPtr lp);
- [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- private static extern IntPtr GetModuleHandle(string name);
- [DllImport("user32.dll", CharSet = CharSet.Auto)]
- private static extern short GetAsyncKeyState(Keys key);
- private IntPtr ptrHook;
- private LowLevelKeyboardProc objKeyboardProcess;
- private IntPtr captureKey(int nCode, IntPtr wp, IntPtr lp)
- {
- if (nCode >= 0)
- {
- KBDLLHOOKSTRUCT objKeyInfo = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lp, typeof(KBDLLHOOKSTRUCT));
- if (objKeyInfo.key == Keys.LWin || objKeyInfo.key == Keys.RWin)
- {
- return (IntPtr)1;
- }
- }
- return CallNextHookEx(ptrHook, nCode, wp, lp);
- }
- private delegate IntPtr LowLevelKeyboardProcDelegate(int nCode, IntPtr wParam, IntPtr lParam);
- public void SetHook()
- {
- ProcessModule objCurrentModule = Process.GetCurrentProcess().MainModule;
- objKeyboardProcess = new LowLevelKeyboardProc(captureKey);
- ptrHook = SetWindowsHookEx(13, objKeyboardProcess, GetModuleHandle(objCurrentModule.ModuleName), 0);
- }
- public void Unhook()
- {
- if (ptrHook != IntPtr.Zero)
- {
- UnhookWindowsHookEx(ptrHook);
- ptrHook = IntPtr.Zero;
- }
- }
- }
Листинг программы
- Обнаружено событие CallbackOnCollectedDelegate
- Message: Был произведен обратный вызов делегата типа "WinBlock+LowLevelKeyboardProc::Invoke",
- полученного сборщиком мусора.
- Это может привести к сбоям приложения, а также к повреждению или утрате данных.
- При передаче делегатов в неуправляемый код управляемое приложение
- должно поддерживать их существование,
- пока не будет гарантировано, что они больше никогда не будут вызваны.
Решение задачи: «.NET 3.x Исключение при блоке клавиши Win»
textual
Листинг программы
- private void button1_Click(object sender, EventArgs e)
- {
- WinBlock.SetHook();
- }
- private void button2_Click(object sender, EventArgs e)
- {
- WinBlock.Unhook();
- }
- internal static class WinBlock
- {
- [StructLayout(LayoutKind.Sequential)]
- private struct KBDLLHOOKSTRUCT
- {
- public Keys key;
- public int scanCode;
- public int flags;
- public int time;
- public IntPtr extra;
- }
- private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- private static extern IntPtr SetWindowsHookEx(int id, LowLevelKeyboardProc callback, IntPtr hMod, uint dwThreadId);
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- private static extern bool UnhookWindowsHookEx(IntPtr hook);
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- private static extern IntPtr CallNextHookEx(IntPtr hook, int nCode, IntPtr wp, IntPtr lp);
- [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- private static extern IntPtr GetModuleHandle(string name);
- [DllImport("user32.dll", CharSet = CharSet.Auto)]
- private static extern short GetAsyncKeyState(Keys key);
- private static IntPtr ptrHook;
- private static LowLevelKeyboardProc objKeyboardProcess;
- //тут зафиксируем на всякий случай
- private static GCHandle gcObjKeyboardProcess = GCHandle.Alloc(objKeyboardProcess);
- private static IntPtr captureKey(int nCode, IntPtr wp, IntPtr lp)
- {
- if (nCode >= 0)
- {
- KBDLLHOOKSTRUCT objKeyInfo = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lp, typeof(KBDLLHOOKSTRUCT));
- if (objKeyInfo.key == Keys.LWin || objKeyInfo.key == Keys.RWin)
- {
- return (IntPtr)1;
- }
- }
- return CallNextHookEx(ptrHook, nCode, wp, lp);
- }
- //Зачем дважды объявил?
- //private delegate IntPtr LowLevelKeyboardProcDelegate(int nCode, IntPtr wParam, IntPtr lParam);
- public static void SetHook()
- {
- ProcessModule objCurrentModule = Process.GetCurrentProcess().MainModule;
- objKeyboardProcess = new LowLevelKeyboardProc(captureKey);
- ptrHook = SetWindowsHookEx(13, objKeyboardProcess, GetModuleHandle(objCurrentModule.ModuleName), 0);
- }
- public static void Unhook()
- {
- if (ptrHook != IntPtr.Zero)
- {
- UnhookWindowsHookEx(ptrHook);
- ptrHook = IntPtr.Zero;
- }
- }
- }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д