1

我已经搜索了一段时间,主要是 C++ 或其他语言的结果,而不是 C#。我见过的东西:

   keybd_event() // A c++ method that theoretically can be included with a DLL import, but hasn't worked in testing
   System.Windows.Forms.SendKeys.Send("{NUMLOCK}"}; // Forms namespace doesn't exist in Windows

目前,我有大约每秒执行一次的代码来观察 numlock 的状态并相应地更新我的表单中的图形。如果设置了布尔切换,我还希望它强制打开 NumLock:


        internal partial class Interop
        {
            public static int VK_NUMLOCK = 0x90;
            public static int VK_SCROLL = 0x91;
            public static int VK_CAPITAL = 0x14;
            public static int KEYEVENTF_EXTENDEDKEY = 0x0001; // If specified, the scan code was preceded by a prefix byte having the value 0xE0 (224).
            public static int KEYEVENTF_KEYUP = 0x0002; // If specified, the key is being released. If not specified, the key is being depressed.

            [DllImport("User32.dll", SetLastError = true)]
            public static extern void keybd_event(
                byte bVk,
                byte bScan,
                int dwFlags,
                IntPtr dwExtraInfo);

            [DllImport("User32.dll", SetLastError = true)]
            public static extern short GetKeyState(int nVirtKey);

            [DllImport("User32.dll", SetLastError = true)]
            public static extern short GetAsyncKeyState(int vKey);
        }

    private void watcher(object source, ElapsedEventArgs e) 
        {
            bool NumLock = (((ushort)GetKeyState(0x90)) & 0xffff) != 0;

            if (!NumLock && fixers.watchNumL)
            {
                // Force NumLock back on
                // Simulate a key press
                Interop.keybd_event((byte)0x90,0x45,Interop.KEYEVENTF_EXTENDEDKEY | 0,IntPtr.Zero);

                // Simulate a key release
                Interop.keybd_event((byte)0x90,0x45,Interop.KEYEVENTF_EXTENDEDKEY | Interop.KEYEVENTF_KEYUP,    IntPtr.Zero);
                NumLock = (((ushort)GetKeyState(0x90)) & 0xffff) != 0;
            }

            if (NumLock)
            {
                this.Dispatcher.Invoke(() =>
                {
                    fixerBoxes["NumL"].FixerImg.Source = new BitmapImage(new Uri(@"/graphics/num_lock_on.png", UriKind.Relative));
                    StatusBox.Text = "Num Lock ON";
                });
            }
            else {
                this.Dispatcher.Invoke(() =>
                {
                    fixerBoxes["NumL"].FixerImg.Source = new BitmapImage(new Uri(@"/graphics/num_lock_off.png", UriKind.Relative));
                    StatusBox.Text = "Num Lock OFF";
                });
            }

        }


        public MainWindow()
        {
            // Start the watcher
            System.Timers.Timer myTimer = new System.Timers.Timer();
            // Tell the timer what to do when it elapses
            myTimer.Elapsed += new ElapsedEventHandler(watcher);
            // Set it to go off every second
            myTimer.Interval = 1000;
            // And start it        
            myTimer.Enabled = true;

        }
4

1 回答 1

1

是一个可以为您执行此操作的类(带有库)。该库做得更多,因此仅为此使用可能有点矫枉过正。该方法keybd_event使用 pinvoke 函数:

// Simulate a key press
Interop.keybd_event((byte)virtualKey,
    0x45,
    Interop.KEYEVENTF_EXTENDEDKEY | 0,
    IntPtr.Zero);

// Simulate a key release
    Interop.keybd_event((byte)virtualKey,
    0x45,
    Interop.KEYEVENTF_EXTENDEDKEY | Interop.KEYEVENTF_KEYUP,
    IntPtr.Zero);

按下和释放按钮会改变 LED 的状态。virtualKey是 VK_ 常数之一。

以下是声明:

internal partial class Interop
{
    public static int VK_NUMLOCK = 0x90;
    public static int VK_SCROLL = 0x91;
    public static int VK_CAPITAL = 0x14;
    public static int KEYEVENTF_EXTENDEDKEY = 0x0001; // If specified, the scan code was preceded by a prefix byte having the value 0xE0 (224).
    public static int KEYEVENTF_KEYUP = 0x0002; // If specified, the key is being released. If not specified, the key is being depressed.

    [DllImport("User32.dll", SetLastError = true)]
    public static extern void keybd_event(
        byte bVk,
        byte bScan,
        int dwFlags,
        IntPtr dwExtraInfo);

    [DllImport("User32.dll", SetLastError = true)]
    public static extern short GetKeyState(int nVirtKey);

    [DllImport("User32.dll", SetLastError = true)]
    public static extern short GetAsyncKeyState(int vKey);
}

于 2022-01-13T16:13:32.347 回答