none
C#如何判斷是由哪個鍵盤輸入 RRS feed

  • 問題

  • 同一台電腦安裝2組usb鍵盤,但因為鍵盤放置位置不同,

    輸入在同一個textbox 裡,請問我要如何判斷是由哪個鍵盤輸入的?

    PS:程式設計成會一直 focus 在 textbox,不可變更,也就是說只能由2個鍵盤判斷位置

    ,輸入的值會是一樣的,但因為鍵盤位置不同,做的事會不一樣

    請大大們指導一下 visual 2010 版


    • 已編輯 筆筆 2017年6月13日 下午 02:33
    2017年6月13日 下午 02:32

解答

所有回覆


  • 不知道可否幫上忙

    抓到 KeyBoard 分別的  hid 值(這個我不會形容)

    可能是長這樣

    \\?\ACPI#ATK3001#4&2537823&0#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}

    之後根據 hid 值來區分作業邏輯

                        case Win32.WM_KEYDOWN:
                        string PVID = e.KeyPressEvent.DeviceName.ToString();
                        break;


    2017年6月15日 上午 04:22
  • 使用範例有成功抓到鍵盤了,但是變成無法輸入文字了

    小弟功力太淺,看不太懂他的CODE

    2017年6月15日 上午 06:04
  • 謝謝,但我現在變成無法輸入文字了‧‧‧
    2017年6月15日 上午 06:05
  • textbox是winform、wpf还是什么?需要在哪判断键盘,是某个事件中么?能不能把现有的代码贴出来,以便更针对性的讨论。

    是 winfrom 的textbox, 在textbox 的 keyUp 事件中,判斷是enter 就會呼叫其他的

    事件,也就是說,在按enter 之前就要完成判斷鍵盤了,

    請再協助一下,謝謝~


    • 已編輯 筆筆 2017年6月15日 下午 12:57
    2017年6月15日 下午 12:57
  • ?????

    • 已標示為解答 筆筆 2017年6月15日 下午 10:54
    • 已編輯 [-] 2018年1月11日 上午 11:43
    2017年6月15日 下午 07:31
  • 最上面tihs提供的链接里的方案在WinForm中可行。只不过那个太复杂了,我简化了一下。

    using System;
    using System.Diagnostics;
    using System.Drawing;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    namespace WindowsFormsApp1
    {
        public class myTextBox : TextBox
        {
            public myTextBox()
            {
                var rid = new RAWINPUTDEVICE[1];
                rid[0].usUsagePage = 0x01;
                rid[0].usUsage = 0x06;
                rid[0].dwFlags = 0x00002000u;
                rid[0].hwndTarget = Handle;
                RegisterRawInputDevices(rid, 1u, (uint)Marshal.SizeOf(rid[0]));
            }
            public int KeyboardID { get; private set; }
            private struct RAWINPUTDEVICE
            {
                internal ushort usUsagePage;
                internal ushort usUsage;
                internal uint dwFlags;
                internal IntPtr hwndTarget;
            }
            private struct RAWINPUTHEADER
            {
                uint dwType;
                uint dwSize;
                internal IntPtr hDevice;
                UIntPtr wParam;
            }
            private struct RAWKEYBOARD
            {
                ushort MakeCode;
                ushort Flags;
                ushort Reserved;
                ushort VKey;
                uint Message;
                uint ExtraInformation;
            }
            private struct RAWINPUT
            {
                internal RAWINPUTHEADER header;
                RAWKEYBOARD data;
            }
            [DllImport("User32.dll")]
            private static extern bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevice, uint numberDevices, uint size);
            [DllImport("User32.dll")]
            private static extern int GetRawInputData(IntPtr hRawInput, uint command, [Out] out RAWINPUT buffer, [In, Out] ref int size, int cbSizeHeader);
            [DllImport("User32.dll")]
            private static extern int GetRawInputData(IntPtr hRawInput, uint command, [Out] IntPtr pData, [In, Out] ref int size, int sizeHeader);
            protected override void WndProc(ref Message m)
            {
                if (m.Msg == 0x00FF)
                {
                    var dwSize = 0;
                    GetRawInputData(m.LParam, 0x10000003u, IntPtr.Zero, ref dwSize, Marshal.SizeOf(typeof(RAWINPUTHEADER)));
                    RAWINPUT input;
                    GetRawInputData(m.LParam, 0x10000003u, out input, ref dwSize, Marshal.SizeOf(typeof(RAWINPUTHEADER)));
                    KeyboardID = input.header.hDevice.ToInt32();
                }
                base.WndProc(ref m);
            }
        }
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                myTextBox1 = new myTextBox();
                myTextBox1.Location = new Point(10, 10);
                myTextBox1.Size = new Size(ClientSize.Width - 20, 21);
                myTextBox1.KeyUp += new KeyEventHandler(myTextBox1_KeyUp);
                Controls.Add(myTextBox1);
            }
            private myTextBox myTextBox1;
            private void myTextBox1_KeyUp(object sender, KeyEventArgs e)
            {
                Debug.WriteLine(myTextBox1.KeyboardID.ToString());
            }
        }
    }

    您的代碼簡化了很多很多,淺顯易懂~完全符合我的需求,謝謝您~~
    2017年6月15日 下午 10:54
  • 您好,結果程式都寫好了,在開發(win7)電腦上測試OK,實際安裝

    在xp電腦上卻不行....真是昏倒

    2017年6月16日 下午 01:02
  • 是怎么个不行呢?上面我的代码只是示例,比如RegisterRawInputDevices这些都是有返回值的,你要判断一下,然后收集错误信息,看一看到底是怎么个不行。

    所謂不行,就是抓取不到返回值, 都抓到0, 但是 win7 系統都沒有問題

    抓到的值大概是 -18XXXX , 因家裡沒有 xp 電腦可以測試,

    只能星期1再到公司測試了~

    2017年6月16日 下午 04:06
  • 您好,結果程式都寫好了,在開發(win7)電腦上測試OK,實際安裝

    在xp電腦上卻不行....真是昏倒

    在 win xp 裡

      protected override void WndProc(ref Message m)
            {
                if (m.Msg == 0x00FF)  這一行進不去
               

    有觀察 m.Msg 的值, 有 0x0101 或 0x0100 就是沒有 0x00ff

    所以無法獲得 keyboardID

    2017年6月19日 下午 10:58

  •  終於搞定了!!

    一開始先確認 RegisterRawInputDevices ,回傳值是 false

    後來去查看了很複雜的那個程式碼,發現 是

     rid[0].dwFlags = 0x00002000u; 這一行的問題

    我改成 0x00000200 就可以運作了

    現在程式在 xp執行上都沒有問題,真的非常感謝您的幫助!
    2017年6月21日 下午 01:50