Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.62
Canckt
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 11
#1

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

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

Доброго времени суток, цель - написать программу, выполняющую код функции (напишу самостоятельно) по нажатию клавиши. Функций должно быть несколько, соответственно и клавиш тоже. При этом программа должна перехватывать нажатия, не будучи в фокусе. А вернее, в момент, когда работает полноэкранное приложение
Порыскав в сети, вычитал, что единственный способ - установить хуки. Сначала пробовал написать подобное на Python с помощью pyHook, но программа не работала, если с нее спадал фокус. Прошу помощи в написании подобного на C++, хотя бы элементарный код, далее подредактирую сам
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Psilon
Master of Orion
5770 / 4718 / 622
Регистрация: 10.07.2011
Сообщений: 14,195
Записей в блоге: 5
Завершенные тесты: 4
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;
}
Canckt
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 11
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)) ===|
raxp
10152 / 6539 / 477
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
26.07.2014, 19:13     Отслеживание нажатий клавиш, когда окно программы не в фокусе #4
вычитал, что единственный способ - установить хуки
далеко не единственный и уж далеко не самый рациональный ввиду всяческих антивирусов.

Знакомтесь, GetAsyncKeyState().
Canckt
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 11
26.07.2014, 22:42  [ТС]     Отслеживание нажатий клавиш, когда окно программы не в фокусе #5
raxp, Почитал описание. Правильно я понял, что эта функция не сработает, если программа будет свернута, а активно будет другое полноэкранное приложение?
Psilon
Master of Orion
5770 / 4718 / 622
Регистрация: 10.07.2011
Сообщений: 14,195
Записей в блоге: 5
Завершенные тесты: 4
27.07.2014, 01:51     Отслеживание нажатий клавиш, когда окно программы не в фокусе #6
Цитата Сообщение от Canckt Посмотреть сообщение
Спасибо, а какие библиотеки надо включить, чтобы программа работала?
ятп <windows.h>
Canckt
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 11
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
MasterOfOrion
Заблокирован
27.07.2014, 06:57     Отслеживание нажатий клавиш, когда окно программы не в фокусе #8
Ну ты ещё фильтр драйвер напиши
raxp уже ответил на вопрос, если речь идёт про WinApi, то следуют использовать GetAsyncKeyState, эта функция ловит состояние клавиатуры вне зависимости от фокуса мэйн виндуа (часто используется в геймдеве)
raxp
10152 / 6539 / 477
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
27.07.2014, 11:12     Отслеживание нажатий клавиш, когда окно программы не в фокусе #9
Почитал описание. Правильно я понял, что эта функция не сработает, если программа будет свернута, а активно будет другое полноэкранное приложение?
поняли неправильно, правильное понятие чуть выше ...и смените переводчик.
Psilon
Master of Orion
5770 / 4718 / 622
Регистрация: 10.07.2011
Сообщений: 14,195
Записей в блоге: 5
Завершенные тесты: 4
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));
    }
}
Canckt
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 11
27.07.2014, 14:12  [ТС]     Отслеживание нажатий клавиш, когда окно программы не в фокусе #11
raxp, Psilon, Спасибо, полезная конструкция. Работает без фокуса, работает в свернутом виде, но когда открываю приложение, на фоне которого программа должна работать - нажатия ловить перестает
raxp
10152 / 6539 / 477
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
27.07.2014, 17:50     Отслеживание нажатий клавиш, когда окно программы не в фокусе #12
...лично я отлов осуществляю в отдельном потоке или таймере.
Canckt
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 11
27.07.2014, 18:09  [ТС]     Отслеживание нажатий клавиш, когда окно программы не в фокусе #13
raxp, я на самом старте изучения C++, потому из Вашей фразы ничего не понял
raxp
10152 / 6539 / 477
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
27.07.2014, 19:00     Отслеживание нажатий клавиш, когда окно программы не в фокусе #14
...а вы не на С++ напирайте, а на WinAPI в MSDN.

http://msdn.microsoft.com/ru-ru/libr...v=vs.110).aspx
http://msdn.microsoft.com/ru-ru/libr...(v=vs.85).aspx
Canckt
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 11
27.07.2014, 19:02  [ТС]     Отслеживание нажатий клавиш, когда окно программы не в фокусе #15
raxp, WinAPI дается легче. Но GetAsyncKeyState() для моей задачи на сработало
raxp
10152 / 6539 / 477
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
27.07.2014, 19:07     Отслеживание нажатий клавиш, когда окно программы не в фокусе #16
...чушь. У всех работает, а у вас не работает. Код использования в тему.
Canckt
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 11
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));
    }
}
raxp
10152 / 6539 / 477
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
27.07.2014, 19:37     Отслеживание нажатий клавиш, когда окно программы не в фокусе #18
пост #14.
Canckt
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 11
27.07.2014, 20:09  [ТС]     Отслеживание нажатий клавиш, когда окно программы не в фокусе #19
raxp, то есть Вы считаете, что стоит модернизировать вышеприведенный код путем помещения цикла for в отдельный поток или таймер?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.07.2014, 22:18     Отслеживание нажатий клавиш, когда окно программы не в фокусе
Еще ссылки по теме:

Обработка нажатий клавиш с glfw C++
Перехват нажатий клавиш только с определенных программ C++ WinAPI
Отслеживание нажатия 2-х клавиш C++ Linux
C++ WinAPI Обработка нажатий клавиш
C++ WinAPI Отслеживание нажатия клавиш

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

Или воспользуйтесь поиском по форуму:
raxp
10152 / 6539 / 477
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
27.07.2014, 22:18     Отслеживание нажатий клавиш, когда окно программы не в фокусе #20
...цикл выкинуть, в поток запилить непосредственно опрос, слип выкинуть.
Yandex
Объявления
27.07.2014, 22:18     Отслеживание нажатий клавиш, когда окно программы не в фокусе
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru