Страницы

Поиск по вопросам

пятница, 24 января 2020 г.

C# Захват сочетания нажатых клавиш на клавиатуре

#c_sharp #клавиатура #keyboardhook


Хочу сделать простенькое приложение с захватом комбинации клавиш (напр. alt+a), но
дело в том что клавиши хукаются только по отдельности, есть ли какая-то возможность
использовать модификаторы, alt, shift, и т.д.
Вот сам код:

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication4
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        globalKeyboardHook gkh = new globalKeyboardHook();
        private void Form1_Load(object sender, EventArgs e)
        {
            gkh.HookedKeys.Add(Keys.A);
            gkh.HookedKeys.Add(Keys.B);
            gkh.HookedKeys.Add(Keys.LMenu);
            gkh.KeyDown += new KeyEventHandler(gkh_KeyDown);
            gkh.KeyUp += new KeyEventHandler(gkh_KeyUp);
        }
        void gkh_KeyUp(object sender, KeyEventArgs e)
        {
            label1.Text="Up\t" + e.KeyCode.ToString();
            e.Handled = true;
        }

        void gkh_KeyDown(object sender, KeyEventArgs e)
        {
            label1.Text = "Down\t" + e.KeyCode.ToString();
            e.Handled = true;
        }
    }
    class globalKeyboardHook
    {
        #region Constant, Structure and Delegate Definitions
        /// 
        /// defines the callback type for the hook
        /// 
        public delegate int keyboardHookProc(int code, int wParam, ref keyboardHookStruct
lParam);

        public struct keyboardHookStruct
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }

        const int WH_KEYBOARD_LL = 13;
        const int WM_KEYDOWN = 0x100;
        const int WM_KEYUP = 0x101;
        const int WM_SYSKEYDOWN = 0x104;
        const int WM_SYSKEYUP = 0x105;
        #endregion

        #region Instance Variables
        /// 
        /// The collections of keys to watch for
        /// 
        public List HookedKeys = new List();
        /// 
        /// Handle to the hook, need this to unhook and call the next hook
        /// 
        IntPtr hhook = IntPtr.Zero;
        #endregion

        #region Events
        /// 
        /// Occurs when one of the hooked keys is pressed
        /// 
        public event KeyEventHandler KeyDown;
        /// 
        /// Occurs when one of the hooked keys is released
        /// 
        public event KeyEventHandler KeyUp;
        #endregion

        #region Constructors and Destructors
        /// 
        /// Initializes a new instance of the  class
and installs the keyboard hook.
        /// 
        public globalKeyboardHook()
        {
            hook();
        }

        /// 
        /// Releases unmanaged resources and performs other cleanup operations before the
        ///  is reclaimed by garbage collection and
uninstalls the keyboard hook.
        /// 
        ~globalKeyboardHook()
        {
            unhook();
        }
        #endregion

        #region Public Methods
        /// 
        /// Installs the global hook
        /// 
        public void hook()
        {
            IntPtr hInstance = LoadLibrary("User32");
            hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0);
        }

        /// 
        /// Uninstalls the global hook
        /// 
        public void unhook()
        {
            UnhookWindowsHookEx(hhook);
        }

        /// 
        /// The callback for the keyboard hook
        /// 
        /// The hook code, if it isn't >= 0, the function shouldn't
do anyting
        /// The event type
        /// The keyhook event information
        /// 
        public int hookProc(int code, int wParam, ref keyboardHookStruct lParam)
        {
            if (code >= 0)
            {
                Keys key = (Keys)lParam.vkCode;
                //MessageBox.Show(key.ToString());
                if (HookedKeys.Contains(key))
                {
                    KeyEventArgs kea = new KeyEventArgs(key);
                    if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && (KeyDown
!= null))
                    {
                        KeyDown(this, kea);
                    }
                    else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && (KeyUp
!= null))
                    {
                        KeyUp(this, kea);
                    }
                    if (kea.Handled)
                        return 1;
                }
            }
            return CallNextHookEx(hhook, code, wParam, ref lParam);
        }
        #endregion

        #region DLL imports
        /// 
        /// Sets the windows hook, do the desired event, one of hInstance or threadId
must be non-null
        /// 
        /// The id of the event you want to hook
        /// The callback.
        /// The handle you want to attach the event to, can
be null
        /// The thread you want to attach the event to, can
be null
        /// a handle to the desired hook
        [DllImport("user32.dll")]
        static extern IntPtr SetWindowsHookEx(int idHook, keyboardHookProc callback,
IntPtr hInstance, uint threadId);

        /// 
        /// Unhooks the windows hook.
        /// 
        /// The hook handle that was returned from SetWindowsHookEx
        /// True if successful, false otherwise
        [DllImport("user32.dll")]
        static extern bool UnhookWindowsHookEx(IntPtr hInstance);

        /// 
        /// Calls the next hook.
        /// 
        /// The hook id
        /// The hook code
        /// The wparam.
        /// The lparam.
        /// 
        [DllImport("user32.dll")]
        static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref
keyboardHookStruct lParam);

        /// 
        /// Loads the library.
        /// 
        /// Name of the library
        /// A handle to the library
        [DllImport("kernel32.dll")]
        static extern IntPtr LoadLibrary(string lpFileName);
        #endregion
    }
}


Хукаются только отдельно нажатые клавиши, которые нужны в работе и по отдельности,
как сделать хук только на сочетание клавиш с модификаторами?
    


Ответы

Ответ 1



Нужная Вам информация хранится в lParam метода hookProc http://www.firststeps.ru/mfc/winapi/hook/r.php?32 Смотрите по ходу выполнения что лежит в lParam.flags

Комментариев нет:

Отправить комментарий