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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Функция "GetAsyncKeyState" отрабатывает выборочно. 
V
    Опции темы
Jr13san
Дата 10.5.2013, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 174
Регистрация: 29.7.2008
Где: г. Павлово

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



Приветствую всех, кто на форуме!
При разработке приложения на c++ я заметил такую проблему на win7. На windows XP было всё в порядке.
Сразу приведу небольшой код консольного приложения:
Код

//Включаем заголовочные файлы в проект
#include <windows.h>//для использования Windows API функций
#include <iostream>//специально для функции printf()


void main()
{
    while(1)//реализуем бесконечный цикл
    {
        if (GetAsyncKeyState(VK_LWIN))//проверяем нажата ли Левая клавиша Windows, если да, то
        {
            printf("%s","Windows");//выводим сообщение
            Sleep(100);//делаем задержку на 100 мсек.
        }
    }
}

Вообщем выясняется, что в некоторых full screen-приложениях данная функция GetAsyncKeyState не реагирует при нажатии клавиш:windows(обе), Pause Break и все кнопки мышки. Сигналы от остальных клавиш обрабатываются. Что же делать с этими, для которых происходит блокировка?
Из справочника прочитал, что блокировка может происходить из за:
1) Текущий рабочий стол - не активный рабочий стол.
2) Приоритетный поток принадлежит другому процессу, а рабочий стол не разрешает работу процедуры-ловушки (hook) или запись в журнал.

Но я не пойму почему на winXP всё работало без проблем, а на этой win7 такая вот смешная картина?

Это сообщение отредактировал(а) Jr13san - 10.5.2013, 20:02
PM MAIL WWW ICQ   Вверх
Dem_max
Дата 11.5.2013, 05:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Заюзать WM_INPUT (RegisterRawInputDevices)


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


Бывалый
*


Профиль
Группа: Участник
Сообщений: 174
Регистрация: 29.7.2008
Где: г. Павлово

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



Да, Спасибо, нашёл кое-какую информацию по этому поводу, но вот за что я не люблю этот с++, так это за кучу всяких типов.
Пишу код:
Код

//Включаем заголовочные файлы в проект
#include <windows.h>//для использования Windows API функций
#include <iostream>//специально для функции printf()

void main()
{
    RAWINPUTDEVICE Rid;
    Rid.usUsagePage = 1;
    Rid.usUsage = 6;
    Rid.dwFlags = 0;
    Rid.hwndTarget = NULL;

    if (RegisterRawInputDevices(Rid,1,sizeof(RAWINPUTDEVICE)) == FALSE)
    {
        printf("%s","Handle Error");
    }
}

error C2664: RegisterRawInputDevices: невозможно преобразовать параметр 1 из 'RAWINPUTDEVICE' в 'PCRAWINPUTDEVICE'

Я не пойму как правильно записать. Везде пишут примерно в таком формате. У меня же как всегда - ошибка. Помогите исправить пожалуйста.
PM MAIL WWW ICQ   Вверх
feodorv
Дата 11.5.2013, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(Jr13san @  11.5.2013,  10:38 Найти цитируемый пост)
    if (RegisterRawInputDevices(&Rid,1,sizeof(RAWINPUTDEVICE)) == FALSE)


Добавлено через 1 минуту и 23 секунды
Или
Цитата(Jr13san @  11.5.2013,  10:38 Найти цитируемый пост)
    RAWINPUTDEVICE Rid[1];




--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Jr13san
Дата 11.5.2013, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 174
Регистрация: 29.7.2008
Где: г. Павлово

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



Хорошо, регистрацию двух девайсов мы прошли:
Код

//Включаем заголовочные файлы в проект
#include <windows.h>//для использования Windows API функций
#include <iostream>//специально для функции printf()


void main()
{
    setlocale(LC_ALL, "Russian");//устанавливаем русский язык для вывода информации на экран
    HWND hWnd = NULL;//объявляем переменную hWnd(handle Window) и присваиваем ей значение NULL(т.е. пустое значение)
    while(!hWnd)//ищем хэндл окна до тех пор, пока не найдём его
    {
        hWnd = FindWindow(NULL, TEXT("Gothic II - 2.6 (fix)"));
        Sleep(100);//задержка цикла
    }

    RAWINPUTDEVICE Rid[2]; 

    Rid[0].usUsagePage = 0x01; 
    Rid[0].usUsage = 0x02; 
    Rid[0].dwFlags = RIDEV_NOLEGACY;   // adds HID mouse and also ignores legacy mouse messages
    Rid[0].hwndTarget = 0;

    Rid[1].usUsagePage = 0x01; 
    Rid[1].usUsage = 0x06; 
    Rid[1].dwFlags = RIDEV_NOLEGACY;   // adds HID keyboard and also ignores legacy keyboard messages
    Rid[1].hwndTarget = 0;

    if (RegisterRawInputDevices(Rid, 2, sizeof(Rid[0])) == FALSE)
    {
        //registration failed. Call GetLastError for the cause of the error
        printf("%s","Registration failed");
    }

}


Что делать дальше? помогите пожалуйста дописать рабочий вариант кода, а то эти мелкософты пишут обрывками кода и у меня ничего не получается. Хоть бы сделали рабочий вариант кода - скопировал, вставил, посмотрел как работает, разобрался и подстроил их код под свои нужды. Неет им так не надо.

Что-то мне подсказывает, что дальше нужно использовать функцию GetRawInputData(), а в ней опять куча параметров вот с такими типами LIAJHGQPOUAYD и KJASJHGQWsaoid. Хотя наверное все бородатые типы - это либо структуры, либо классы, заранее объявленные в каком-либо месте..

Это сообщение отредактировал(а) Jr13san - 11.5.2013, 16:18
PM MAIL WWW ICQ   Вверх
Dem_max
Дата 11.5.2013, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата

 но вот за что я не люблю этот с++

Что то с++ я вообще не увидел.

Цитата

а то эти мелкософты пишут обрывками кода и у меня ничего не получается


код весь тут
http://msdn.microsoft.com/en-us/library/wi...6(v=vs.85).aspx

http://www.codeproject.com/Articles/381673...ultiTouch-Digit

P.S. обязательно указать флаг RIDEV_INPUTSINK чтобы вести отлов событий когда приложение не в фокусе.


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


Бывалый
*


Профиль
Группа: Участник
Сообщений: 174
Регистрация: 29.7.2008
Где: г. Павлово

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




Я про него и говорил.
Я хоть и не очень шарю в с++, но что-то в их исходнике я не вижу "switch" перед "case". Я вот по крайней мере даже не понимаю что конкретно проверять "кэйсом". Уж лучше бы написал кто простенький пример, хотя бы рабочий пример. Может и он работать путью не будет, что мне мучится в этих дебрях? Ладно Win API, но эти преобразования типов просто выводят из себя. Ладно.. Ещё раз прошу, помогите, напишите простенький рабочий пример, пожалуйста, ведь не долго.

PS:
Ладно switch-case - это ещё базовый синтаксис, а вот куда дели это ? :
Код

LRESULT WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)//WPARAM, LPARAM, Z*LUPPARAM мать его ети!
{
    // WM_INPUT data
    //
    static RAWINPUT buffer[32];
    static RAWINPUT ** pBuffer = new RAWINPUT *[32];
    static unsigned int HEADERSIZE = sizeof(RAWINPUTHEADER);

    switch(msg)
    {

    ...

    // input handling: use raw input
    //
    case WM_INPUT:
        {
        ...


Ладно, программисты, не обижайтесь, если что не так сказал...

Это сообщение отредактировал(а) Jr13san - 11.5.2013, 21:48
PM MAIL WWW ICQ   Вверх
volatile
Дата 11.5.2013, 23:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Jr13san @  10.5.2013,  19:59 Найти цитируемый пост)
я заметил такую проблему на win7.

Цитата(Jr13san @  10.5.2013,  19:59 Найти цитируемый пост)
Вообщем выясняется, что в некоторых full screen-приложениях 

В каких это некоторых ?
В вин 7 нет больше консольных full screen приложений.


PM MAIL   Вверх
Jr13san
Дата 12.5.2013, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 174
Регистрация: 29.7.2008
Где: г. Павлово

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



Цитата

В каких это некоторых ?
В вин 7 нет больше консольных full screen приложений.

Да нет, вы поймите меня правильно. Я делаю консольное приложение для fullscreen-приложений: Gothic, Gothic II. Может быть даже ключевое слово и не "fullscreen", а просто у данных приложений своя обработка событий с клавиатуры и мышки. А вот, например, в том же самом CS 1.6 и "GetAsyncKeyState" нормально работает.
Но у меня возникла проблема - я не знаю что писать дальше в этой структуре вызовов(т.е. в коде). Я вот и думаю, а будет ли вообще работать этот RawInputDevice?

Это сообщение отредактировал(а) Jr13san - 12.5.2013, 10:41
PM MAIL WWW ICQ   Вверх
volatile
Дата 12.5.2013, 23:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Jr13san @  12.5.2013,  10:36 Найти цитируемый пост)
Я делаю консольное приложение для fullscreen-приложений: Gothic, Gothic II.
... в том же самом CS 1.6 

Сорри, не знаю о чем вы говорите...

Цитата(Jr13san @  11.5.2013,  20:31 Найти цитируемый пост)
LRESULT WndProc(HWND hwnd, UINT 

Да, и если вы пишете все-же консольное приложение, то там в принципе нет WndProc


PM MAIL   Вверх
Jr13san
Дата 13.5.2013, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 174
Регистрация: 29.7.2008
Где: г. Павлово

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



Цитата

Сорри, не знаю о чем вы говорите...

Да хоть для программы "Калькулятор" напишите отлов событий нажатия клавиш, это не важно. Главное то, что в коде я не продвинулся дальше регистрации "девайса", который выдаёт ошибку!
Что толку ходить вокруг, да около, можно тему закрывать. Всё равно путного здесь никто ничего больше не подскажет.
Я сам не люблю писать или делать работу за других, но пытаюсь им объяснить так, чтобы они более-менее поняли как делать и у них всё было для этого. И в итоге люди сами всё делают. Здесь же я не вижу хода написания кода или структуры вызовов функций. У меня нету ни рабочего примера, ни понятного алгоритма действий, а только непонятные куски кода.
PM MAIL WWW ICQ   Вверх
volatile
Дата 13.5.2013, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Jr13san @  13.5.2013,  09:53 Найти цитируемый пост)
Всё равно путного здесь никто ничего больше не подскажет.


Jr13san, чтоб что-то путное подсказали, нужно сначала задать путный вопрос.
После третьего дня, кажецца я начинаю понимать что вам нужно. 
Вы хотите в консольном приложении отлавливать нажатия клавиш, фокус ввода которых находицца в другом приложении? 
так чтоле? 

да, и еще вопрос, от имени админа пробовали запускать вашу программу, которая на XP работала?

PM MAIL   Вверх
Jr13san
Дата 13.5.2013, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 174
Регистрация: 29.7.2008
Где: г. Павлово

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



Цитата

Jr13san, чтоб что-то путное подсказали, нужно сначала задать путный вопрос.

volatile, спасибо.

Цитата
После третьего дня, кажецца я начинаю понимать что вам нужно. 
Вы хотите в консольном приложении отлавливать нажатия клавиш, фокус ввода которых находицца в другом приложении? 
так чтоле? 

Ну вообщем то да. Расскажу максимально подробно как всё происходит.

1) Пользователь запускает игру - "Gothic II" и консольное приложение.
2) Консоль как только находит окно "Gothic II - 2.6 (fix)", получает его handle, PID и др., сразу же начинает искать строку с таким названием "KeyState_000" внутри памяти игры "Gothic II" через ReadProcessMemory(). И как только она находит адрес по которому расположена данная строка, она сразу же может записывать вместо нулей код текущей нажатой клавиши. Например, если нажат пробел, то строка в памяти игры "Gothic II" примет вид: "KeyState_032", дальше через 25 мсек. происходит замена кода клавиши обратно на нули: "KeyState_000".
Я же со стороны игры могу обработать ту строку "KeyState_032" через скрипты и сделать определённые выводы. Вот такая система управления была задумана.

Чтение и запись в память игры уже реализована. Отлов нажатий, как я уже писал раньше, был сделан на основе API функции GetAsyncKeyState(). Но на win7 для "Gothic II" она не работает как положено.
Помогите мне дописать рабочий прототип на основе "RawInputDevice".

Цитата

да, и еще вопрос, от имени админа пробовали запускать вашу программу, которая на XP работала?

Только что попробовал - не работает.
PM MAIL WWW ICQ   Вверх
volatile
Дата 13.5.2013, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Jr13san @  13.5.2013,  14:44 Найти цитируемый пост)
Помогите мне дописать рабочий прототип на основе "RawInputDevice".

Jr13san, что-то я сильно сомневаюсь что RawInputDevice будет получать клавиатурный ввод из другого приложения...

Вам, имхо, нужно хук на клаву ставить. (причем в отдельной dll)
SetWindowsHookEx (WH_KEYBOARD, ...
SetWindowsHookEx (WH_KEYBOARD_LL, ...

осилите ли, не знаю. И к тому-же в игрушках может стоять защита от этого. (впрочем это предположение, с игрушками дел не имел)
PM MAIL   Вверх
Jr13san
Дата 14.5.2013, 07:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 174
Регистрация: 29.7.2008
Где: г. Павлово

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



Говорят, что из за хуков возникают сильные лаги(задержки, подвисания). Мне бы не желательно таких вещей добавлять к и так уже "старушке Gothic".
Цитата

Вам, имхо, нужно хук на клаву ставить. (причем в отдельной dll)

Если речь идёт об инжектинге, то я пас, и, одновременно, против данного способа. Лучше уж ничего, чем такой костыль вставлять.
Ну хорошо, а может есть какие-то отдельные способы отследить нажатия только на клавиши мышки?
PM MAIL WWW ICQ   Вверх
EgoBrain
Дата 14.5.2013, 08:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 537
Регистрация: 23.3.2008
Где: Комната

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



Может тебе попробовать DirectInput? Там опрос устройство через промежутки времени осуществляется...
PM MAIL ICQ Skype   Вверх
Jr13san
Дата 15.5.2013, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 174
Регистрация: 29.7.2008
Где: г. Павлово

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



EgoBrain, может быть, только я не знаю как им пользоваться. Это смешно, но я попробую, присоединяйтесь пожалуйста, кто хочет.
Кажется "bems" в  похожей теме мне помогал вместе с остальными участниками дискуссии:
http://forum.vingrad.ru/index.php?showtopi...t&p=2404095
PM MAIL WWW ICQ   Вверх
volatile
Дата 15.5.2013, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Jr13san @  14.5.2013,  07:12 Найти цитируемый пост)
что из за хуков возникают сильные лаги(задержки, подвисания). 

хех, начитались чего-то там...
в любом случае, это вообще ноль, по сравнению с вашим кодом, который нагружает процессор на все 100%
 smile 
Цитата(Jr13san @  10.5.2013,  19:59 Найти цитируемый пост)
    while(1)//реализуем бесконечный цикл
    {
        if (GetAsyncKeyState(VK_LWIN))//проверяем нажата ли Левая клавиша Windows, если да, то
        {
            printf("%s","Windows");//выводим сообщение
            Sleep(100);//делаем задержку на 100 мсек.
        }
    }


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


Эксперт
***


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

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



Цитата

Может тебе попробовать DirectInput?

DirectInput использует WM_INPUT

Цитата

DirectInput

DirectInput is a set of API calls that abstracts input devices on the system. Internally, DirectInput creates a second thread to read WM_INPUT data, and using the DirectInput APIs will add more overhead than simply reading WM_INPUT directly. DirectInput is only useful for reading data from DirectInput joysticks; however, if you only need to support the Xbox 360 controller for Windows, use XInput instead. Overall, using DirectInput offers no advantages when reading data from mouse or keyboard devices, and the use of DirectInput in these scenarios is discouraged.


http://msdn.microsoft.com/en-us/library/ee418864

Это сообщение отредактировал(а) Dem_max - 15.5.2013, 19:20


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


Бывалый
*


Профиль
Группа: Участник
Сообщений: 174
Регистрация: 29.7.2008
Где: г. Павлово

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



Вообщем нашёл и GlobalHook пример на С# и выяснил, что есть один косяк в одновременном нажатии 3-х кнопок, не знаю чей, но он есть. И GetAsyncKeyState также не справляется с одновременным нажатием(да даже и последовательным нажатием) некоторых комбинаций клавиш, хотя некоторые комбинации(пробовал до 5 штук одновременно) обрабатывает нормально.
Как пример, с помощью ниже прикреплённых исходников программы, нельзя отловить одновременное нажатие "G", "H", "7".
Исходники взял с сайта проекта "CodeProject"(прикреплены ниже).

Это сообщение отредактировал(а) Jr13san - 19.5.2013, 19:46

Присоединённый файл ( Кол-во скачиваний: 1 )
Присоединённый файл  globalhook_demo.zip 17,79 Kb
PM MAIL WWW ICQ   Вверх
volatile
Дата 19.5.2013, 23:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Jr13san @  19.5.2013,  19:40 Найти цитируемый пост)
косяк в одновременном нажатии 3-х кнопок, не знаю чей

Это косяк клавиатуры. т.е самого девайса.
Да и вообще это не косяк, а нормальное поведение.
PC клавиатура расчитана на последовательные нажатия, а вы видимо хотите испольнять на ней пятую симфонию Бетховена.  smile
Исключения составляют только комбинации с переключателями: ctrl, alt, shift, win

Цитата(Jr13san @  19.5.2013,  19:40 Найти цитируемый пост)
 "G", "H", "7".

Такие комбинации нормальная клавитура не обязана переваривать.
Если разбираетесь немного в электронике, просто полюбопытсвуйте внутренним устройством клавиатуры.
Там матрица, и при определенных комбинациях 3-ёх и более клавиш, там просто физически невозможно определить какие именно клавиши были нажаты. Причем невозможные комбинации, разняцца для разных моделей.
Короче, говоря языком С++, нажатие 3 клавиш одновременно, - это UB. 
Оно может и сработать иногда, но чаще - нет smile





Это сообщение отредактировал(а) volatile - 20.5.2013, 00:12
PM MAIL   Вверх
Jr13san
Дата 20.5.2013, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 174
Регистрация: 29.7.2008
Где: г. Павлово

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



Да нет, просто у меня старый пример был на одну кнопку рассчитан, и недавно я стал расширять возможности, хотя бы до 5 кнопок одновременно нажатых(это с небольшим запасом). И в итоге на win7 ничего не работает, вот приходится либо искать подсказки по "инжектингу" dll в процесс и ставить хуки, либо отступиться от этого всего и не париться больше. Мне вот просто ради интереса важно понять и попробовать сделать рабочий пример. На Youtube нашёл видео о том, как внедрить dll в процесс на c++ и от туда вызвать прорисовку синего прямоугольника при нажатии кнопки F1. Попробую, может что-то получится...

Вообщем на счёт клавиатуры ясно. Чем больше кнопок тебе нужно отследить одновременно, тем больше придётся паять дорожек. В принципе есть шина I2C с линией данных SDA и линией синхронизации SCL, может через них можно как-то это реализовать? Или просто пускай винда опрашивает клавиатуру и создаёт очередь нажатых кнопок. Если кнопка повторяется, то не пишем её в очередь, иначе записываем. А если кнопка отпущена, то удаляем её из очереди. Не знаю. Ну да ладно, это уже вопрос по аппаратной части.



Это сообщение отредактировал(а) Jr13san - 20.5.2013, 12:42
PM MAIL WWW ICQ   Вверх
volatile
Дата 20.5.2013, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Jr13san @  20.5.2013,  12:40 Найти цитируемый пост)
просто пускай винда опрашивает клавиатуру и создаёт очередь нажатых кнопок. 

Венда не опрашивает клавиатуру. В клавиатуре (обычной), есть свой микроконтроллер, который опрашивает матрицу кнопок.
и в случае нажатия, отправляет код нажатой клавиши в комп.
А венда (вообще операционка), уже переваривает этот код.
(для 3-ей и более кнопки одновременно (исключая ctrl, alt, shift, win), просто не будут поступать коды нажатых клавиш, от самой клавиатуры. 

Если же вы хотите делать свой клавиатурный девайс, то да можно делать все что угодно.
Но это уже совсем, совсем другая тема...


Это сообщение отредактировал(а) volatile - 20.5.2013, 13:28
PM MAIL   Вверх
Jr13san
Дата 21.5.2013, 08:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 174
Регистрация: 29.7.2008
Где: г. Павлово

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



Цитата

Если же вы хотите делать свой клавиатурный девайс, то да можно делать все что угодно.

Да, я загорелся идеей и в принципе кое-что придумал в связке с демультиплексорами. Наброски схемы уже есть. Осталось навести последние штрихи и можно начинать топить пластмассу smile и прокладывать провода smile 
Проблема в том, кто и как будет обрабатывать сигналы с клавиатуры? Я по крайней мере не знаю куда уходят 6 сигналов с обычной клавиатуры.. smile Но с другой стороны, в связке с микроконтроллером новая клавиатура работала бы.
Ладно, не буду оффтопить.

Нашёл простой исходничёк для работы с клавиатурой на сайте:
http://www.wischik.com/lu/programmer/keymouse.html
При нажатии на "правый Alt" происходит эмуляция нажатия на правую кнопку мышки.
Есть и исходник и готовая программка, которую нужно закрывать через диспетчер, потому что у неё нет формы.
Буду разбираться, может что-то и получится.

Это сообщение отредактировал(а) Jr13san - 24.5.2013, 12:18
PM MAIL WWW ICQ   Вверх
Jr13san
Дата 26.5.2013, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 174
Регистрация: 29.7.2008
Где: г. Павлово

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



Прощу прощения за дабл-постинг, но у меня есть один вопрос.
Начну с небольшого исходника, нарытого в недрах интернета:
Консольное приложение:
Код

#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <iostream>
#include <cstdio>
using namespace std;

HHOOK g_Hook;
HANDLE g_evExit;

LRESULT CALLBACK LowLevelMouseProc (int code, WPARAM wParam, LPARAM lParam)
{
    if (code == HC_ACTION)
    {
        const char *msg;
        char msg_buff[128];
        switch (wParam)
        {
            case WM_LBUTTONDOWN: msg = "WM_LBUTTONDOWN"; break;
            case WM_LBUTTONUP: msg = "WM_LBUTTONUP"; break;
            case WM_MOUSEWHEEL: msg = "zDelta = "; break;
            case WM_RBUTTONDOWN: msg = "WM_RBUTTONDOWN"; break;
            case WM_RBUTTONUP: msg = "WM_RBUTTONUP"; break;
            default: 
                sprintf(msg_buff, "Unknown msg: %u", wParam); 
                msg = msg_buff;
                break;
        }//switch

        cout << msg << wParam << endl;

        static bool left_down = false;
        static bool right_down = false;
        switch (wParam)
        {
            case WM_LBUTTONDOWN: left_down = true; break;
            case WM_LBUTTONUP:   left_down = false; break;
            case WM_RBUTTONDOWN: right_down = true; break;
            case WM_RBUTTONUP:   right_down = false; break;
        }//switch
        
        if (left_down && right_down)
            SetEvent(g_evExit);
    }//if

    return CallNextHookEx(g_Hook, code, wParam, lParam); 
}//LowLevelMouseProc


int main()
{
    g_evExit = CreateEvent(0, TRUE, FALSE, 0);
    if (!g_evExit)
    {
        cerr << "CreateEvent failed, le = " << GetLastError() << endl;
        return 1;
    }//if

    g_Hook = SetWindowsHookEx(WH_MOUSE_LL, &LowLevelMouseProc, 
                              GetModuleHandle(0), 0);
    if (!g_Hook)
    {
        cerr << "SetWindowsHookEx() failed, le = " << GetLastError() << endl;
        return 1;
    }//if

    cout << "Press both left and right mouse buttons to exit..." << endl;

    MSG msg;
    DWORD status;
    while (1)
    {
        while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
            DispatchMessage(&msg);

        status = MsgWaitForMultipleObjects(1, &g_evExit, FALSE, 
                                           INFINITE, QS_ALLINPUT);
        if (status == (WAIT_OBJECT_0 + 1))
        {
            // there are messages to process, eat em up
            continue;
        }//if
        else
        {
            // assume g_evExit is signaled
            break;
        }//else
    }//while
    
    cout << "Exiting..." << endl;
    UnhookWindowsHookEx(g_Hook);
    CloseHandle(g_evExit);
    return 0;
}//main

Значит ставится хук на события мышки и вообщем-то они отрабатывают на ура, НО мне потребовалось отследить, то, в какую сторону происходит вращение колёсика мышки. И как на зло wParam всегда возвращает одно и то же значение не зависимо от стороны вращения колеса мышки. Т.е. хоть преобразуй с помощью макроса "GET_WHEEL_DELTA_WPARAM(wParam)", хоть не преобразуй - результат один и тот же.
Помогите пожалуйста. Весь интернет перерыл, пока что ничего не помогает.

Это сообщение отредактировал(а) Jr13san - 26.5.2013, 12:18
PM MAIL WWW ICQ   Вверх
volatile
Дата 26.5.2013, 19:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Jr13san @  26.5.2013,  12:16 Найти цитируемый пост)
Помогите пожалуйста. Весь интернет перерыл, пока что ничего не помогает.

зачем весь интернет? достаточно MSDN
учитесь пользовацца. у меня вот тоже не было готового ответа
решение такое:
Код

            case WM_MOUSEWHEEL: 
            {
               PMSLLHOOKSTRUCT p = (PMSLLHOOKSTRUCT) lParam;
               cout << "zDelta = " << GET_WHEEL_DELTA_WPARAM (p->mouseData) << endl;
               break;
            }

Выдает 120 при кручении в одну сторону и -120 в другую.

кроме того у вас здесь очень нехорошо, надо добавить:

Цитата(Jr13san @  26.5.2013,  12:16 Найти цитируемый пост)
        const char *msg;
        char msg_buff[128];
        msg_buff [0] = 0;
        msg = msg_buff;

        switch (wParam)
        {


PM MAIL   Вверх
Jr13san
Дата 26.5.2013, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 174
Регистрация: 29.7.2008
Где: г. Павлово

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



volatile, круто! Спасибо за помощь!
По крайней мере я догадывался, что нужно делать какое-то хитрое преобразование, похожее на получение координат, когда происходит событие WM_MOUSEMOVE:
Код

const MSLLHOOKSTRUCT *p = 
            reinterpret_cast<const MSLLHOOKSTRUCT*>(lParam);
        cout << msg << " - [" << p->pt.x << ',' << p->pt.y << ']' << endl;

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

Это сообщение отредактировал(а) Jr13san - 26.5.2013, 21:48
PM MAIL WWW ICQ   Вверх
KaZepKa
Дата 27.5.2013, 08:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Дабы не создавать новую темку, спрошу тут:
Через WH_MOUSE_LL можно ли ловить зажим какой-нить кнопки мыши? Вот если хукать клаву(WH_KEYBOARD_LL),  зажим ловиться через
Код

if(nCode==HC_ACTION && p->vkCode==0x45 && (wParam==WM_KEYDOWN || wParam==WM_SYSKEYDOWN))

т.е. если зажал кнопку E, то действия после if повторяются, пока не отожмешь кнопку.
А вот если хукать мышь(например, среднюю кнопку мыши):
Код

if(nCode==HC_ACTION && wParam==WM_MBUTTONDOWN)

Действие выполняется только один раз при нажатии на эту кнопку, но не зажимает. Так вот, как правильно хукнуть в таком случае?)

Это сообщение отредактировал(а) KaZepKa - 27.5.2013, 08:55
PM MAIL   Вверх
Dem_max
Дата 27.5.2013, 09:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата

Действие выполняется только один раз при нажатии на эту кнопку

Все верно, тебе же сообщение пришло о нажатии, тебе чего еще нужно то ???


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


Новичок



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

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



Цитата(Dem_max @  27.5.2013,  10:04 Найти цитируемый пост)
Все верно, тебе же сообщение пришло о нажатии, тебе чего еще нужно то ??? 

по идеи да, но при зажатии кнопки на клавиатуре, почему-то действия повторяются, а в случаи с мышью такого нет...

Получилось реализовать зажим, через таймер: при WM_MBUTTONDOWN, активирую таймер, при WM_MBUTTONUP разрушаю, а нужные действия произвожу при отлове WM_TIMER. Так, правильно или есть более ровные способы?)
PM MAIL   Вверх
volatile
Дата 27.5.2013, 16:37 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(KaZepKa @  27.5.2013,  08:53 Найти цитируемый пост)
Вот если хукать клаву

Цитата(KaZepKa @  27.5.2013,  09:13 Найти цитируемый пост)
при зажатии кнопки на клавиатуре, почему-то действия повторяются, а в случаи с мышью такого нет...

KaZepKa, а причем здесь вообще хуки?
Клавиатура повторяет нажатую клавишу, делает это кстати, сам девайс. Задержку перед повтором и частоту можно регулировать.
Сделано это, для удобства, например набрать такст типа "---------------------------------------" довольно просто.
У мыши такого нет, потому-что, а нафига?



PM MAIL   Вверх
Jr13san
Дата 27.5.2013, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 174
Регистрация: 29.7.2008
Где: г. Павлово

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



KaZepKa, а ты введи переменную(ые) или массив в качестве флагов нажатых кнопок.
Приведу небольшой пример кода, но там сделано только на две клавиатурных клавиши. Но можно сделать по аналогии для всех и для мышки тоже.
Win32 Application:
Код

bool keys[256];

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)

    PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;

        FILE * pFile;
          pFile = fopen ("myfile.txt","a+");
          if (pFile!=NULL)
          {
            if (nCode==HC_ACTION)
            {
                switch (p->vkCode)
                {
                    case VK_LWIN:
                        if (keys[p->scanCode]==0 && wParam==WM_KEYDOWN || wParam==WM_SYSKEYDOWN)
                        {
                            fputs ("LWin-DOWN ",pFile);
                            keys[p->scanCode] = 1;
                        }
                        else if (keys[p->scanCode]==1 && wParam==WM_KEYUP || wParam==WM_SYSKEYUP)
                        {
                            fputs ("LWin-UP ",pFile);
                            keys[p->scanCode] = 0;
                        }
                        break;

                    case VK_SPACE:
                        if (keys[p->scanCode]==0 && wParam==WM_KEYDOWN || wParam==WM_SYSKEYDOWN)
                        {
                            fputs ("Space-DOWN ",pFile);
                            keys[p->scanCode] = 1;
                        }
                        else if (keys[p->scanCode]==1 && wParam==WM_KEYUP || wParam==WM_SYSKEYUP)
                        {
                            fputs ("Space-UP ",pFile);
                            keys[p->scanCode] = 0;
                        }
                        break;
                }

            }
            fclose (pFile);
          }
    
    MessageBeep(1);
  return CallNextHookEx(0,nCode,wParam,lParam);
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ if (msg==WM_DESTROY) PostQuitMessage(0);
  return DefWindowProc(hwnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR,int)

    
  HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInstance, 0);
  WNDCLASSEX wcex; ZeroMemory(&wcex,sizeof(wcex)); wcex.cbSize=sizeof(WNDCLASSEX);
  wcex.lpfnWndProc=(WNDPROC)WndProc; wcex.hInstance=hInstance; wcex.lpszClassName=L"KeyMouseClass";
  RegisterClassEx(&wcex);
  CreateWindowEx(WS_EX_NOACTIVATE,L"KeyMouseClass", L"KeyMouse",WS_POPUP|WS_VISIBLE,0,0,0,0,0,0,hInstance,0);
  MSG msg;
  while (GetMessage(&msg, NULL, 0, 0)) {TranslateMessage(&msg); DispatchMessage(&msg);}

  UnhookWindowsHookEx(hook);
  return (int)msg.wParam;
}



Это сообщение отредактировал(а) Jr13san - 27.5.2013, 16:57
PM MAIL WWW ICQ   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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