Установка окна по центру экрана

Для того, чтобы создаваемое диалоговое окно отображалось в самом центре экрана, его надо создать с атрибутом стиля DS_CENTER. Но иногда требуется отцентровать уже созданное или чужое окно. Для этого я написал небольшую функцию, устанавливающую выбранное окно по центру экрана, с некоторыми дополнительными возможностями. Функция самодостаточна, не требует дополнительных переменных в сегменте данных, корректно работает с любыми окнами, пропуская развернутые на весь экран.
;-------------------------------------------------------------------------
; Процедура перемещения окна в центр экрана. Если окно развернуто или
; его размеры превышают размеры экрана, то окно не перемещается
; Параметры:
;   hwnd - хэндл окна
;   mode - относительно каких координат центровать окно (1 - только
;          рабочая область экрана с учетом размеров панели задач и
;          различных тулбаров, 0 - относительно размеров всего экрана)
;-------------------------------------------------------------------------
proc    WindowToCenter hwnd:DWORD, mode:DWORD
        ; Локальные переменные, они же структура RECT
        local   left   :DWORD
        local   top    :DWORD
        local   right  :DWORD
        local   bottom :DWORD
 
        ; Сохранить все регистры
        pusha
 
        ; Такое окно существует?
        invoke  IsWindow,[hwnd]
        or      eax,eax
        jz      .loc_ret
        ; Окно развернуто на весь экран?
        invoke  IsZoomed,[hwnd]
        or      eax,eax
        jnz     .loc_ret
 
        ; Получить размеры окна
        lea     eax,[left]
        invoke  GetWindowRect,[hwnd],eax
 
        ; Флаги функции SetWindowPos
        push    SWP_NOSIZE+SWP_NOZORDER
        push    NULL
        push    NULL
 
        ; Какие размеры экрана получать
        mov     eax,SM_CYSCREEN      ; Вся экранная область
        cmp     [mode],0
        je      @f
        mov     eax,SM_CYFULLSCREEN  ; Рабочая область экрана
@@:
        ; Получить высоту экрана
        invoke  GetSystemMetrics,eax
        mov     ecx,[bottom]
        sub     ecx,[top]
 
        ; Высота окна больше высоты экрана?
        cmp     ecx,eax
        jbe     @f
 
        ; Почистить стек и на выход
        add     esp,12
        jmp     .loc_ret
@@:
        sub     eax,ecx
        shr     eax,1
        ; Новая координата Y
        push    eax
 
        ; Какие размеры экрана получать
        mov     eax,SM_CXSCREEN      ; Вся экранная область
        cmp     [mode],0
        je      @f
        mov     eax,SM_CXFULLSCREEN  ; Рабочая область экрана
@@:
        ; Получить ширину экрана
        invoke  GetSystemMetrics,eax
        mov     ecx,[right]
        sub     ecx,[left]
 
        ; Ширина окна больше ширины экрана?
        cmp     ecx,eax
        jbe     @f
 
        ; Почистить стек и на выход
        add     esp,16
        jmp     .loc_ret
@@:
        sub     eax,ecx
        shr     eax,1
        ; Новая координата X
        push    eax
 
        ; Разместить окно по центру экрана
        invoke  SetWindowPos,[hwnd],NULL
 
.loc_ret:
        ; Восстановить все регистры
        popa
        ret
endp

Параметры вызова: hwnd - хэндл окна, которое надо отцентровать, mode - режим центровки: 0 - установить окно по центру всего экрана, 1 - установить окно по центру рабочей области, то есть с учетом размеров панели задач и различных тулбаров.

В приложении два примера с исходниками, создающие окно с изменяемыми размерами и устанавливающие его по центру экрана или клиентской области.
Теги:
окно
Добавлено: 10 Апреля 2018 20:31:48 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...