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

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

12.05.2013, 01:06. Показов 11408. Ответов 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
Ответ Создать тему
Новые блоги и статьи
сукцессия 14. Обновленная схема модели
anaschu 28.06.2026
ГЛОБАЛЬНАЯ ОПИСАТЕЛЬНАЯ СПЕЦИФИКАЦИЯ ЭКОСИСТЕМНОЙ МОДЕЛИ «SOIL CHEMISTRY & MYCORRHIZA 2. 0» https:/ / ibb. co/ NnkGpfMd Представленная интегрированная схема описывает непрерывную нелинейную. . .
сукцессия 13. Питон модель трехзонного мицелия, пока что в основном арбускулярного
anaschu 28.06.2026
## Разработка агентной модели микоризной сукцессии: от выявления артефактов к созданию комплексной системы ### Аннотация Представлено исследование по разработке агентной модели микоризной. . .
сукцессия 12. краткий список проверок модели перед запуском.
anaschu 27.06.2026
Скрытые отказы в моделях систем динамики (SD-models) экологических систем: два случая из практики Контекст Разбирался прототип модели систем динамики (SD-модели) микоризной сукцессии: пять. . .
Сукцессия 11. Проверка орудий перед войной: разработка через тестирование
anaschu 27.06.2026
Как не дать модели соврать самой себе: проверки для симуляции микоризной сукцессии Введение Когда вы строите математическую модель живой системы — грибов, растений, почвы — главная опасность. . .
10 сукцессия. Питон код войны грибов и растений
anaschu 27.06.2026
import numpy as np class PlantAgent: def __init__(self, name, strategy, initial_biomass): self. name = name self. strategy = strategy # "greedy" (широколиственные) или. . .
сукцессия 9. Математика подлости: как растения предали грибных друзей
anaschu 27.06.2026
Статья 2. Глобальная фосфорная война: эволюционно-экономические механизмы распределения биомов Земли Введение: Экологический рынок как игра с нулевой суммой Традиционная экология долгое время. . .
сукцессия 8. Как я спорил с ИИ, которые - агенты растений и ненавистники грибов!
anaschu 27.06.2026
Статья 1. Хроники грибного восстания: как Сократов диалог разрушил академические догмы ИИ Введение: Синдром «цифрового учебника» Современные большие языковые модели (LLM) обладают колоссальным. . .
Главный вопрос моделирования сукцессии
anaschu 27.06.2026
главный вопрос. Если эктомикориза лучше добывает недоступный фосфор. И ее масса максимальна из всех. А широколиственный лес тоже имеет самую крутую биомассу. То почему не возникло их симбиоза? Это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru