Тюнингуем контрол msctls_trackbar32
За время существования этого сайта тут было доработано уже несколько различных стандартных элементов управления, настало время провести тюнинг контрола msctls_trackbar32. Создается он обычным образом, например, через прописывание в ресурсах. Обязательно надо добавить в импорт библиотеку comctl32.dll и вызвать функцию InitCommonControls. Ну а поскольку мы будем добавлять к контролу различные нестандартные функции, то и делать это будем в специально отведенной процедуре-обработчике. Для этого воспользуемся субклассированием. Действия стандартные, примеров субклассирования на этом сайте предостаточно.Code (Assembler) : Убрать нумерацию
- ; Настройки ползунка
- invoke GetDlgItem,[hwnddlg],IDC_PROGRESS
- mov [track],eax
- ; Установить наш собственный обработчик
- invoke SetWindowLong,[track],GWL_WNDPROC,TrackProc
- ; Сохранить хэндл предыдущего обработчика
- invoke SetWindowLong,[track],GWL_USERDATA,eax
Начинаем с избавления от рамки. Тут ничего нового, это уже было разобрано в одной из предыдущих статей. В случае с msctls_trackbar32 код в обработчике будет абсолютно такой же. Все необходимые значения констант и порядок установки обработчика можно посмотреть по приведенной ссылке.
Code (Assembler) : Убрать нумерацию
- ; Система хочет поменять состояние интерфейса
- cmp [uMsg],WM_UPDATEUISTATE
- je .wm_updateuistate
- ...
- ...
- .wm_updateuistate:
- ; Принудительно сбросить фокус
- mov [wParam],(UIS_SET shl 16 + UISF_HIDEFOCUS)
- jmp .process_ok
Code (Assembler) : Убрать нумерацию
- ; Вращение колесика мыши
- cmp [uMsg],WM_MOUSEWHEEL
- je .wm_mousewheel
- ...
- ...
- .wm_mousewheel:
- ; Инвертировать направление вращения колесика
- neg [wParam]
- jmp .process_ok
Добавляем "рулетку"
Для наглядности я сделал этот элемент видимым. В реальных проектах после позиционирования "рулетки" все риски на шкале можно убрать, а саму "рулетку" надо обязательно сделать невидимой. После всех выполненных манипуляций, при клике на контрол получаем координаты события при помощи функции GetMessagePos, затем при помощи функции ScreenToClient проецируем координаты клика на "рулетку". Остается, как я говорил выше, решить пропорцию и установить новую позицию бегунка в соответствии с местом клика. Важно проверять левую границу после пересчета координат, если она будет меньше начального значения, то надо принудительно приравнивать ее к этому значению.
Code (Assembler) : Убрать нумерацию
- ; Клик в области контрола
- cmp [uMsg],WM_LBUTTONDOWN
- je .wm_lbuttondown
- ...
- ...
- .wm_lbuttondown:
- ; Получить координаты события клика
- invoke GetMessagePos
- and eax,0FFFFh
- add eax,5
- mov [pt.x],eax
- ; Пересчитать координаты в пределах линейки
- invoke ScreenToClient,[ruler],pt
- ; Начальная координата не должна выходить за границу линейки
- mov eax,[pt.x]
- or eax,eax
- jns @f
- mov [pt.x],0
- @@:
- ; Получить размеры линейки
- invoke GetWindowRect,[ruler],coord
- ; Получить максимальное значение ползунка
- invoke SendMessage,[hBtn],TBM_GETRANGEMAX,NULL,NULL
- xor edx,edx
- mov ecx,[pt.x]
- imul ecx
- mov ecx,[coord.right]
- sub ecx,[coord.left]
- xor edx,edx
- idiv ecx
- mov ecx,[coord.right]
- sub ecx,[coord.left]
- shr ecx,1
- cmp ecx,edx
- jbe @f
- inc eax
- @@:
- ; Установить новую позицию в соответствии с кликом
- invoke SendMessage,[hBtn],TBM_SETPOS, TRUE, eax
- ; Отправить сообщение главному окну
- invoke SendMessage,[mainwnd],WM_HSCROLL,0,[hBtn]
- jmp .process_ok
Просмотров: 291 | Комментариев: 0
Метки: Assembler
Комментарии
Отзывы посетителей сайта о статье
Комментариeв нет
Добавить комментарий
Заполните форму для добавления комментария