подключить клавиатуру: как узнать название программы, где нажата клавиша? - PullRequest
0 голосов
/ 22 февраля 2012

Я сделал простую хук-клавиатуру на C #, поэтому у меня есть следующий код:

        private static IntPtr hKeyboardHook = IntPtr.Zero;
        private const int WH_KEYBOARD_LL = 13;
        private const int WM_KEYDOWN = 0x100;

        private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        private static extern int UnhookWindowsHookEx(IntPtr idHook);
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
        [DllImport("user32")]
        private static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState, byte[] lpwTransKey, int fuState);
        [DllImport("user32")]
        private static extern int GetKeyboardState(byte[] pbKeyState);
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern short GetKeyState(int vKey);
        private delegate int HookProc(int nCode, int wParam, IntPtr lParam);
        [DllImport("kernel32.dll")]
        public static extern IntPtr GetModuleHandle(string lpModuleName);
        private static LowLevelKeyboardProc _proc = HookCallback;

 public void initialization()
        {
            using (Process curProcess = Process.GetCurrentProcess())
                using (ProcessModule curModule = curProcess.MainModule)
                {
                    hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, _proc, GetModuleHandle(curModule.ModuleName), 0);
                }  
        }

    private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
        {
            int vkCode = Marshal.ReadInt32(lParam);
            if (vkCode >= 32 && vkCode < 160)
                Console.Write((Keys)vkCode);
            if (vkCode == 13)
                Console.WriteLine("\n");
        }
        return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
    }

Работает нормально, без проблем !!моя программа сжимает все клавиши нажатыми в другой программе и пишет это на консоли.Но я хочу иметь название программы, в которой нажата клавиша, и я не знаю, как я могу это сделать.

Кто-нибудь может мне помочь?

1 Ответ

2 голосов
/ 22 февраля 2012

Вы используете низкоуровневый крючок (WH_KEYBOARD_LL). Низкоуровневые перехватчики отправляются прежде, чем оконный менеджер решит, какая программа получит сообщение. Следовательно, нет «названия программы, в которой нажата клавиша», потому что диспетчер окон еще не решил, в какую программу будет доставлено нажатие клавиши. (Вы можете попытаться угадать, позвонив GetForegroundWindow.)

(Просто любопытно: какую конечную проблему вы пытаетесь решить с помощью клавиатуры? Возможно, есть лучший способ. Надеюсь, вы не пишете кейлоггер.)

...