Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.50/16: Рейтинг темы: голосов - 16, средняя оценка - 4.50
Canckt
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 11
#1

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

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

Доброго времени суток, цель - написать программу, выполняющую код функции (напишу самостоятельно) по нажатию клавиши. Функций должно быть несколько, соответственно и клавиш тоже. При этом программа должна перехватывать нажатия, не будучи в фокусе. А вернее, в момент, когда работает полноэкранное приложение
Порыскав в сети, вычитал, что единственный способ - установить хуки. Сначала пробовал написать подобное на Python с помощью pyHook, но программа не работала, если с нее спадал фокус. Прошу помощи в написании подобного на C++, хотя бы элементарный код, далее подредактирую сам
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.07.2014, 17:57
Ответы с готовыми решениями:

Отслеживание нажатия клавиш на C++
Здравствуте, прочитал статью про то как перехватывать нажатие клавиш средствами...

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

Определить когда в фокусе CppWebBrowser1
Есть задача определить когда находится в фокусе CppWebBrowser1 и когда он...

Эмулирование нажатий клавиш
Вводная: С++ builder 6. Программа А та что пишу я. Программа Б не моя. ...

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

21
Psilon
Master of Orion
Эксперт .NET
5998 / 4848 / 902
Регистрация: 10.07.2011
Сообщений: 14,460
Записей в блоге: 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;
}
1
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)) ===|
0
raxp
10183 / 6566 / 492
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
26.07.2014, 19:13 #4
вычитал, что единственный способ - установить хуки
далеко не единственный и уж далеко не самый рациональный ввиду всяческих антивирусов.

Знакомтесь, GetAsyncKeyState().
0
Canckt
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 11
26.07.2014, 22:42  [ТС] #5
raxp, Почитал описание. Правильно я понял, что эта функция не сработает, если программа будет свернута, а активно будет другое полноэкранное приложение?
0
Psilon
Master of Orion
Эксперт .NET
5998 / 4848 / 902
Регистрация: 10.07.2011
Сообщений: 14,460
Записей в блоге: 5
Завершенные тесты: 4
27.07.2014, 01:51 #6
Цитата Сообщение от Canckt Посмотреть сообщение
Спасибо, а какие библиотеки надо включить, чтобы программа работала?
ятп <windows.h>
1
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
0
MasterOfOrion
Заблокирован
27.07.2014, 06:57 #8
Ну ты ещё фильтр драйвер напиши
raxp уже ответил на вопрос, если речь идёт про WinApi, то следуют использовать GetAsyncKeyState, эта функция ловит состояние клавиатуры вне зависимости от фокуса мэйн виндуа (часто используется в геймдеве)
0
raxp
10183 / 6566 / 492
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
27.07.2014, 11:12 #9
Почитал описание. Правильно я понял, что эта функция не сработает, если программа будет свернута, а активно будет другое полноэкранное приложение?
поняли неправильно, правильное понятие чуть выше ...и смените переводчик.
0
Psilon
Master of Orion
Эксперт .NET
5998 / 4848 / 902
Регистрация: 10.07.2011
Сообщений: 14,460
Записей в блоге: 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));
    }
}
0
Canckt
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 11
27.07.2014, 14:12  [ТС] #11
raxp, Psilon, Спасибо, полезная конструкция. Работает без фокуса, работает в свернутом виде, но когда открываю приложение, на фоне которого программа должна работать - нажатия ловить перестает
0
raxp
10183 / 6566 / 492
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
27.07.2014, 17:50 #12
...лично я отлов осуществляю в отдельном потоке или таймере.
0
Canckt
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 11
27.07.2014, 18:09  [ТС] #13
raxp, я на самом старте изучения C++, потому из Вашей фразы ничего не понял
0
raxp
10183 / 6566 / 492
Регистрация: 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
1
Canckt
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 11
27.07.2014, 19:02  [ТС] #15
raxp, WinAPI дается легче. Но GetAsyncKeyState() для моей задачи на сработало
0
raxp
10183 / 6566 / 492
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
27.07.2014, 19:07 #16
...чушь. У всех работает, а у вас не работает. Код использования в тему.
0
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));
    }
}
0
raxp
10183 / 6566 / 492
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
27.07.2014, 19:37 #18
пост #14.
0
Canckt
0 / 0 / 0
Регистрация: 20.07.2014
Сообщений: 11
27.07.2014, 20:09  [ТС] #19
raxp, то есть Вы считаете, что стоит модернизировать вышеприведенный код путем помещения цикла for в отдельный поток или таймер?
0
raxp
10183 / 6566 / 492
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
27.07.2014, 22:18 #20
...цикл выкинуть, в поток запилить непосредственно опрос, слип выкинуть.
0
27.07.2014, 22:18
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.07.2014, 22:18

Перехват нажатий клавиш
Уже всё перерыл, чтобы найти что-то подобное! Если нахожу пример - он либо не...

Нажатие клавиш WASD из консоли в окно
Доброго времени суток. Я совсем новенький в C++ и надо чтоб клавиши зажимались...

Обработка нажатий клавиш
Добрый день! Решил сделать небольшую обработку нажатий клавиш в приложении,...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

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