TatsuSheva Ответов: 1

Как отключить определенный ключ


Я делаю приложение, которое даст некоторые разрешения пользователям.
Я использовал то, что было сказано в этой статье здесь[^]
Спасибо.
Вот что я сделал:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Security.Permissions;

using System.Windows.Forms;
using Microsoft.Win32;
using System.Diagnostics;
namespace UserControl
{
    class Control
    {
        [StructLayout(LayoutKind.Sequential)]
        private struct KBDLLHOOKSTRUCT
        {
            public Keys key;
            public int scanCode;
            public int flags;
            public int time;
            public IntPtr extra;
        }

        //System level functions to be used for hook and unhook keyboard input
        private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam);
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook,
            HookHandlerDelegate lpfn, 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 hhk, int nCode,
            IntPtr wParam, ref KBDLLHOOKSTRUCT lParam);
        [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);


        //Declaring Global objects
        private static IntPtr ptrHook;
        //private static LowLevelKeyboardProc objKeyboardProcess;
        private static HookHandlerDelegate proc;
        private const int WH_KEYBOARD_LL = 13;

        private const int VK_CONTROL = 0x11;
        private const int WM_KEYUP = 0x0101;
        private const int WM_SYSKEYUP = 0x0105;
        [DllImport("user32.dll")]
        private static extern int FindWindow(string className, string windowText);

        [DllImport("user32.dll")]
        private static extern int ShowWindow(int hwnd, int command);

        [DllImport("user32.dll")]
        public static extern int FindWindowEx(int parentHandle, int childAfter, string className, int windowTitle);

        [DllImport("user32.dll")]
        private static extern int GetDesktopWindow();

        private const int SW_HIDE = 0;
        private const int SW_SHOW = 1;


        


        protected static int Handle
        {
            get
            {
                return FindWindow("Shell_TrayWnd", "");
            }
        }

        protected static int HandleOfStartButton
        {
            get
            {
                int handleOfDesktop = GetDesktopWindow();
                int handleOfStartButton = FindWindowEx(handleOfDesktop, 0, "button", 0);
                return handleOfStartButton;
            }
        }

        public Control()
        {
            proc = new HookHandlerDelegate(HookCallback);
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                ptrHook = SetWindowsHookEx(WH_KEYBOARD_LL, proc,
                   GetModuleHandle(curModule.ModuleName), 0);
            }
        }
        
        private static IntPtr HookCallback(int nCode, IntPtr wParam, ref KBDLLHOOKSTRUCT lParam)
        {
            //Filter wParam for KeyUp events only - otherwise this code
            //will execute twice for each keystroke (ie: on KeyDown and KeyUp)
            //WM_SYSKEYUP is necessary to trap Alt-key combinations
            if (nCode >= 0)
            {
                if (wParam == (IntPtr)WM_KEYUP || wParam == (IntPtr)WM_SYSKEYUP)
                {
                    //Raise the event

                } return (IntPtr)1;
                //Return a dummy value to trap the keystroke
               
            }
            //The event wasn't handled, pass it to next application
            return CallNextHookEx(ptrHook, nCode, wParam, ref lParam);
        }
        
        public static void Dispose()
        {
            UnhookWindowsHookEx(ptrHook);
        }
        public static void Hide()
        {

            proc = new HookHandlerDelegate(HookCallback);
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                ptrHook = SetWindowsHookEx(WH_KEYBOARD_LL, proc,
                   GetModuleHandle(curModule.ModuleName), 0);
            }

           
        }


    }

}


Что я уже пробовал:

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

Richard MacCutchan

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

ZurdoDev

Как сказал Ричард, сначала вам нужно понять, как работает этот код, чтобы потом вы могли легко изменить его.

TatsuSheva

Я нашел решение, спасибо.

ZurdoDev

1. ответьте на комментарий так, чтобы пользователь был уведомлен.
2. пожалуйста, опубликуйте что-нибудь в качестве решения, чтобы этот вопрос больше не оставался без ответа.

1 Ответов

Рейтинг:
6

TatsuSheva

Вот что я сделал.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Security.Permissions;

using System.Windows.Forms;
using Microsoft.Win32;
using System.Diagnostics;
namespace UserControl
{
    class Control
    {
        [StructLayout(LayoutKind.Sequential)]
        private struct KBDLLHOOKSTRUCT
        {
            public Keys key;
            public int scanCode;
            public int flags;
            public int time;
            public IntPtr extra;
        }

        //System level functions to be used for hook and unhook keyboard input
        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);


        //Declaring Global objects
        private static IntPtr ptrHook;
        private static LowLevelKeyboardProc objKeyboardProcess;

        private const int WH_KEYBOARD_LL = 13;
        private const int VK_CONTROL = 0x11;
        
        public Control()
        {
            ProcessModule objCurrentModule = Process.GetCurrentProcess().MainModule;
            objKeyboardProcess = new LowLevelKeyboardProc(captureKey);
            ptrHook = SetWindowsHookEx(13, objKeyboardProcess, GetModuleHandle(objCurrentModule.ModuleName), 0);
        }
        public static IntPtr captureKey(int nCode, IntPtr wp, IntPtr lp)
        {
            if (nCode >= 0)
            {
                KBDLLHOOKSTRUCT objKeyInfo = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lp, typeof(KBDLLHOOKSTRUCT));

                if (objKeyInfo.key == Keys.RControlKey || objKeyInfo.key == Keys.LControlKey || objKeyInfo.key == Keys.F4 || objKeyInfo.key == Keys.Alt || objKeyInfo.key == Keys.Tab || objKeyInfo.key == Keys.Delete) // Disabling Windows keys
                {
                    return (IntPtr)1;
                }
            }
            return CallNextHookEx(ptrHook, nCode, wp, lp);
        }
        
        public static void Dispose()
        {
            UnhookWindowsHookEx(ptrHook);
        }
        public static void Hide()
        {
           
            ProcessModule objCurrentModule = Process.GetCurrentProcess().MainModule;
            objKeyboardProcess = new LowLevelKeyboardProc(captureKey);
            ptrHook = SetWindowsHookEx(13, objKeyboardProcess, GetModuleHandle(objCurrentModule.ModuleName), 0);

           
        }


    }

}