Управление индикаторами на USB-клавиатуре
От: Аноним  
Дата: 26.11.08 20:41
Оценка:
Есть USB-клавиатура. Требуется программно зажигать индикаторы Caps Lock, Scroll Lock и/или Num Lock. Нагуглил когда-то одно решение, но так понял, что оно только для PS/2 клавиатур. Программно эмулировать нажатие соответствующих клавиш, думаю, не подойдёт, потому что нажатие, например, Caps Lock всегда будет перехвачено системой и сами понимаете что будет. В какую сторону копать?
клавиатура keyboard индикаторы led caps lock
Re: Управление индикаторами на USB-клавиатуре
От: Andrew S Россия http://alchemy-lab.com
Дата: 26.11.08 23:06
Оценка:
А>Есть USB-клавиатура. Требуется программно зажигать индикаторы Caps Lock, Scroll Lock и/или Num Lock. Нагуглил когда-то одно решение, но так понял, что оно только для PS/2 клавиатур. Программно эмулировать нажатие соответствующих клавиш, думаю, не подойдёт, потому что нажатие, например, Caps Lock всегда будет перехвачено системой и сами понимаете что будет. В какую сторону копать?

Это? http://www.rsdn.ru/Forum/Message.aspx?mid=1357795&only=1
Автор: Ямаха.
Дата: 01.09.05
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[2]: Управление индикаторами на USB-клавиатуре
От: Аноним  
Дата: 27.11.08 13:30
Оценка:
Здравствуйте, Andrew S, Вы писали:

А>>Есть USB-клавиатура. Требуется программно зажигать индикаторы Caps Lock, Scroll Lock и/или Num Lock. Нагуглил когда-то одно решение, но так понял, что оно только для PS/2 клавиатур. Программно эмулировать нажатие соответствующих клавиш, думаю, не подойдёт, потому что нажатие, например, Caps Lock всегда будет перехвачено системой и сами понимаете что будет. В какую сторону копать?


AS>Это? http://www.rsdn.ru/Forum/Message.aspx?mid=1357795&only=1
Автор: Ямаха.
Дата: 01.09.05


Да, вот это решение на моей USB-клавиатуре не работает
Re[3]: Управление индикаторами на USB-клавиатуре
От: Andrew S Россия http://alchemy-lab.com
Дата: 27.11.08 18:19
Оценка:
А>>>Есть USB-клавиатура. Требуется программно зажигать индикаторы Caps Lock, Scroll Lock и/или Num Lock. Нагуглил когда-то одно решение, но так понял, что оно только для PS/2 клавиатур. Программно эмулировать нажатие соответствующих клавиш, думаю, не подойдёт, потому что нажатие, например, Caps Lock всегда будет перехвачено системой и сами понимаете что будет. В какую сторону копать?

AS>>Это? http://www.rsdn.ru/Forum/Message.aspx?mid=1357795&only=1
Автор: Ямаха.
Дата: 01.09.05


А>Да, вот это решение на моей USB-клавиатуре не работает


Скорее всего, другое название устройства. Я думаю, самый правильный вариант — попробовать получить хендл устройства клавиатуры при помощи SetupApi.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[4]: Управление индикаторами на USB-клавиатуре
От: Аноним  
Дата: 30.11.08 08:16
Оценка:
Здравствуйте, Andrew S, Вы писали:

А>>>>Есть USB-клавиатура. Требуется программно зажигать индикаторы Caps Lock, Scroll Lock и/или Num Lock. Нагуглил когда-то одно решение, но так понял, что оно только для PS/2 клавиатур. Программно эмулировать нажатие соответствующих клавиш, думаю, не подойдёт, потому что нажатие, например, Caps Lock всегда будет перехвачено системой и сами понимаете что будет. В какую сторону копать?


AS>>>Это? http://www.rsdn.ru/Forum/Message.aspx?mid=1357795&only=1
Автор: Ямаха.
Дата: 01.09.05


А>>Да, вот это решение на моей USB-клавиатуре не работает


AS>Скорее всего, другое название устройства. Я думаю, самый правильный вариант — попробовать получить хендл устройства клавиатуры при помощи SetupApi.


Ты не мог бы рассказать о SetupApi чуть поподробнее, какие функции смотреть, например. Я с ним совсем не знаком.
Re[5]: Управление индикаторами на USB-клавиатуре
От: Andrew S Россия http://alchemy-lab.com
Дата: 01.12.08 17:43
Оценка:
А>>>>>Есть USB-клавиатура. Требуется программно зажигать индикаторы Caps Lock, Scroll Lock и/или Num Lock. Нагуглил когда-то одно решение, но так понял, что оно только для PS/2 клавиатур. Программно эмулировать нажатие соответствующих клавиш, думаю, не подойдёт, потому что нажатие, например, Caps Lock всегда будет перехвачено системой и сами понимаете что будет. В какую сторону копать?

AS>>>>Это? http://www.rsdn.ru/Forum/Message.aspx?mid=1357795&only=1
Автор: Ямаха.
Дата: 01.09.05


А>>>Да, вот это решение на моей USB-клавиатуре не работает


AS>>Скорее всего, другое название устройства. Я думаю, самый правильный вариант — попробовать получить хендл устройства клавиатуры при помощи SetupApi.


А>Ты не мог бы рассказать о SetupApi чуть поподробнее, какие функции смотреть, например. Я с ним совсем не знаком.


Попродробнее — в MSDN.
Вкратце — надо пронумерить устройства нужного класса (в данном случае — клавиатура), затем для каждого устройства попробовать получить нужный интерфейс (SetupDiEnumDeviceInterfaces), ну и наконец, получить искомый путь к устройству (SetupDiGetDeviceInterfaceDetail). Получится или нет — в данном случае неизвестно, но попробуйте, вероятность есть.
А для начала я бы просто посмотрел, какие нативные имена зарегистрированы, если нашлось бы подходящее — попробовал бы его. Если заработает код, указанный в предыдущих сообщениях — тогда бы уже и стал ковырять, как это имя правильно получить. Тем более, что клавиатура может быть не одна.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[6]: Управление индикаторами на USB-клавиатуре
От: Аноним  
Дата: 02.12.08 15:56
Оценка:
Здравствуйте, Andrew S, Вы писали:

А>>>>>>Есть USB-клавиатура. Требуется программно зажигать индикаторы Caps Lock, Scroll Lock и/или Num Lock. Нагуглил когда-то одно решение, но так понял, что оно только для PS/2 клавиатур. Программно эмулировать нажатие соответствующих клавиш, думаю, не подойдёт, потому что нажатие, например, Caps Lock всегда будет перехвачено системой и сами понимаете что будет. В какую сторону копать?


AS>>>>>Это? http://www.rsdn.ru/Forum/Message.aspx?mid=1357795&only=1
Автор: Ямаха.
Дата: 01.09.05


А>>>>Да, вот это решение на моей USB-клавиатуре не работает


AS>>>Скорее всего, другое название устройства. Я думаю, самый правильный вариант — попробовать получить хендл устройства клавиатуры при помощи SetupApi.


А>>Ты не мог бы рассказать о SetupApi чуть поподробнее, какие функции смотреть, например. Я с ним совсем не знаком.


AS>Попродробнее — в MSDN.

AS>Вкратце — надо пронумерить устройства нужного класса (в данном случае — клавиатура), затем для каждого устройства попробовать получить нужный интерфейс (SetupDiEnumDeviceInterfaces), ну и наконец, получить искомый путь к устройству (SetupDiGetDeviceInterfaceDetail). Получится или нет — в данном случае неизвестно, но попробуйте, вероятность есть.
AS>А для начала я бы просто посмотрел, какие нативные имена зарегистрированы, если нашлось бы подходящее — попробовал бы его. Если заработает код, указанный в предыдущих сообщениях — тогда бы уже и стал ковырять, как это имя правильно получить. Тем более, что клавиатура может быть не одна.

Спасибо за подсказку. Я попробовал, но никаких устройств мой код не находит (SetupDiEnumDeviceInterfaces постоянно возвращает FALSE, в GetLastError() — ERROR_NO_MORE_ITEMS).

#include <windows.h>

#include <setupapi.h>
#pragma comment(lib, "setupapi")

#include <vector>
using namespace std;


/*
Здесь константы, которые взял из того кода, и те, которые сам отыскал в Google.
Кто знает, может дело в них?
*/


vector<HANDLE> g_devices;


void collectDevicesByInterface(HDEVINFO di, const GUID * guid_devinterface) {
    SP_DEVICE_INTERFACE_DATA did = { sizeof(did) };
    for (DWORD i = 0; SetupDiEnumDeviceInterfaces(di, NULL, guid_devinterface, i, &did); ++i) {        
        
        DWORD detailsSize;
        if (!SetupDiGetDeviceInterfaceDetail(di, &did, NULL, 0, &detailsSize, NULL))
            continue;

        vector<BYTE> details_(detailsSize);
        SP_DEVICE_INTERFACE_DETAIL_DATA * details = reinterpret_cast<SP_DEVICE_INTERFACE_DETAIL_DATA *>(&details_[0]);
        details->cbSize = sizeof(*details);
        if (!SetupDiGetDeviceInterfaceDetail(di, &did, details, detailsSize, &detailsSize, NULL))
            continue;        

        HANDLE h = CreateFile(details->DevicePath, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
        if (h == INVALID_HANDLE_VALUE)
            continue;

        g_devices.push_back(h);
    }
}

void collectDevices(const GUID * guid_devclass) {

    HDEVINFO di = SetupDiGetClassDevs(guid_devclass, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
    if (di == INVALID_HANDLE_VALUE)
        return;

    collectDevicesByInterface(di, &GUID_DEVINTERFACE_HID);
    collectDevicesByInterface(di, &GUID_DEVINTERFACE_KEYBOARD);
    
    SetupDiDestroyDeviceInfoList(di);
}

int main() {

    collectDevices(&GUID_DEVCLASS_HIDCLASS);
    collectDevices(&GUID_DEVCLASS_KEYBOARD);
    
    if (g_devices.empty())
        return 0;

    KEYBOARD_INDICATOR_PARAMETERS InputBuffer = {1};
    for (int i = 1; ; ++i) {
        InputBuffer.LedFlags = i & 7;
        DWORD xx;

        for (size_t i = 0; i < g_devices.size(); ++i)
            DeviceIoControl(g_devices[i], IOCTL_KEYBOARD_SET_INDICATORS, &InputBuffer, sizeof(KEYBOARD_INDICATOR_PARAMETERS), 0, 0, &xx, 0);
        
        Sleep(500);
    }

    for (size_t i = 0; i < g_devices.size(); ++i)
        CloseHandle(g_devices[i]);

    return 0;
}


Подозрение падает на константы GUID_*, которые я нашёл в поисковике... Но может что-нибудь ещё не так?
Re[7]: Управление индикаторами на USB-клавиатуре
От: Andrew S Россия http://alchemy-lab.com
Дата: 02.12.08 18:30
Оценка:
AS>>Попродробнее — в MSDN.
AS>>Вкратце — надо пронумерить устройства нужного класса (в данном случае — клавиатура), затем для каждого устройства попробовать получить нужный интерфейс (SetupDiEnumDeviceInterfaces), ну и наконец, получить искомый путь к устройству (SetupDiGetDeviceInterfaceDetail). Получится или нет — в данном случае неизвестно, но попробуйте, вероятность есть.
AS>>А для начала я бы просто посмотрел, какие нативные имена зарегистрированы, если нашлось бы подходящее — попробовал бы его. Если заработает код, указанный в предыдущих сообщениях — тогда бы уже и стал ковырять, как это имя правильно получить. Тем более, что клавиатура может быть не одна.

А>Спасибо за подсказку. Я попробовал, но никаких устройств мой код не находит (SetupDiEnumDeviceInterfaces постоянно возвращает FALSE, в GetLastError() — ERROR_NO_MORE_ITEMS).


А>Подозрение падает на константы GUID_*, которые я нашёл в поисковике... Но может что-нибудь ещё не так?


Вроде все нормально. Единственно, можно попробовать перечислить все интерфейсы (передать в guid InterfaceClassGuid енума NULL).
В любом случае — возьмите WinObj и посмотрите — может, есть какие подозрительные символьные имена.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[8]: Управление индикаторами на USB-клавиатуре
От: Аноним  
Дата: 04.12.08 09:07
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>>>Попродробнее — в MSDN.

AS>>>Вкратце — надо пронумерить устройства нужного класса (в данном случае — клавиатура), затем для каждого устройства попробовать получить нужный интерфейс (SetupDiEnumDeviceInterfaces), ну и наконец, получить искомый путь к устройству (SetupDiGetDeviceInterfaceDetail). Получится или нет — в данном случае неизвестно, но попробуйте, вероятность есть.
AS>>>А для начала я бы просто посмотрел, какие нативные имена зарегистрированы, если нашлось бы подходящее — попробовал бы его. Если заработает код, указанный в предыдущих сообщениях — тогда бы уже и стал ковырять, как это имя правильно получить. Тем более, что клавиатура может быть не одна.

А>>Спасибо за подсказку. Я попробовал, но никаких устройств мой код не находит (SetupDiEnumDeviceInterfaces постоянно возвращает FALSE, в GetLastError() — ERROR_NO_MORE_ITEMS).


А>>Подозрение падает на константы GUID_*, которые я нашёл в поисковике... Но может что-нибудь ещё не так?


AS>Вроде все нормально. Единственно, можно попробовать перечислить все интерфейсы (передать в guid InterfaceClassGuid енума NULL).

AS>В любом случае — возьмите WinObj и посмотрите — может, есть какие подозрительные символьные имена.

С NULL абсолютно то же самое...

Опробовал WinObj. Присутствуют устройства KeyboardClass0 и KeyboardClass1... Выходит, все попытки использовать SetupApi были для меня напрасны...

Я тут ещё поэкспериментировал на клавиатурах знакомых. Похоже, что виноват DeviceIoControl и IOCTL_KEYBOARD_SET_INDICATORS, который видимо работает только для PS/2 клавиатур. На самом деле, мне несколько месяцев назад приходилось уже обращать внимание на управление клавиатурными индикаторами, я даже нашёл ссылку, но не уделил ей достаточно внимания. Пришлось найти её снова:

http://mamedev.org/source/src/osd/windows/ledutil.c.html

Не зря же они для USB и PS/2 используют разные способы! Способ с посылкой нажатия клавиш мне очень мало подходит, но видимо всё-таки придётся использовать его для USB-клавиатур...

Вам огромное спасибо за помощь!
Re[9]: Управление индикаторами на USB-клавиатуре
От: Andrew S Россия http://alchemy-lab.com
Дата: 05.12.08 06:39
Оценка:
А>Опробовал WinObj. Присутствуют устройства KeyboardClass0 и KeyboardClass1... Выходит, все попытки использовать SetupApi были для меня напрасны...

Ну, я ж предупреждал — посмотрите сначала уже известные объекты

А>Я тут ещё поэкспериментировал на клавиатурах знакомых. Похоже, что виноват DeviceIoControl и IOCTL_KEYBOARD_SET_INDICATORS, который видимо работает только для PS/2 клавиатур. На самом деле, мне несколько месяцев назад приходилось уже обращать внимание на управление клавиатурными индикаторами, я даже нашёл ссылку, но не уделил ей достаточно внимания. Пришлось найти её снова:


А>http://mamedev.org/source/src/osd/windows/ledutil.c.html


А>Не зря же они для USB и PS/2 используют разные способы! Способ с посылкой нажатия клавиш мне очень мало подходит, но видимо всё-таки придётся использовать его для USB-клавиатур...


Ну, просто не нашли способа управлять по-другому. Но это не значит, что его нет... Может, кроме KeyboardClass есть еще какие подозрительные имена?

А>Вам огромное спасибо за помощь!


Да не за что, жаль, что ничего нового не обнаружилось.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[10]: Управление индикаторами на USB-клавиатуре
От: Аноним  
Дата: 05.12.08 13:57
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Ну, просто не нашли способа управлять по-другому. Но это не значит, что его нет... Может, кроме KeyboardClass есть еще какие подозрительные имена?


К сожалению нет
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.