Blog. Just Blog

Перехват и обработка изменения курсора

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Закрепим материал по системным событиям. В сегодняшнем примере отработаем перехват изменения формы курсора. Начнем с описания отсутствующих структур и констант, которые будут использоваться в нашем коде.
  1. struct CURSORINFO
  2.     cbSize      dd ?
  3.     flags       dd ?
  4.     hCursor     dd ?
  5.     ptScreenPos POINT
  6. ends
  7.  
  8. EVENT_OBJECT_NAMECHANGE = 0x800C
  9. WINEVENT_OUTOFCONTEXT   = 0x0000
  10. OBJID_CURSOR            = 0xFFFFFFF7
Затем, как и в предыдущем примере, устанавливаем хук на системные события. В зависимости от ситуации, сделать это можно при инициализации приложения или в какой-нибудь другой определенный вами момент.
  1.         ; Установить хук на системные события
  2.         invoke  SetWinEventHook,EVENT_OBJECT_NAMECHANGE,\
  3.                 EVENT_OBJECT_NAMECHANGE,NULL,WinEventProc,\
  4.                 0,0,WINEVENT_OUTOFCONTEXT
Ну и сам обработчик системного события. Тут первым делом проверяется, что изменившийся объект является курсором, потом на всякий случай проверяем тип события, если их планируется несколько. Вся необходимая информация об изменившемся курсоре получается при помощи функции GetCursorInfo. Это хэндл нового курсора, его координаты и флаги отображения.
  1. proc WinEventProc hWinEventHook:DWORD, event:DWORD, hwnd:DWORD,\
  2.                   idObject:DWORD, idChild:DWORD, idEventThread:DWORD,\
  3.                   dwmsEventTime:DWORD
  4.         pusha
  5.         ; Изменяемый объект - курсор?
  6.         cmp     [idObject],OBJID_CURSOR
  7.         jne     .loc_ret
  8.  
  9.         ; Курсор изменяется?
  10.         cmp     [event],EVENT_OBJECT_NAMECHANGE
  11.         jne     .loc_ret
  12.  
  13.         ; Получить инфомрацию о курсоре
  14.         mov     [pci.cbSize],sizeof.CURSORINFO
  15.         invoke  GetCursorInfo,pci
  16.         ; Курсор изменился?
  17.         mov     eax,[pci.hCursor]
  18.         cmp     eax,[hCursor]
  19.         ; Нет, пропустить
  20.         je      .loc_ret
  21.         ; Да, сохранить хэндл нового курсора
  22.         mov     [hCursor],eax
  23.         ; В структуре CURSORINFO содержится информация о курсоре
  24.         ...
  25.         ...
  26. .loc_ret:
  27.         popa
  28.         ret
  29. endp
В обработчике проверяется хэндл старого и нового курсора, так как система щедро сыплет событиями даже когда курсор просто стоит на месте. Обработчик реагирует только когда хэндл курсора изменился, то есть изменилась его форма. Что интересно, хэндл курсора, возвращаемый в структуре CURSORINFO, не совпадает со стандартными хэндлами курсоров. Объяснить причину такого поведения системы я не могу. Если вам это необходимо, то можно составить табличку соответствия.

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

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

Cursor.Hook.Demo.zip (2,903 bytes)


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

Метки: Assembler
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
toor (14.09.2021 в 07:58):
имелось ввиду программно, на определенное время.

Например как в программах Window Detective или Process Explorer, когда выбирается окно при помощи курсора-мишени.

Курсор меняется функцией SetSystemCursor, а восстанавливается SystemParametersInfo(SPI_SETCURSORS, 0, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE)

А вот между вызовами этих методов, пока не выбрано нужное окно, нужно запретить изменять курсор. Гугление пока не дало положительных результатов...
ManHunter (13.09.2021 в 20:17):
Поставь в настройках мыши на все случаи одинаковый курсор
toor (13.09.2021 в 19:42):
Я не знаете, можно ли каким то образом запретить изменение курсора?

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

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

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