Уведомления об изменении курсора

Можно ли получать уведомления об изменении курсора мыши? Меня интересуют изменения, вызванные моим процессом, но общесистемное уведомление было бы так же хорошо. Поскольку я использую сторонние библиотеки, может быть несколько причин изменения курсора.

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

Мое текущее решение - проверить, совпадает ли курсор мыши с LoadCursor(nullptr, IDC_HAND). Однако:

  • Может ли это быть причиной утечки ресурсов? документация for LoadCursor указывает, что если ресурс уже существует, то вместо нового ресурса возвращается ссылка на указанный ресурс. Поэтому кажется, что я не должен пытаться отпустить ручку.
  • Дорого ли выполнять эту проверку часто, так как LoadCursor будет вызываться много раз?
  • Должен ли я кэшировать курсор IDC_HAND? Если он не существует, когда я выполняю LoadCursor, когда создается курсор в виде руки, обязательно ли он будет иметь тот же самый дескриптор? Судя по моим тестам, да.

Насколько я могу судить, идеальным сценарием является наличие сообщения Windows, указывающего на изменение курсора, на каком этапе я мог бы выполнить проверку дескриптора LoadCursor. Возможно есть альтернативы?

Спасибо за ваше время и помощь.


person Pooven    schedule 07.03.2015    source источник
comment
Вы можете использовать обход, чтобы перехватить SetCursor().   -  person Remy Lebeau    schedule 07.03.2015
comment
Система загружает IDC_HAND при запуске, поэтому ваш вызов просто получит ссылку на существующий курсор. Чтобы получать уведомления об изменении курсора, используйте специальные возможности. Ищите изменения в OBJID_CURSOR.   -  person Raymond Chen    schedule 08.03.2015


Ответы (1)


Поздний ответ, извиняюсь. На основе отзыва Раймонда Чена (спасибо) и его публикации, я настраиваю ловушку только для события EVENT_OBJECT_NAMECHANGE (которое срабатывает при изменении курсора мыши):

SetWinEventHook(EVENT_OBJECT_NAMECHANGE, EVENT_OBJECT_NAMECHANGE, nullptr, WinEventProc, GetCurrentProcessId(), GetCurrentThreadId(), WINEVENT_INCONTEXT);

И прослушал идентификатор объекта OBJID_CURSOR:

void CALLBACK WinEventProc(
  HWINEVENTHOOK hWinEventHook,
  DWORD         event,
  HWND          hwnd,
  LONG          idObject,
  LONG          idChild,
  DWORD         dwEventThread,
  DWORD         dwmsEventTime
  )
{
  if (idObject == OBJID_CURSOR)
  {
    ...
  }
}
person Pooven    schedule 21.03.2016