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

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

19.04.2011, 17:13. Показов 35594. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Многофункциональное здание: как одно здание порождает конфликты требований, которые никто не планировал (мат мет мод 29)
anaschu 23.06.2026
Многофункциональное здание: как одно здание порождает конфликты требований, которые никто не планировал Материалы для обсуждения с МГСУ · 2026 Рисунки внутри приложенного ворд файла. Что за. . .
28. Конкретное развертывание плана номер 1 из поста номер 27
anaschu 22.06.2026
Можно ли из модели получить конкретные строительные требования? Честно — напрямую из текущей модели такие ответы не получить. Но цепочка логики есть, и она не такая длинная. Где разрыв . . .
27. Планы на разработку функциональных требований к строительству внутри модели пищеблока (или не только его?)
anaschu 22.06.2026
Что уже реализовано и даёт конфликты «бесплатно» Самый простой конфликт уже работает — конфликт за ресурс-работника. Заданий больше, чем доступных поваров → очередь в queue1. Это прямое отражение. . .
26. мед мат модель.Какие типы конфликтов функциональных требований можно рассчитать через ДЕС-моделирование (СМО) в AnyLogic?
anaschu 22.06.2026
Что ДЕС/ СМО умеет считать напрямую: Конфликты за ресурсы (очереди, узкие места). Несколько типов агентов (повара, учителя, рабочие, пациенты) претендуют на один ресурс (лифт, вход, коридор,. . .
25 модель здравосохранения и функциональных требований к пищеблоку: конфликты функциональных требований.
anaschu 22.06.2026
Есть ли данные о том, какие функциональные/ эксплуатационные требования или их сочетания труднее всего учитывать при проектировании зданий? Да, такие данные есть, и они хорошо описаны и в российской,. . .
Remote Connection Manager
DevAlt 21.06.2026
Написал для себя небольшую прилагу: https:/ / github. com/ altbodhi/ ReConMan По итогу пришел к мысли, что DU не дружат с существующими технологиями. От сериализации до отображения в реляционную. . .
Администрация Хабра удаляет новые энергоэфективные алгоритмы, которые не западной школы кода, и вовсе никак не сгенерированы
Hrethgir 20.06.2026
Делается это, как замечено, при правках - при объявлении концептуальных отличий в алгоримах. Делается это, по линейке событий - после дополнения публикации основными отличиями от основных западных. . .
Процесс ориентированная диалектика (не новость - просто системное обновление, философия).
Hrethgir 20.06.2026
Однажды один участник в своём блоге, на этом форуме, сделал запись "О языках замолвите слово". Понимая, что язык - важная вещь, я решил хорошо подумать, прежде чем сказать, и сказал то, что вы видите. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru