Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.96/48: Рейтинг темы: голосов - 48, средняя оценка - 4.96
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 15
1

Отслеживание нажатий клавиш, когда окно программы не в фокусе

25.07.2014, 17:57. Показов 9420. Ответов 21
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток, цель - написать программу, выполняющую код функции (напишу самостоятельно) по нажатию клавиши. Функций должно быть несколько, соответственно и клавиш тоже. При этом программа должна перехватывать нажатия, не будучи в фокусе. А вернее, в момент, когда работает полноэкранное приложение
Порыскав в сети, вычитал, что единственный способ - установить хуки. Сначала пробовал написать подобное на Python с помощью pyHook, но программа не работала, если с нее спадал фокус. Прошу помощи в написании подобного на C++, хотя бы элементарный код, далее подредактирую сам
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.07.2014, 17:57
Ответы с готовыми решениями:

Считывание нажатий клавиш, когда программа не в фокусе
Для проверки нажатой кнопки есть команды KeyDown\Up и KeyPress, но они работают только когда...

Отслеживание нажатий комбинаций клавиш
Здравстуйте. Подскажите пожалуйста как можно отследить нажатие клавиш fn + (f1, .. ,f12) с помощью...

Отслеживание и подсчет правильных и неправильных нажатий клавиш
Приветствую всех, кто решил откликнуться! Ситуация такая, есть текст в текстовом документе, он...

Отслеживание нажатий клавиш внутри процедуры/цикла
Такие дела, недавно начал изучать VB и появилась проблема. Идет выполнение цикла внутри процедуры...

21
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
25.07.2014, 18:26 2
Canckt, создаем процедуру обработки нажатий:
C++
1
2
3
4
5
6
LRESULT __declspec(dllexport)__stdcall  CALLBACK KeyboardProc(int nCode,WPARAM wParam, LPARAM lParam)
{
    // что-то делаем
 
    return CallNextHookEx( hkb, nCode, wParam, lParam );
}
регистрируем хук:

C++
1
2
3
4
5
BOOL __declspec(dllexport)__stdcall installhook()
{
    hkb=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,hins,0);
    return TRUE;
}
1
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 15
26.07.2014, 18:39  [ТС] 3
Psilon, Спасибо, а какие библиотеки надо включить, чтобы программа работала?

В таком виде:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int main()
{
    LRESULT __declspec(dllexport)__stdcall  CALLBACK KeyboardProc(int nCode,WPARAM wParam, LPARAM lParam)
    {
    // что-то делаем
        if (wparam == VK_F1)
        {
        cout<<"Вы нажали F1"
        }
 
 
    return CallNextHookEx( hkb, nCode, wParam, lParam );
    }
 
    BOOL __declspec(dllexport)__stdcall installhook()
    {
    hkb=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,hins,0);
    return TRUE;
    }
 
}
Выдает
C++ (Qt)
1
2
3
4
5
D:\CPP-projects\Proga\f1-detect.cpp||In function 'int main()':|
D:\CPP-projects\P\f1-detect.cpp|13|error: 'LRESULT' was not declared in this scope|
D:\CPP-projects\P\f1-detect.cpp|13|error: expected ';' before '__attribute__'|
D:\CPP-projects\P\f1-detect.cpp|31|error: expected '}' at end of input|
||=== Build failed: 3 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
0
10231 / 6609 / 498
Регистрация: 28.12.2010
Сообщений: 21,156
Записей в блоге: 1
26.07.2014, 19:13 4
вычитал, что единственный способ - установить хуки
далеко не единственный и уж далеко не самый рациональный ввиду всяческих антивирусов.

Знакомтесь, GetAsyncKeyState().
0
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 15
26.07.2014, 22:42  [ТС] 5
raxp, Почитал описание. Правильно я понял, что эта функция не сработает, если программа будет свернута, а активно будет другое полноэкранное приложение?
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
27.07.2014, 01:51 6
Цитата Сообщение от Canckt Посмотреть сообщение
Спасибо, а какие библиотеки надо включить, чтобы программа работала?
ятп <windows.h>
1
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 15
27.07.2014, 04:53  [ТС] 7
Psilon, С горем пополам победил ошибки. Код вышел следующий:
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
#include <windows.h>
#include <iostream>
#include <stdio.h>
using namespace std;
HHOOK hkb;
HINSTANCE hins;
 
LRESULT __declspec(dllexport)__stdcall  CALLBACK KeyboardProc(int nCode,WPARAM wParam, LPARAM lParam)
    {
        if (wParam == VK_F1)
            {
        cout<<"Вы нажали F1";
            }
 
 
    return CallNextHookEx(hkb, nCode, wParam, lParam );
    }
 
BOOL __declspec(dllexport)__stdcall installhook()
    {
    hkb=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc, hins,0);
    return TRUE;
    }
 
int main()
{
 
 
 
 
}
Функции вроде объявились, а как теперь их запустить? То есть, заставить программу работать и реагировать хотя бы на F1
0
Заблокирован
27.07.2014, 06:57 8
Ну ты ещё фильтр драйвер напиши
raxp уже ответил на вопрос, если речь идёт про WinApi, то следуют использовать GetAsyncKeyState, эта функция ловит состояние клавиатуры вне зависимости от фокуса мэйн виндуа (часто используется в геймдеве)
0
10231 / 6609 / 498
Регистрация: 28.12.2010
Сообщений: 21,156
Записей в блоге: 1
27.07.2014, 11:12 9
Почитал описание. Правильно я понял, что эта функция не сработает, если программа будет свернута, а активно будет другое полноэкранное приложение?
поняли неправильно, правильное понятие чуть выше ...и смените переводчик.
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
27.07.2014, 11:26 10
raxp, ладно, ладно, уговорили

вроде, как-то так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <Windows.h>
#include <iostream>
#include <chrono>
#include <thread>
 
int main()
{
    for (;;)
    {
        for (char i = 0; i < 255; i++)
        {
            int keyState = GetAsyncKeyState(i);
            if (keyState == 1 || keyState == -32767)
            {
                std::cout << i << std::endl;
                break;
            }
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
}
0
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 15
27.07.2014, 14:12  [ТС] 11
raxp, Psilon, Спасибо, полезная конструкция. Работает без фокуса, работает в свернутом виде, но когда открываю приложение, на фоне которого программа должна работать - нажатия ловить перестает
0
10231 / 6609 / 498
Регистрация: 28.12.2010
Сообщений: 21,156
Записей в блоге: 1
27.07.2014, 17:50 12
...лично я отлов осуществляю в отдельном потоке или таймере.
0
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 15
27.07.2014, 18:09  [ТС] 13
raxp, я на самом старте изучения C++, потому из Вашей фразы ничего не понял
0
10231 / 6609 / 498
Регистрация: 28.12.2010
Сообщений: 21,156
Записей в блоге: 1
27.07.2014, 19:00 14
...а вы не на С++ напирайте, а на WinAPI в MSDN.

http://msdn.microsoft.com/ru-r... .110).aspx
http://msdn.microsoft.com/ru-r... s.85).aspx
1
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 15
27.07.2014, 19:02  [ТС] 15
raxp, WinAPI дается легче. Но GetAsyncKeyState() для моей задачи на сработало
0
10231 / 6609 / 498
Регистрация: 28.12.2010
Сообщений: 21,156
Записей в блоге: 1
27.07.2014, 19:07 16
...чушь. У всех работает, а у вас не работает. Код использования в тему.
0
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 15
27.07.2014, 19:10  [ТС] 17
Собственно, пробовал то, что написал товарищ выше
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <Windows.h>
#include <iostream>
#include <chrono>
#include <thread>
 
int main()
{
    for (;;)
    {
        for (char i = 0; i < 255; i++)
        {
            int keyState = GetAsyncKeyState(i);
            if (keyState == 1 || keyState == -32767)
            {
                std::cout << i << std::endl;
                break;
            }
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
}
0
10231 / 6609 / 498
Регистрация: 28.12.2010
Сообщений: 21,156
Записей в блоге: 1
27.07.2014, 19:37 18
пост #14.
0
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 15
27.07.2014, 20:09  [ТС] 19
raxp, то есть Вы считаете, что стоит модернизировать вышеприведенный код путем помещения цикла for в отдельный поток или таймер?
0
10231 / 6609 / 498
Регистрация: 28.12.2010
Сообщений: 21,156
Записей в блоге: 1
27.07.2014, 22:18 20
...цикл выкинуть, в поток запилить непосредственно опрос, слип выкинуть.
0
27.07.2014, 22:18
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.07.2014, 22:18
Помогаю со студенческими работами здесь

Отслеживание нажатий клавиш на клавиатуре после нажатия на кнопку
В программе имеется форма с кнопкой(button1). Больше ничего нет, у кнопки изменил только свойство...

Отловить нажатие определенной комбинации клавиш, даже когда программа не в фокусе
Бодрого дня или ночи! :D Написал программу и теперь нузно разобраться как сделать в ней управление...

Перехватить клик по клавише на клавиатуре, когда окно не в фокусе
Здравствуйте, у меня Windows Form приложение. Мне нужно отловить клик по клавише Shift на...

Отправка нажатий клавиш в неактивное окно - SendMessage
Доброго времени суток, пытаюсь реализовать отправку нажатий клавиш/кликов в окно игры, но возникает...

Отправка нажатий клавиш в окно стороннего приложения
Есть код на C++, в нём реализован поиск нужного окна по известному классу, эмуляция нажатий клавиш...

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru