Blog. Just Blog

Как узнать количество подключенных к компьютеру мышек

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Как узнать количество подключенных к компьютеру мышек
Как узнать количество подключенных к компьютеру мышек

Даже если я работаю на ноутбуке, обязательно подключаю к нему мышь и полноразмерную клавиатуру. Работать на тачпаде могу только в самых крайних случаях. И как-то раз я подумал: курсор можно двигать через тачпад, можно при помощи мыши, можно даже подключить сразу несколько мышей. А вот как узнать, какое количество мышей подключено к компьютеру? Вопрос, как и ответ на него, на первый взгляд кажется бесполезным. Но таким образом мы научимся работать со списком устройств в системе, а также обрабатывать ситуации, когда у пользователя действительно может не оказаться подключенных мышек. В этом случае ваше приложение должно предупреждать пользователя об ограничении функционала или взаимодействовать с пользователем, учитывая максимальное использование клавиатуры.

Теоретически факт наличия подключенной мыши можно определить, вызвав функцию GetSystemMetrics с параметром SM_MOUSEPRESENT. Но эта функция не дает ответ на основной вопрос, решаемый в статье, а главное, может возвращать неправильный результат при наличии в системе различных эмуляторов устройств ввода.

Для получения списка подключенных устройств используются функции Setup API. Их очень много, несколько сотен, из всего этого разнообразия нас интересуют лишь несколько. Но сперва несколько констант и структур, которые нам понадобятся для работы, но про которые не знает FASM.
  1. DIGCF_PRESENT    = 2
  2. DIGCF_ALLCLASSES = 4
  3.  
  4. SPDRP_DEVICEDESC = 0
  5. SPDRP_HARDWAREID = 1
  6. SPDRP_LOCATION_INFORMATION = 13
  7.  
  8. ; GUID {4D36E96F-E325-11CE-BFC1-08002BE10318}
  9. GUID_DEVCLASS_MOUSE \
  10.     dd 04D36E96Fh
  11.     dw 0E325h
  12.     dw 011CEh
  13.     db 0BFh, 0C1h, 008h, 000h, 02Bh, 0E1h, 003h, 018h
  14.  
  15. struct SP_DEVINFO_DATA
  16.         cbSize dd ?
  17.         ClassGuid rb 16
  18.         DevInst dd ?
  19.         Reserved dd ?
  20. ends
Теперь немного теории, как в общем виде можно получить список всех устройств. Первым шагом надо получить хэндл списка всех устройств при помощи функции SetupDiGetClassDevs. Выделять память под список не требуется, об этом позаботится система. Затем этот список перебираем при помощи функции SetupDiEnumDeviceInfo, указывая поочередно индекс устройства, начиная с нулевого. В случае успеха функция вернет заполненную структуру SP_DEVINFO_DATA для каждого устройства. Если вызов закончился неудачей, значит подключенных устройств нет и перебор надо заканчивать. На основании данных структуры SP_DEVINFO_DATA можно получить всю интересующую информацию об устройстве, для этого используется функция SetupDiGetDeviceRegistryProperty. Всего доступны несколько десятков типов данных, в нашем примере будет достаточно названия устройства, места его подключения и идентификатора производителя. Когда все устройства из списка будут обработаны, надо освободить выделенную память при помощи функции SetupDiDestroyDeviceInfoList.
  1.         ; Получить список всех устройств, фактически
  2.         ; подключенных к компьютеру
  3.         invoke  SetupDiGetClassDevs,NULL,NULL,NULL,\
  4.                 DIGCF_PRESENT+DIGCF_ALLCLASSES
  5.         mov     [DeviceInfoSet],eax
  6.  
  7.         ; Начать перебор с первого устройства
  8.         mov     [index],0
  9.  
  10. loc_loop:
  11.         ; Подготовить структуру и очистить строки
  12.         mov     [DeviceInfoData.cbSize],sizeof.SP_DEVINFO_DATA
  13.  
  14.         invoke  RtlZeroMemory,devname,100h
  15.         invoke  RtlZeroMemory,location,100h
  16.         invoke  RtlZeroMemory,hwid,100h
  17.  
  18.         ; Получить информацию об очередном устройстве
  19.         invoke  SetupDiEnumDeviceInfo,[DeviceInfoSet],\
  20.                 [index],DeviceInfoData
  21.         or      eax,eax
  22.         ; Устройств больше нет
  23.         jz      loc_done
  24.  
  25.         ; Наименование устройства
  26.         invoke  SetupDiGetDeviceRegistryProperty,\
  27.                 [DeviceInfoSet],DeviceInfoData,\
  28.                 SPDRP_DEVICEDESC,\
  29.                 NULL,devname,100h,NULL
  30.  
  31.         ; Место подключение устройства
  32.         invoke  SetupDiGetDeviceRegistryProperty,\
  33.                 [DeviceInfoSet],DeviceInfoData,\
  34.                 SPDRP_LOCATION_INFORMATION,\
  35.                 NULL,location,100h,NULL
  36.  
  37.         ; Производитель устройства
  38.         invoke  SetupDiGetDeviceRegistryProperty,\
  39.                 [DeviceInfoSet],DeviceInfoData,\
  40.                 SPDRP_HARDWAREID,\
  41.                 NULL,hwid,100h,NULL
  42.  
  43.         ; Следующее устройство
  44.         inc     [index]
  45.         jmp     loc_loop
  46. loc_done:
  47.         ; Прибраться за собой
  48.         invoke  SetupDiDestroyDeviceInfoList,[DeviceInfoSet]
Но это код для получения полного списка устройств. Чтобы получить информацию о конкретном типе устройств, в нашем случае мышек, при вызове функции SetupDiGetClassDevs требуется уточнить категорию устройств. Код изменится на следующий:
  1.         ; Получить список устройств типа "мышь", фактически
  2.         ; подключенных к компьютеру
  3.         invoke  SetupDiGetClassDevs,GUID_DEVCLASS_MOUSE,\
  4.                 NULL,NULL,DIGCF_PRESENT
Все остальное без изменений. Теперь мы можем точно ответить на вопрос, поставленный в начале статьи. Для динамического отслеживания изменения конфигурации оборудования было бы правильным еще обрабатывать сообщение WM_DEVICECHANGE и соответствующим образом реагировать на подключение или отключение мышек.

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

Примеры программ с исходными текстами (FASM)Примеры программ с исходными текстами (FASM)

Get.Devices.List.Demo.zip (6,578 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 332 | Комментариев: 0

Метки: Assembler

Комментарии

Отзывы посетителей сайта о статье
Комментариeв нет

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2025
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0032 сек.) / Память: 4.5 Mb
Наверх