Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.59/190: Рейтинг темы: голосов - 190, средняя оценка - 4.59
4 / 4 / 0
Регистрация: 11.03.2011
Сообщений: 115

Глобальный хук клавиатуры

19.04.2011, 17:13. Показов 35596. Ответов 24
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Я пишу программу с функцией воспроизведения.

Мне нужно, что бы программа при нажатии на клавишу начинала воспроизведение, или переходила на следующий или предыдущий трек.

При этом нужна возможность задания этих клавиш.

В моей программе есть специальный интерфейс(Interface) в котором есть описание для функции CurrentOptions.

То есть мне надо, что бы я нажал на какую то клавишу и если значение

C#
1
Interface.CurrentOptions.PlayStartHotKey = "Home";
соответствует нажатой клавише (в данном случае клавише "Home"), то начинается воспроизведение.

Как мне сделать такой глобальный хук?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
19.04.2011, 17:13
Ответы с готовыми решениями:

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

Отслеживание состояния "NumLock" или глобальный хук клавиатуры
Здравствуйте! Нужно по нажатию NumLock выводить окно программы. Что предпочтительнее, отслеживать состояние NumLock(включен или выключен),...

Глобальный хук
Всем доброго времени суток! Помогите написать глобальный хук и функцию для него, чтобы перехватывал вводимый текст с клавиатуры и писал в...

24
145 / 145 / 26
Регистрация: 09.10.2009
Сообщений: 261
20.04.2011, 13:17
Студворк — интернет-сервис помощи студентам
В свое время модифицировал данный проект под свои нужды. Добавьте следующий код в ваш класс-перехватчик:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
        [DllImport("user32")]
        private static extern int GetKeyboardState(byte[] pbKeyState);
 
        [DllImport("user32")]
        private static extern int ToUnicodeEx(
            int uVirtKey,
            int uScanCode,
            byte[] lpbKeyState,
            byte[] pwszBuff,
            int cchBuff,
            uint wFlags,
            int dwhkl);
 
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int GetWindowThreadProcessId(IntPtr handleWindow, out int lpdwProcessID);
 
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr GetKeyboardLayout(int WindowsThreadProcessID);
 
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr GetForegroundWindow();
 
        // Идентификатор активного процесса
        private static int _ProcessId;
 
        // Получаем все установленные в системе языки
        private static InputLanguageCollection _InstalledInputLanguages;
 
        // Текущий язык ввода
        private static int _CurrentInputLanguage;
 
        // Получение раскладки клавиатуры активного окна
        private static int GetKeyboardLayoutId()
        {
            _InstalledInputLanguages = InputLanguage.InstalledInputLanguages;
 
            // Получаем хендл активного окна
            IntPtr hWnd = GetForegroundWindow();
            
            // Получаем номер потока активного окна
            int WinThreadProcId = GetWindowThreadProcessId(hWnd, out _ProcessId);
            
            // Получаем раскладку
            IntPtr KeybLayout = GetKeyboardLayout(WinThreadProcId);
            
            // Циклом перебираем все установленные языки для проверки идентификатора
            for (int i = 0; i < _InstalledInputLanguages.Count; i++)
            {
                if (KeybLayout == _InstalledInputLanguages[i].Handle)
                {
                    _CurrentInputLanguage = _InstalledInputLanguages[i].Culture.KeyboardLayoutId;//.ThreeLetterWindowsLanguageName.ToString();
                }
            }
 
            return _CurrentInputLanguage;
        }
Данный код позволяет нам получать раскладку активного окна, а также - корректно работать с кириллицей.
В методе KeyboardHookProc обработка KeyPress должна выглядеть следующим образом:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
                if (KeyPress != null && wParam == WM_KEYDOWN)
                {
                    byte[] keyState = new byte[256];
                    GetKeyboardState(keyState);
                    int localeId = GetKeyboardLayoutId();
                    byte[] inBuffer = new byte[2];
 
                    if (ToUnicodeEx(MyKeyboardHookStruct.vkCode,
                          MyKeyboardHookStruct.scanCode,
                          keyState,
                          inBuffer,
                          2,
                          0,
                          localeId) >= 1)
                    {
                        UnicodeEncoding uEn = new UnicodeEncoding();
                        string outKey = uEn.GetString(inBuffer);
 
                        foreach (char key in outKey)
                        {
                            KeyPressEventArgs e = new KeyPressEventArgs(key);
                            KeyPress(this, e);
                            handled = handled || e.Handled;
                        }
                    }
                }
Класс формы будет выглядеть как-то так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
        static string URL { get; set; }
        static readonly UserActivityHook ActHook = new UserActivityHook();
        static readonly WindowsMediaPlayer WmPlayer = new WindowsMediaPlayer();
        
        public static void MyKeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar.ToString().ToLower().Equals("s") || e.KeyChar.ToString().ToLower().Equals("ы"))
            {
                if (WmPlayer.playState == WMPPlayState.wmppsPlaying)
                {
                    WmPlayer.controls.stop();
                }
            }
 
            if (e.KeyChar.ToString().ToLower().Equals("p") || e.KeyChar.ToString().ToLower().Equals("з"))
            {
                if (WmPlayer.playState == WMPPlayState.wmppsStopped || WmPlayer.playState == WMPPlayState.wmppsPaused)
                {
                    WmPlayer.controls.play();
                }
 
                if (WmPlayer.playState == WMPPlayState.wmppsUndefined)
                {
                    WmPlayer.URL = URL;
                    WmPlayer.controls.play();
                }
            }
        }
 
        public static void MyKeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyData.ToString().ToLower().Equals("home"))
                WmPlayer.controls.pause();
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            URL = @"E:\Trance\Karo\Across the Universe 012.mp3";
 
            ActHook.KeyPress += MyKeyPress;
            ActHook.KeyUp += MyKeyUp;
        }
В качестве примера использовал библиотеку WMPLib. Собственно, по нажатию на "з" / "p" (рус. и англ. эквиваленты) мы воспроизводим заданный файл. По нажатию на "ы" / "s" мы останавливаем воспроизведение. А "home" у нас отвечает за паузу.
П.С. Хук срабатывает даже при неактивном окне текущей программы. You're welcome.
1
4 / 4 / 0
Регистрация: 11.03.2011
Сообщений: 115
20.04.2011, 13:42  [ТС]
Спасибо, буду это иметь ввиду) пока у меня несколько иначе реализовано и пока работает)
0
4 / 4 / 0
Регистрация: 11.03.2011
Сообщений: 115
29.05.2011, 13:09  [ТС]
Новая проблема: клавиши иногда (а иногда и часто) перестают работать.
Можно ли создать такую команду, которая будет проверять, висит ли хук или нет и в противном случае будет его вешать?
0
 Аватар для Mans7
64 / 64 / 14
Регистрация: 05.08.2011
Сообщений: 323
Записей в блоге: 5
06.04.2012, 00:34
У меня возникла необходимость работы с хуком и я взял тот что Вы здесь выложили. Не примите за оффтоп.
Скажите пожалуйста, только ли у меня одного после перехвата хука и выполнению необходимого кода, приложение зависает на 2-3 секунды?
0
1 / 1 / 0
Регистрация: 05.11.2011
Сообщений: 14
13.03.2014, 06:19
Здравствуйте! Проверил данный пример - к сожалению, в нем так же присутствует общая проблема - в консольных приложениях раскладка не определяется. И в потомках тоже (т.е. запустили Outlook, тыкнули на http-ссылку, открылся IE и в IE уже раскладка определяется неправильно). Неужели только мне это надо?! Куда копать - непонятно...

Добавлено через 18 часов 58 минут
Прошелся ProcMon-ом. При тыканьи на ссылку, появляется два процесса iexplore. У одного 18 нитей, у другого 22. GetForegroundWindow показывает на нить одного из них. Есть вероятность, что волшебный IE написан так, что GetForegroundWindow неправильно определяет номер процесса (раскладки у разных нитей, надеюсь не могут быть разными). Кто-нибудь побеждал такое? Теоретически, можно добавить костыль, который будет проверять имя процесса, но если IE несколько, как узнать активного? %(
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
13.03.2014, 06:19

Глобальный хук на CreateProcess
требуется отслеживать запуск некоторых приложений и прибивать их при запуске, подскажите как реализовать чую полез в дремучий лес , если не...

Не ставится глобальный хук на мышь
В общем пытаюсь разобраться с Хуками. Короче ставлю глобальный Хук на мышку. Вроде все должно работать, но Хук не ставиться. Вот фрагменты...

Глобальный хук перестает работать
Всем привет, проблема: есть глобальный хук, он отслеживает какую кнопку я нажал, и если я нажал определенную клавишу то выполняется метод...

Глобальный Хук и ошибка 126
Здравствуйте, помогите пожалуйста. Пытаюсь скопировать глобальный хук из этой программы в свою, и вроде бы всё просто (там уже есть...

Глобальный клавиатурный хук и диспетчер задач
Я пишу глобальный клавиатурный хук. В нём при нажатии на определённые кнопки появляется сообщение о том что эта кнопка нажата. Например...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
25
Ответ Создать тему
Новые блоги и статьи
сукцессия 6. Питон реализация энилоджиковской модели, картинка про Центральную часть будущей модели
anaschu 26.06.2026
Етить. ИИ мне на основе моего старого файла R создал вот эту вот хмерь на пайтоне. Это уже новая модель, модель сукцессии грибной. потоки фосфора, азота. Углерода. 5 видов организмов. Я даже. . .
Как замкнутый ядерный цикл решит проблему недостатки фосфора? Био миграция фосфора со дна океана
anaschu 26.06.2026
Биологический лифт: Концепция подъема фосфора со дна океана с помощью ЗЯТЦ Предлагаю на обсуждение альтернативу тяжелому промышленному бурению океанического дна. Вместо сложной инженерии мы можем. . .
сукцессия 5
anaschu 26.06.2026
ПЛАН РАЗРАБОТКИ математической модели сукцессии микоризных систем Переход AM → EcM (Endo + ErM) · Шумилов А. С. · ИФХиБПП РАН · Пущино · 2026 . . .
сукцессия 4
anaschu 25.06.2026
Более детализированный план разработки План доработки модели динамики микоризных симбиозов (EcM с гистерезисом) Цель: Реализовать логику переключения между эрикоидным (ErM) и эктомикоризным. . .
сукцессия 3
anaschu 25.06.2026
Примерный план работ по модели
сукцессия 2
anaschu 25.06.2026
параметризировочная калибровочная таблица будущей модели
Многофункциональное здание: как одно здание порождает конфликты требований, которые никто не планировал (мат мет мод 29)
anaschu 23.06.2026
Многофункциональное здание: как одно здание порождает конфликты требований, которые никто не планировал Материалы для обсуждения с МГСУ · 2026 Рисунки внутри приложенного ворд файла. Что за. . .
28. Конкретное развертывание плана номер 1 из поста номер 27
anaschu 22.06.2026
Можно ли из модели получить конкретные строительные требования? Честно — напрямую из текущей модели такие ответы не получить. Но цепочка логики есть, и она не такая длинная. Где разрыв . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru