【问题标题】:How can I check and toggle Num-Lock programmatically in C#?如何在 C# 中以编程方式检查和切换 Num-Lock?
【发布时间】:2009-08-28 15:20:44
【问题描述】:

我想以编程方式检查 num-lock 的值,并能够切换。在 C# 中最简单的方法是什么?

原因是我想在程序启动时验证 num-lock 是否“ON”。

谢谢

【问题讨论】:

    标签: c# num-lock


    【解决方案1】:

    查看How to programmatically turn on the Numlock Key

    using System;
    using System.Runtime.InteropServices;
    
    class SetNumlockKeyOn
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct INPUT
        {
            internal int type;
            internal short wVk;
            internal short wScan;
            internal int dwFlags;
            internal int time;
            internal IntPtr dwExtraInfo;
            int dummy1;
            int dummy2;
            internal int type1;
            internal short wVk1;
            internal short wScan1;
            internal int dwFlags1;
            internal int time1;
            internal IntPtr dwExtraInfo1;
            int dummy3;
            int dummy4;
    }
    [DllImport(“user32.dll”)]
    static extern int SendInput(uint nInputs, IntPtr pInputs, int cbSize);
    
    public static void SetNumlockOn()
    {
        const int mouseInpSize = 28;//Hardcoded size of the MOUSEINPUT tag !!!
        INPUT input = new INPUT();
        input.type = 0x01; //INPUT_KEYBOARD
        input.wVk = 0x90; //VK_NUMLOCK
        input.wScan = 0;
        input.dwFlags = 0; //key-down
        input.time = 0;
        input.dwExtraInfo = IntPtr.Zero;
    
        input.type1 = 0x01;
        input.wVk1 = 0x90;
        input.wScan1 = 0;
        input.dwFlags1 = 2; //key-up
        input.time1 = 0;
        input.dwExtraInfo1 = IntPtr.Zero;
    
        IntPtr pI = Marshal.AllocHGlobal(mouseInpSize * 2);
        Marshal.StructureToPtr(input, pI, false);
        int result = SendInput(2, pI, mouseInpSize); //Hardcoded size of the MOUSEINPUT tag !!!
    
        //if (result == 0 || Marshal.GetLastWin32Error() != 0)
        // Console.WriteLine(Marshal.GetLastWin32Error());
        Marshal.FreeHGlobal(pI);
    }
    

    【讨论】:

    • 你的链接失效了。
    • 找到内容,已复制...希望对您有所帮助;)
    • 我有一个 Acer Aspire 15,它坚持在每次进入睡眠状态(或醒来 - 不确定是哪个)时关闭数字锁定。我尝试了 InitialKeyboardIndicators 注册表技巧,但这并没有解决它 - 每次唤醒计算机并登录时,数字键盘就像箭头键一样。所以我将上面的代码构建成一个小 exe,并使用 Windows 的任务计划程序运行每当我解锁我的笔记本电脑时。问题解决了。非常感谢!
    • 我认为您需要检查 BIOS 的设置,但不客气)
    • 这个答案很好用。但是有一个问题:你怎么知道输入大小是多少?不同的电脑有区别吗? SendInput 的文档只是说如果大小错误,它将失败。
    【解决方案2】:

    您可以通过 P/Invoke 使用 GetKeyboardState 和 keybd_event 来执行此操作。

    keybd_event 的 MSDN 页面准确显示了如何切换数字锁定以及获取它的状态(在 C++ 中)。

    keybd_eventGetKeyboardState 在 pinvoke.net 上提供 P/Invoke 签名。

    【讨论】:

      【解决方案3】:

      除了阿森给出的答案:

      在 64 位构建中存在堆损坏问题。使用此代码的程序可能随时崩溃。要查看这一点,请启用调试选项“启用 Windows 调试堆分配器”。调试器在调用 FreeHGlobal 时停止。

      它有助于计算 INPUT 结构的大小,如下所示。

      int mouseInpSize = Marshal.SizeOf(input);
      IntPtr pI = Marshal.AllocHGlobal(mouseInpSize);
      Marshal.StructureToPtr(input, pI, false);
      int result = SendInput(2, pI, mouseInpSize);
      Marshal.FreeHGlobal(pI);
      

      【讨论】:

        猜你喜欢
        • 2016-12-26
        • 2016-12-18
        • 2012-07-25
        • 2012-02-22
        • 2013-06-05
        • 2011-07-13
        • 2012-06-20
        • 2019-07-21
        相关资源
        最近更新 更多