Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.51/55: Рейтинг темы: голосов - 55, средняя оценка - 4.51
3 / 3 / 1
Регистрация: 13.03.2011
Сообщений: 114

Перехватчик клавиш + эмуляция нажатия клавиш

12.05.2013, 01:06. Показов 11562. Ответов 36
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! Срочно нужна помощь!

Моя программа работает в фоновом режиме. Мне нужно:
1) чтобы где бы я не находился в среде, программа ловила сообщения с клавиатуры, и обрабатывала их. (не шпионское ПО=) )
2) чтобы эта программа могла посылать сообщения в то окно в котором были нажаты клавиши... Сообщения - эмуляция нажатия клавиш.

Как мне осуществить хотя-бы один из пунктов?
Спасибо заранее!
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
12.05.2013, 01:06
Ответы с готовыми решениями:

Эмуляция нажатия клавиш
здрасте.мне нужно проэмулировать нажатие кнопок мыши и нажатий клавиш в неактивном окне(конкретно в браузере). слышал что можно окно...

Не работает эмуляция нажатия клавиш
while (true) { if (GetAsyncKeyState(VK_RSHIFT)== -32767 && progWorking == true) { keybd_event(VK_CONTROL, 0, 0, 0); ...

Перехват нажатия клавиш
Почему при нажатии на любую клавишу, выдаёт 2 MessageDox'a? Как я понимаю значит функция выполняется 2 раза, почему? В общем как сделать...

36
3 / 3 / 1
Регистрация: 13.03.2011
Сообщений: 114
12.05.2013, 16:17  [ТС]
Студворк — интернет-сервис помощи студентам
Спасибо. Заработало.
Но вопрос другой открытый - можно ли узнать откуда пришло сообщение? В каком окне я нажал на мышку?
0
 Аватар для FreeMan108
121 / 121 / 32
Регистрация: 04.03.2013
Сообщений: 370
12.05.2013, 16:21
Да, можно.

C++
1
((PMSG)lParam)->hwnd; //its a handle to our window
А вообще смотрите MSDN / RSDN
1
3 / 3 / 1
Регистрация: 13.03.2011
Сообщений: 114
12.05.2013, 17:05  [ТС]
Спасибо, ладно буду разбираться.

Добавлено через 42 минуты
Не знаете почему может дублироваться нажатие мышки? То есть, если я нажму правую кнопку мыши, то тело обработки сообщения выполнится дважды, как будто у нас этот Хуук зарегестрирован два раза в системе, и в списке обработчиков появляется два раза...
0
 Аватар для FreeMan108
121 / 121 / 32
Регистрация: 04.03.2013
Сообщений: 370
12.05.2013, 17:29
Есть такое дело. На самом деле хук срабатывает каждый раз, когда появляется новое сообщение, а оно может дублироваться именно в программе. По-этому такие помехи будет отсеять довольно трудно.

Добавлено через 2 минуты
Кст. я ошибался, все-таки можно отследить от кого пришло сообщение даже с помощью хуков WH_KEYBOARD/WH_MOUSE.
0
3 / 3 / 1
Регистрация: 13.03.2011
Сообщений: 114
12.05.2013, 17:33  [ТС]
Как?

Еще проблема, маюсь уже минут 50.
При обработки сообщения делаю.

C++
1
2
3
4
       hWndFrom = ((PMSG)lParam)->hwnd;
   
        PostMessage(hWndFrom, WM_KEYDOWN, VK_CONTROL,0); 
        PostMessage(hWndFrom, WM_KEYDOWN,'S',0);
Хочу имитировать нажатие комбинации клавиш Ctrl + S... Нифига не работает. Хотя если я напишу такой код:
C++
1
MessageBox (hWndFrom, L"Hi there!", L"Caption" ,MB_OK | MB_ICONWARNING);
то сообщение успешно выведется там где нажата клавиша Мыши...

Почему посылка нажатия клавиш не работает?? Если потом сделать WM_KEYUP то ничего не изменится
0
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
12.05.2013, 17:35
Цитата Сообщение от unkarjedy Посмотреть сообщение
Хочу имитировать нажатие комбинации клавиш Ctrl + S
Осталось ещё их отпускание.
0
 Аватар для FreeMan108
121 / 121 / 32
Регистрация: 04.03.2013
Сообщений: 370
12.05.2013, 17:40
В некоторых случаях вы получаете хэндл кнопки, по-этому не работает.

Попробуйте так:

C++
1
HWND hWndFrom = GetParent (((PMSG)lParam)->hwnd);
0
3 / 3 / 1
Регистрация: 13.03.2011
Сообщений: 114
12.05.2013, 17:40  [ТС]
Уже написал Если потом сделать WM_KEYUP то ничего не изменится... Если клавиши отпустить то ноль реакции так-же
0
 Аватар для FreeMan108
121 / 121 / 32
Регистрация: 04.03.2013
Сообщений: 370
12.05.2013, 17:43
Не в коем случае не делайте PostMessage, так как это сообщение пройдет через ваш хук. Оно вам надо? Есть риск в бесконечной обработке сообщения. Делайте SendMessage.
0
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
12.05.2013, 17:49
Цитата Сообщение от FreeMan108 Посмотреть сообщение
В некоторых случаях вы получаете хэндл кнопки
Мне кажется, если юзер нажмёт Ctrl+S, оно придёт той же кнопке, а переправить его куда надо - это задача проги (DefWindowProc). Разве нет?
1
 Аватар для FreeMan108
121 / 121 / 32
Регистрация: 04.03.2013
Сообщений: 370
12.05.2013, 17:59
Цитата Сообщение от Somebody Посмотреть сообщение
Мне кажется, если юзер нажмёт Ctrl+S, оно придёт той же кнопке, а переправить его куда надо - это задача проги (DefWindowProc). Разве нет?
Насчет этого вы правы.
0
3 / 3 / 1
Регистрация: 13.03.2011
Сообщений: 114
12.05.2013, 18:04  [ТС]
Не получается в любом случае, отправлять пытаюсь и Перенту и самому hWnd...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
       hWnd        = ((PMSG)lParam)->hwnd;
        hWndParent  = GetParent (hWnd);
 
        PostMessage(hWnd, WM_KEYDOWN, VK_CONTROL,0); 
        PostMessage(hWnd, WM_KEYDOWN,'S',0); 
        PostMessage(hWnd, WM_KEYUP,'S',0); 
        PostMessage(hWnd, WM_KEYUP, VK_CONTROL,0);
 
        PostMessage(hWndParent, WM_KEYDOWN, VK_CONTROL,0); 
        PostMessage(hWndParent, WM_KEYDOWN,'S',0); 
        PostMessage(hWndParent, WM_KEYUP,'S',0); 
        PostMessage(hWndParent, WM_KEYUP, VK_CONTROL,0);
 
        MessageBox(hWnd, L"Hi there!", L"Caption", 0);
Добавлено через 35 секунд
Проверяю на браузере, должно высветиться сохранить страницу как... ничего не происходит
0
 Аватар для FreeMan108
121 / 121 / 32
Регистрация: 04.03.2013
Сообщений: 370
12.05.2013, 18:12
Странно. Будем разбираться.
0
3 / 3 / 1
Регистрация: 13.03.2011
Сообщений: 114
12.05.2013, 18:47  [ТС]
Частично разобраться... Нашел функцию SendInput... Работает, но пока глючно =)

Добавлено через 3 минуты
Попробовал так...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
INPUT ip;
 
    ip.type = INPUT_KEYBOARD;
    ip.ki.wScan = 0; // hardware scan code for key
    ip.ki.time = 0;
    ip.ki.dwExtraInfo = 0;
 
    // Press the "A" key
    ip.ki.wVk = 's'; // virtual-key code for the "a" key
    ip.ki.wVk = VK_CONTROL;
    ip.ki.dwFlags = 0; // 0 for key press
 
    SendInput(1, &ip, sizeof(INPUT));
Но так Ctrl тупо залипает, а клавиша 'S' не реагирует

Добавлено через 47 секунд
Через SendMesage так ничего и не получилось
0
213 / 139 / 8
Регистрация: 18.08.2010
Сообщений: 1,018
13.05.2013, 01:33
ЧТо же там сложного? Вот тебе рабочий пример, как отлавливать нажатые клавиши, делать что-то с ними, и эмулировать их нажатие, либо пропускать их.

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <windows.h>
#include <iostream>
 
HHOOK s_KeyboardHookHandle;
bool flag = false;
 
LRESULT __stdcall HookCallback(int nCode, WPARAM wParam, LPARAM lParam);
UINT KeyDown(WORD scanCode);
UINT KeyUp(WORD scanCode);
 
 
int _tmain(int argc, _TCHAR* argv[])
{
    printf("start\n");
    s_KeyboardHookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, HookCallback, NULL, 0);
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        printf("_");
    }
    printf("press for unhook\n");
    std::cin.get();
    printf("end\n");
    UnhookWindowsHookEx(s_KeyboardHookHandle);
    return 0;
}
 
LRESULT __stdcall HookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (flag)//если нажатая клавиша является сэмулированной нами в SendInput, тогда ничего не делаем, а просто пересылаем хук дальше с помощью CallNextHookEx, иначе будет рекурсия и система повиснет
        return CallNextHookEx(s_KeyboardHookHandle, nCode, wParam, lParam);
 
    if (nCode >= 0)
    {
        KBDLLHOOKSTRUCT kbHookStruct = *((KBDLLHOOKSTRUCT*)lParam);
 
        if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)
        {
            printf("%d down\n", kbHookStruct.scanCode);
            //клавиша была зажата. Что-то делаем свое... Раскоментируй следующую строку, чтобы нажатая клавиша так и не "нажалась"
            //return -1;
            //эмулируем нажатие клавиши:
            KeyDown((DWORD)kbHookStruct.scanCode);
        }
 
        if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP)
        {
            printf("%d up\n", kbHookStruct.scanCode);
            //клавиша была отжата. Что-то делаем свое... Раскоментируй следующую строку, чтобы клавиша так и осталась "нажатой", не смотря на то, что пользователь уже убрал палец с клавиши;)
            //return -1;
            //эмулируем отжатие клавиши:
            KeyUp((DWORD)kbHookStruct.scanCode);
        }
    }
    return -1;
}
 
UINT KeyDown(WORD scanCode)
{
    INPUT* inputs = new INPUT[1];
    inputs[0].type = INPUT_KEYBOARD;
    inputs[0].ki.dwFlags = KEYEVENTF_SCANCODE;
    inputs[0].ki.wScan = scanCode;
    //inputs[0].ki.wVk = '1';
    flag = true;
    UINT retVal = SendInput(1, inputs, sizeof(inputs[0]));
    flag = false;
    delete(inputs);
    return retVal;
}
 
UINT KeyUp(WORD scanCode)
{
    INPUT* inputs = new INPUT[1];
    inputs[0].type = INPUT_KEYBOARD;
    inputs[0].ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
    inputs[0].ki.wScan = scanCode;
    //inputs[0].ki.wVk = '1';
    flag = true;
    UINT retVal = SendInput(1, inputs, sizeof(inputs[0]));
    flag = false;
    delete(inputs);
    return retVal;
}
Добавлено через 3 минуты
Цитата Сообщение от unkarjedy Посмотреть сообщение
Но так Ctrl тупо залипает, а клавиша 'S' не реагирует
потому что ты лепишь все в одну структуру. Сперва записываешь S, а потом сразу переписываешь контролом. Контрол у тебя зажимается, но не отжимается, потому что функция SendInput отдельно шлет сигнал для нажатия клавиши и отдельно для отпускания. Потому вам нужно вызывать эту функцию два раза, но с разными значениями dwFlags. Короч смотри мой пример, там все работает.
0
 Аватар для FreeMan108
121 / 121 / 32
Регистрация: 04.03.2013
Сообщений: 370
13.05.2013, 19:11
Tolias28, хуки нужно хранить в dll. Вы согласны?
1
213 / 139 / 8
Регистрация: 18.08.2010
Сообщений: 1,018
13.05.2013, 23:00
Цитата Сообщение от FreeMan108 Посмотреть сообщение
Tolias28, хуки нужно хранить в dll. Вы согласны?
Да.. До того, как увидел ваше сообщение, этого не знал. А вот почитал мсдн, уже узнал зачем и для чего..) Я в этом деле сам пока тоже новенький))
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
13.05.2013, 23:00

История нажатия клавиш
Я прошу прощения, но знает ли кто ни будь как можно реализовать это: Нужно создать программу которая будет записывать в файл историю...

Имитация нажатия клавиш
Как сделать так, чтобы нужный мне текст как будто сам набирался на клавиатуре, но чтобы пользователь (другой человек) сам ничего не делал?

Отключение нажатия клавиш
Всем привет! как можно отключить нажатие клавиш ALT + TAB, ALT+ F4, CTRL + ALT + DEL. Подскажите, пожалуйста? Добавлено через 12 минут...

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

Отслеживание нажатия клавиш
Нужно написать логер нажатия клавиш. Сам код кейлогера у меня есть. Подскажите как сделать так чтобы при вводе ключевого слова (например...


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

Или воспользуйтесь поиском по форуму:
37
Ответ Создать тему
Новые блоги и статьи
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
День 5 из 28: Codex подсказывает следующий запрос
and_y87 12.10.2026
9 октября 2026 года OpenAI запустила бету Composer predictions — подсказок следующего сообщения в текущем диалоге Codex. Это помощь с формулировкой запроса, а не автоматическое продолжение задачи. . . .
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru