Перетаскивание окна за любое место правой кнопкой мыши
В одной из первых статей на этом блоге я рассказывал, как легко сделать перетаскивание окна за любое место левой кнопкой мыши. А тут что-то мне захотелось странного, а именно реализовать перетаскивание окна точно так же за любое место, но только правой кнопкой мыши. Как оказалось, простым пробросом сообщения от мышки на заголовок окна сделать это нельзя. После некоторых раздумий у меня получился вот такой вариант. При клике мышкой по окну оно захватывает события мыши при помощи функции SetCapture и сохраняет начальные координаты окна, при перемещении курсора принудительно перемещает окно вслед за ним, а при отпускании кнопки мышки освобождает перехват событий мыши функцией ReleaseCapture. Начнем с обработчика сообщений окна.Code (Assembler) : Убрать нумерацию
- ; Установка обработчика перетаскивания правой кнопкой
- ; мыши и колесиком
- cmp [msg],WM_RBUTTONDOWN
- je .drag_window_set
- cmp [msg],WM_MBUTTONDOWN
- je .drag_window_set
- ; Снятие обработчика перетаскивания правой кнопкой
- ; мыши и колесиком
- cmp [msg],WM_RBUTTONUP
- je .drag_window_release
- cmp [msg],WM_MBUTTONUP
- je .drag_window_release
- ; Обработчик перемещения мыши
- cmp [msg],WM_MOUSEMOVE
- je .drag_window_ex
Дальше нам понадобится определить несколько структур в сегменте данных, чтобы работать с координатами курсора и окна, а также с его размерами.
Code (Assembler) : Убрать нумерацию
- pt POINT
- pos POINT
- r RECT
Code (Assembler) : Убрать нумерацию
- .drag_window_set:
- ; Запомнить положение окна и установить обработчик событий мыши
- movsx eax,word [lparam+0]
- mov [pos.x],eax
- movsx eax,word [lparam+2]
- mov [pos.y],eax
- invoke SetCapture,[hwnddlg]
- .drag_window_ex:
- ; Обработчик установлен на наше окно?
- invoke GetCapture
- cmp eax,[hwnddlg]
- jne .processed
- ; Получить координаты курсора
- invoke GetCursorPos,pt
- invoke GetWindowRect,[hwnddlg],r
- ; Для окна без заголовка корректируем положение окна
- ; с учетом толщины рамок, установленной в системе
- mov eax,[pos.x]
- sub [pt.x],eax
- invoke GetSystemMetrics,SM_CXFIXEDFRAME
- shr eax,1
- sub [pt.x],eax
- mov eax,[pos.y]
- sub [pt.y],eax
- invoke GetSystemMetrics,SM_CYFIXEDFRAME
- shr eax,1
- sub [pt.y],eax
- mov eax,[r.left]
- sub [r.right],eax
- mov eax,[r.top]
- sub [r.bottom],eax
- ; Переместить окно вслед за курсором
- invoke MoveWindow,[hwnddlg],[pt.x],[pt.y],[r.right],[r.bottom],TRUE
- jmp .processed
- .drag_window_release:
- ; Снять обработчик событий мыши
- invoke ReleaseCapture
- jmp .processed
Code (Assembler) : Убрать нумерацию
- ; Для окна с заголовком придется корректировать положение с учетом
- ; толщины границ обрамления и высоты заголовка
- mov eax,[pos.x]
- sub [pt.x],eax
- invoke GetSystemMetrics,SM_CXFIXEDFRAME
- sub [pt.x],eax
- mov eax,[pos.y]
- sub [pt.y],eax
- invoke GetSystemMetrics,SM_CYFIXEDFRAME
- sub [pt.y],eax
- invoke GetSystemMetrics,SM_CYCAPTION
- sub [pt.y],eax
- mov eax,[r.left]
- sub [r.right],eax
- mov eax,[r.top]
- sub [r.bottom],eax
В приложении примеры программ с исходными текстами, реализующие перетаскивание окна с заголовком и без заголовка при помощи колесика и/или правой кнопки мыши, а также уже известным вам способом левой кнопкой мыши.
Просмотров: 1811 | Комментариев: 0
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Комментариeв нет
Добавить комментарий
Заполните форму для добавления комментария