Установка окна по центру с учетом нескольких мониторов
И вновь работа над ошибками. На этот раз переосмысление статьи об установке окна по центру экрана. Приведенный там код работает без проблем, но только для единственного монитора, при наличии двух и более мониторов результат получается неправильным. Основные принципы работы с несколькими мониторами я расписал в предыдущей статье, повторять не буду.Code (Assembler) : Убрать нумерацию
- ;-------------------------------------------------------------------------
- ; Процедура перемещения окна в центр экрана. Если окно развернуто или
- ; его размеры превышают размеры экрана, то окно не перемещается
- ; Параметры:
- ; hwnd - хэндл окна
- ; mode - относительно каких координат центровать окно (1 - только
- ; рабочая область экрана с учетом размеров панели задач и
- ; различных тулбаров, 0 - относительно размеров всего экрана)
- ;-------------------------------------------------------------------------
- proc WindowToCenterEx hwnd:DWORD, mode:DWORD
- MONITOR_DEFAULTTONEAREST = 2
- struct MONITORINFO
- cbSize dd ?
- rcMonitor RECT
- rcWork RECT
- dwFlags dd ?
- ends
- locals
- minfo MONITORINFO
- coord RECT
- endl
- ; Сохранить все регистры
- pusha
- ; Такое окно существует?
- invoke IsWindow,[hwnd]
- or eax,eax
- jz .loc_ret
- ; Окно развернуто на весь экран?
- invoke IsZoomed,[hwnd]
- or eax,eax
- jnz .loc_ret
- ; Получить размеры окна
- lea eax,[coord]
- invoke GetWindowRect,[hwnd],eax
- ; Монитор, на котором находится окно
- invoke MonitorFromWindow,[hwnd],MONITOR_DEFAULTTONEAREST
- ; В регистре ESI указатель на структуру информации о мониторе
- lea esi,[minfo]
- mov [esi+MONITORINFO.cbSize],sizeof.MONITORINFO
- invoke GetMonitorInfo,eax,esi
- ; Весь экран
- lea esi,[minfo.rcMonitor]
- cmp [mode],0
- je @f
- ; Рабочая область экрана
- lea esi,[minfo.rcWork]
- @@:
- mov eax,[esi+RECT.right]
- sub eax,[esi+RECT.left]
- lea edi,[coord]
- mov ebx,[edi+RECT.right]
- sub ebx,[edi+RECT.left]
- ; Окно шире монитора
- cmp ebx,eax
- jg .loc_ret
- mov ecx,[esi+RECT.bottom]
- sub ecx,[esi+RECT.top]
- mov edx,[edi+RECT.bottom]
- sub edx,[edi+RECT.top]
- ; Окно выше монитора
- cmp edx,ecx
- jg .loc_ret
- shr ebx,1
- shr eax,1
- add eax,[esi+RECT.left]
- sub eax,ebx
- shr edx,1
- shr ecx,1
- add ecx,[esi+RECT.top]
- sub ecx,edx
- ; Разместить окно по центру монитора
- invoke SetWindowPos,[hwnd],NULL,eax,ecx,NULL,NULL,\
- SWP_NOSIZE+SWP_NOZORDER
- .loc_ret:
- ; Восстановить все регистры
- popa
- ret
- endp
Теперь хотелось бы сказать несколько слов по поводу юзабилити. Почти всегда я пользовался одним монитором, лишь с недавнего времени на постоянку обзавелся вторым. И тут я понял, что меня дико раздражает практически во всем используемом софте. Несмотря на то, с каким монитором я работаю в данный момент, независимо от того, с какого монитора была запущена программа, все окна открываются на основном мониторе. Лично мне, например, было бы гораздо удобнее, чтобы новое окно программы появлялось именно на том мониторе, где сейчас у меня находится курсор. Реализуется это простейшим кодом:
Code (Assembler) : Убрать нумерацию
- section '.data' data readable writeable
- ; Структура для получения координат курсора
- pt POINT
- ...
- section '.code' code readable executable
- ; Обработчик окна
- ...
- cmp [msg],WM_INITDIALOG
- je wminitdialog
- ...
- ...
- wminitdialog:
- ; Получить координаты курсора
- invoke GetCursorPos,pt
- ; Переместить окно на монитор, где находится курсор
- invoke SetWindowPos,[hwnddlg],NULL,[pt.x],[pt.y],NULL,NULL,\
- SWP_NOSIZE+SWP_NOZORDER
- ; Отцентровать окно
- stdcall WindowToCenterEx,[hwnddlg],0
В приложении два примера с исходными текстами, создающие окно с изменяемыми размерами и устанавливающие его по центру экрана или клиентской области того монитора, на котором это окно находится.
Просмотров: 1784 | Комментариев: 5
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
veeDAN
(21.12.2018 в 14:39):
ManHunter, от Вас ничего.
ManHunter
(25.11.2018 в 09:16):
- Вовочка, расскажи, как работает трансформатор?
- УУУУУууууууу-уууу-у-уу!
Весь код прокомментирован, статья на русском, пример прилагается. Что еще надо?
- УУУУУууууууу-уууу-у-уу!
Весь код прокомментирован, статья на русском, пример прилагается. Что еще надо?
veeDAN
(25.11.2018 в 03:15):
Подскажите, как это работает?
ManHunter
(25.06.2018 в 07:41):
Да это понятно, мне и мышкой лишний раз махнуть - не переломлюсь. Просто когда работаешь с приятной и удобной программой, то мысленно посылаешь ее создателям лучи добра, а когда творится такая хрень, то в точности наоборот.
wet
(25.06.2018 в 05:51):
Можно запомнить одну комбинацию клавиш, которая экономит нервы и время по перетаскиванию окна:
Win+ Shift + стрелки вправо и влево и окно за один клик переносится из монитора в монитор
Так проще, чем ждать, пока программисты исправятся и начнут думать о нескольких мониторах :)
Добавить комментарий
Заполните форму для добавления комментария