从禁用Windows密钥类

时间:2017-05-22 02:10:44

标签: c# visual-studio

非常感谢您花时间阅读。我的问题是我已经创建了一个类文件,在研究中找到了一些帮助,并找到了禁用我的Windows密钥的代码,如果为真,我已将此代码实现为复选框值。选中复选框后,它会运行我创建的类文件,但是当我取消选中该复选框后,我需要禁用此代码以再次启用Windows密钥。我承认这段代码在我的脑海中稍微高了一点,我多次经历过这段代码,并且仍在试图弄清楚它的结构和工作方式。

class EnableDisableKeys
{
    // Structure contain information about low-level keyboard input event
    [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 IntPtr ptrHook;
    private LowLevelKeyboardProc objKeyboardProcess;

    public void KeyHook()
    {
        ProcessModule objCurrentModule = Process.GetCurrentProcess().MainModule;
        objKeyboardProcess = new LowLevelKeyboardProc(captureKey);
        ptrHook = SetWindowsHookEx(13, objKeyboardProcess, GetModuleHandle(objCurrentModule.ModuleName), 0);
    }

    private IntPtr captureKey(int nCode, IntPtr wp, IntPtr lp)
    {
        if (nCode >= 0)
        {
            KBDLLHOOKSTRUCT objKeyInfo = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lp, typeof(KBDLLHOOKSTRUCT));

            if (objKeyInfo.key == Keys.RWin || objKeyInfo.key == Keys.LWin) // Disabling Windows keys
            {
                return (IntPtr)1;
            }
        }
        return CallNextHookEx(ptrHook, nCode, wp, lp);
    }


}

在我的Winform上。

public partial class ParentalSettingsForm : Form
{
    EnableDisableKeys ed = new EnableDisableKeys();
    public ParentalSettingsForm()
    {

        InitializeComponent();
    }

    private void ParentalSettingsForm_Load(object sender, EventArgs e)
    {

    }

    private void checkBoxDisableWindowsKey_CheckedChanged(object sender, EventArgs e)
    {
        if(checkBoxDisableWindowsKey.Checked == true)
        {
            ed.KeyHook();
        }

    }
}

现在我知道它可能是一个小设置我需要改变某处禁用但似乎无法找到它。在我得到答案之前,我将继续研究这个解决方案,但是我已经提到过与禁用或重新启用密钥有关的任何事情对我来说都是新的。谢谢。

1 个答案:

答案 0 :(得分:1)

在类中设置一个布尔标志,告诉它是否要取消win键。在captureKey()方法中检查它。在这里,我将默认值设置为禁止键:

    public bool SuppressWinKey = true;

    private IntPtr captureKey(int nCode, IntPtr wp, IntPtr lp)
    {
        if (nCode >= 0)
        {
            KBDLLHOOKSTRUCT objKeyInfo = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lp, typeof(KBDLLHOOKSTRUCT));

            if (objKeyInfo.key == Keys.RWin || objKeyInfo.key == Keys.LWin) // Disabling Windows keys
            {
                if (SuppressWinKey)
                {
                    return (IntPtr)1;
                }
            }
        }
        return CallNextHookEx(ptrHook, nCode, wp, lp);
    }

在表单中,在表单加载时设置挂钩(不响应复选框):

EnableDisableKeys ed = new EnableDisableKeys();

private void ParentalSettingsForm_Load(object sender, EventArgs e)
{
    ed.KeyHook();
}

现在,当复选框被更改时切换该标志:

private void checkBoxDisableWindowsKey_CheckedChanged(object sender, EventArgs e)
{
    ed.SuppressWinKey = checkBoxDisableWindowsKey.Checked;
}