Для того, чтобы создаваемое диалоговое окно отображалось в самом центре экрана, его надо создать с атрибутом стиля 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 - установить окно по центру рабочей области, то есть с учетом размеров панели задач и различных тулбаров.
В приложении два примера с исходниками, создающие окно с изменяемыми размерами и устанавливающие его по центру экрана или клиентской области.