Blog. Just Blog

Обработка колесика мыши над иконкой в трее

12.11.2021 | Категория: Образ мышления: Assembler | Автор: ManHunter
"По следам наших публикаций", как любили писать в советской прессе. В предыдущей статье я обещал рассказать, каким образом можно реализовать обработку вращения колесика мыши над иконкой в системном трее. Поскольку система не отправляет иконкам в трее сообщение WM_MOUSEWHEEL, обрабатывать его мы будем при помощи хуков и описанных в предыдущей статье методов определения, что курсор находится над нужной иконкой. Начнем с локального хука. Установка и снятие хука выполняется самым обычным способом, например:
  1. proc DialogProc hwnddlg,msg,wparam,lparam
  2.         push    ebx esi edi
  3.         cmp     [msg],WM_INITDIALOG
  4.         je      .wminitdialog
  5.         cmp     [msg],WM_CLOSE
  6.         je      .wmclose
  7.         ...
  8.         ...
  9.         xor     eax,eax
  10.         jmp     .finish
  11.  
  12. .wminitdialog:
  13.         ...
  14.         ...
  15.         ; Показать иконку в трее
  16.         invoke  Shell_NotifyIcon, NIM_ADD,node
  17.  
  18.         ; Установить обработчик мыши
  19.         invoke  GetCurrentThreadId
  20.         invoke  SetWindowsHookEx,WH_MOUSE,MousewheelProc,NULL,eax
  21.         mov     [hhkm],eax
  22.  
  23.         mov     eax,[hwnddlg]
  24.         mov     [hwmain],eax
  25.         jmp     .processed
  26.  
  27.         ...
  28.         ...
  29. .wmclose:
  30.         ; Снять обработчик мыши
  31.         invoke  UnhookWindowsHookEx,[hhkm]
  32.         ; Удалить иконку из трея
  33.         invoke  Shell_NotifyIcon,NIM_DELETE,node
  34.  
  35.         ; Закрыть окно
  36.         invoke  EndDialog,[hwnddlg],0
  37. .processed:
  38.         mov     eax,1
  39. .finish:
  40.         pop     edi esi ebx
  41.         ret
  42. endp
Обработчик событий мыши проверяет, что пришло сообщение WM_MOUSEWHEEL и что курсор в текущий момент находится над нужной иконкой в трее. Если эти условия выполнены, то проверяется направление вращения колесика и, в зависимости от этого, выполняются те или иные действия. Имейте в виду, что для сообщения WM_MOUSEWHEEL в обработчик хука приходит структура не MOUSEHOOKSTRUCT, а MOUSEHOOKSTRUCTEX с дополнительным полем mouseData.
  1. ; Структура для обработчика хука
  2. struct MOUSEHOOKSTRUCTEX
  3.         pt           POINT
  4.         hwnd         dd ?
  5.         wHitTestCode dd ?
  6.         dwExtraInfo  dd ?
  7.         mouseData    dd ?
  8. ends
  9.  
  10. ;-------------------------------------------------------------
  11. ; Обработка mousewheel
  12. ;-------------------------------------------------------------
  13. proc MousewheelProc nCode:dword,wParam:dword,lParam:dword
  14.         pusha
  15.  
  16.         cmp     [nCode],0
  17.         jl      .loc_ret
  18.  
  19.         ; Это сообщение от колеса мыши?
  20.         cmp     [wParam],WM_MOUSEWHEEL
  21.         jne     .loc_ret
  22.  
  23.         ; Заполнить структуру для идентификации иконки
  24.         mov     [notify.cbSize],sizeof.NOTIFYICONIDENTIFIER
  25.         mov     eax,[hwmain]
  26.         mov     [notify.hWnd],eax
  27.         mov     [notify.uID],ICON_ID
  28.  
  29.         ; Получить координаты иконки в трее
  30.         invoke  Shell_NotifyIconGetRect,notify,rc
  31.  
  32.         ; Указатель на MOUSEHOOKSTRUCT
  33.         mov     ebx,[lParam]
  34.  
  35.         ; Курсор находится внутри прямоугольника иконки?
  36.         invoke  PtInRect,rc,[ebx+MOUSEHOOKSTRUCTEX.pt.x],\
  37.                 [ebx+MOUSEHOOKSTRUCTEX.pt.y]
  38.         or      eax,eax
  39.         ; Нет, ничего не делать
  40.         jz      .loc_ret
  41.  
  42.         ; Проверить направление поворота колесика
  43.         mov     eax,[ebx+MOUSEHOOKSTRUCTEX.mouseData]
  44.         or      eax,eax
  45.         js      .loc_down
  46. .loc_up:
  47.         ; Вращение вверх
  48.         ...
  49.         ...
  50.         jmp     .loc_ret
  51. .loc_down:
  52.         ; Вращение вниз
  53.         ...
  54.         ...
  55.  
  56. .loc_ret:
  57.         popa
  58.         invoke  CallNextHookEx,[hhkm],[nCode],[wParam],[lParam]
  59.         ret
  60. endp
Способ замечательно работает, но есть одно большое "НО". Локальный хук будет срабатывать только в том случае, когда активно окно приложения. Если ваше приложение подразумевает именно такой принцип работы, то все нормально, больше ничего придумывать не надо.

Читать статью целиком »
Просмотров: 208 | Комментариев: 7

Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2021
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.08 сек. / MySQL: 1 (0.0162 сек.) / Память: 4.75 Mb
Наверх