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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Функция "GetAsyncKeyState" отрабатывает выборочно. 
V
    Опции темы
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   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

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

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

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

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


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

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


 




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


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

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