Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поймать нажатие клавиш в консоле, когда консоль неактивная 
V
    Опции темы
Townsmen
Дата 3.6.2012, 23:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 20.7.2011

Репутация: нет
Всего: 1



Есть консольное приложение, оно реагирует на нажитие стрелок вверх или низ но только тогда когда окно консоли активировано. Код нашол на этом форуме
Код

#include <conio.h>
using namespace std;

void doUpArrowAction() { cout << "UP";} //ф-ция нажатия стрелки вверх
void doDownArrowAction() { cout << "DOWN";}  //ф-ция нажатия стрелки вниз

int key = _getch(); // в key код клавиши, можем привести к char
if (key == 0xE0) // значение для навигац. клавиши, в нек-рых компилерах 0
{
  key = _getch(); // собсно код самой навигац. клавиши
  if (key == 0x50)
    doDownArrowAction();
  else if (key == 0x48)
    doUpArrowAction();
}


Как сделать что бы консоль реагировала на нажатие стрелок вверх или низ даже тогда, когда я работаю в другом окне и нажимаю на клавиши?
PM MAIL   Вверх
Cheloveck
Дата 4.6.2012, 01:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 3
Всего: 32



Тебе нужно ловить сообщения от ОС с помощью SetWindowsHookEx с параметром WH_KEYBOARD.  Тут есть пример.


Это сообщение отредактировал(а) Cheloveck - 4.6.2012, 01:45


--------------------
user posted image
PM Jabber   Вверх
Townsmen
Дата 4.6.2012, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 20.7.2011

Репутация: нет
Всего: 1



что-то я не могу разобраться как должна работать эта функция  SetWindowsHookEx взял часть кода с наведенного примера, вот что у меня получилось:
Код

# include <iostream>
# include <string>
#include <conio.h>
#include <windows.h>

using namespace std;
int rt;
HHOOK hKeyboardHook = 0;
HMODULE hInstance = 0;
LRESULT CALLBACK KeyboardProc(int code,       // hook code
                              WPARAM wParam,  // virtual-key code
                              LPARAM lParam)  // keystroke-message information
{
    cout << "press";
    if (code > 0)
    {
       cout << "press1";
    }
    cin >> rt;
    return CallNextHookEx(hKeyboardHook, code, wParam, lParam);
};


int main()
{
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hInstance, 0);
    cout << "Vvod: ";
    cin >> rt;
    if(rt>0 && rt<100) {
        cout << "yes";
    } else {
        cout << "no";
    }
    cin >> rt;
    
  return 0;
}


я так понял когда жмеш любую клавишу на клавиатуре должна срабатывать функция KeyboardProc ? или я что-то нетак делаю?
PM MAIL   Вверх
Cheloveck
Дата 4.6.2012, 12:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 3
Всего: 32



Цитата(Townsmen @  4.6.2012,  13:15 Найти цитируемый пост)
HMODULE hInstance = 0;

Почему ноль?
http://stackoverflow.com/a/454503
В случае, если вызов происходит из *.exe файла мы получаем
Код

DWORD err = GetLastError();

err = 1428, что означает 
Цитата

Cannot set nonlocal hook without a module handle.


Это сообщение отредактировал(а) Cheloveck - 4.6.2012, 12:56


--------------------
user posted image
PM Jabber   Вверх
Townsmen
Дата 4.6.2012, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 20.7.2011

Репутация: нет
Всего: 1



HMODULE hInstance - дескриптор экземпляра прикладной программы
это нужно указать дискриптор програмы в которой я буду работать, что бы консольное приложение ловило сообщения этой програмы ( клавиши) ?
PM MAIL   Вверх
Cheloveck
Дата 4.6.2012, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 3
Всего: 32



Цитата(Townsmen @  4.6.2012,  13:55 Найти цитируемый пост)
это нужно указать дискриптор програмы в которой я буду работать, что бы консольное приложение ловило сообщения этой програмы ( клавиши) ? 

Код

hInstance = GetModuleHandle(NULL);

Не помогает, нужно поместить в DLL, по всей видимости


--------------------
user posted image
PM Jabber   Вверх
Townsmen
Дата 4.6.2012, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 20.7.2011

Репутация: нет
Всего: 1



я с DLL еще не работал, незнаю как их подключать и как создавать их.
Вот нашол код где SetWindowsHookEx работает без DLL
http://forum.vingrad.ru/forum/topic-343733...okex/index.html
PM MAIL   Вверх
volatile
Дата 4.6.2012, 23:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(Townsmen @  3.6.2012,  23:19 Найти цитируемый пост)
Как сделать что бы консоль реагировала на нажатие стрелок вверх или низ даже тогда, когда я работаю в другом окне и нажимаю на клавиши? 

Можно и без длл.
GetAsyncKeyState возвращает текущее состояние клавиши (нажата/отпущена), не зависимо от активности приложения.


PM MAIL   Вверх
Dem_max
Дата 5.6.2012, 04:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 4
Всего: 39



Используй сообщение WM_INPUT для получения нажатий.


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
Townsmen
Дата 5.6.2012, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 20.7.2011

Репутация: нет
Всего: 1



Спасибо всем большое за помощь!  Воспользовался GetAsyncKeyState как раз то что надо  smile
Пример кода, может кому то пригодится:
Код

# include <iostream>
#include <windows.h>

using namespace std;
void doDownArrowAction() { cout << "press Insert \n";}

int main()
{
    bool dowork = TRUE;
    while(dowork == TRUE)//цикл работает пока dowork = TRUE
    {
        if(GetAsyncKeyState(0x2D))//если нажата клавиша Insert
        {
           doDownArrowAction();
        }
        Sleep(100);//выжидаем 100 мс для уменьшения нагрузки на процессор
    }
    
  return 0;
}



PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0859 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.