Эффект плавного открытия окна
Разберем еще один красивый эффект для ваших приложений - плавное сворачивание и разворачивание окна. Для этого используются те же функции, что и для создания окон нестандартной формы, так как по сути это такая же работа с прямоугольными регионами, но только в цикле с заданными параметрами. Алгоритм простой: прямоугольный регион окна увеличивается от центра до полного размера или уменьшается со всех сторон до центра. Для этого надо сперва надо вычислить шаг, на который будет увеличиваться или уменьшаться горизонтальная и вертикальная координата.Code (Assembler) : Убрать нумерацию
- ; Обработчик инициализации окна
- ...
- ; Получить размер окна
- invoke GetClientRect,[hwnddlg],coord
- ; Вычислить размеры окна для создания основного региона
- mov eax,[coord.bottom]
- sub eax,[coord.top]
- mov [height],eax
- mov eax,[coord.right]
- sub eax,[coord.left]
- mov [width],eax
- SPEED = 4 ; Скорость анимации
- ; Вычислить коэффициент соотношения сторон в зависимости от
- ; размеров ширины и высоты окна
- cmp eax,[height]
- ja @f
- ; Высота/ширина
- xor edx,edx
- mov eax,[height]
- mov ecx,[width]
- div ecx
- shl eax,SPEED
- mov [delta_x],(1 shl SPEED) ; Шаг изменения ширины
- mov [delta_y],eax ; Шаг изменения высоты
- jmp @1
- @@:
- ; Ширина/высота
- xor edx,edx
- mov eax,[width]
- mov ecx,[height]
- div ecx
- shl eax,SPEED
- mov [delta_x],eax ; Шаг изменения ширины
- mov [delta_y],(1 shl SPEED) ; Шаг изменения высоты
- @1:
При плавном разворачивании окна цикл начинается с середины окна. Размер региона по горизонтали и вертикали уменьшается на соответствующий шаг. При достижении края одной из сторон окно полностью перерисовывается. Между итерациями цикла делается небольшая пауза, по опытам вполне достаточно одной миллисекунды. Для увеличения скорости анимации нужно увеличить шаг.
Code (Assembler) : Убрать нумерацию
- ; Разворачиваем окно. Для этого установим регион
- ; в цикле от центра до края окна
- ; Текущие смещения окна - центр экрана
- mov eax,[width]
- shr eax,1
- mov [cur_x],eax
- mov eax,[height]
- shr eax,1
- mov [cur_y],eax
- loc_loop_show:
- ; Создать главный регион диалогового окна
- invoke CreateRectRgn,0,0,[width],[height]
- mov [hRMain],eax
- ; Вырезать все окно
- invoke CreateRectRgn,0,0,[width],[height]
- push eax
- invoke CombineRgn,[hRMain],[hRMain],eax,RGN_DIFF
- ; Освободить хэндл и память региона
- invoke DeleteObject
- ; Добавить прямоугольный регион (режим RGN_OR)
- mov eax,[height]
- sub eax,[cur_y]
- push eax
- mov eax,[width]
- sub eax,[cur_x]
- push eax
- invoke CreateRectRgn,[cur_x],[cur_y]
- push eax
- invoke CombineRgn,[hRMain],[hRMain],eax,RGN_OR
- ; Освободить хэндл и память региона
- invoke DeleteObject
- ; Установить новый регион для окна и перерисовать его
- invoke SetWindowRgn,[hwnddlg],[hRMain],TRUE
- ; Освободить хэндл и память главного региона
- invoke DeleteObject,[hRMain]
- ; Окно уже показывается?
- invoke IsWindowVisible,[hwnddlg]
- or eax,eax
- jnz @f
- ; Сделать окно видимым
- invoke ShowWindow,[hwnddlg],SW_SHOW
- @@:
- ; Вычесть шаг по вертикали и горизонтали
- mov eax,[delta_x]
- sub [cur_x],eax
- mov eax,[delta_y]
- sub [cur_y],eax
- ; Дошли до края хотя бы по одной координате?
- cmp [cur_x],0
- jbe loc_show
- cmp [cur_y],0
- jbe loc_show
- ; Небольшая пауза
- invoke Sleep,1
- jmp loc_loop_show
- loc_show:
- ; Сбросить регион для окна и перерисовать его
- invoke SetWindowRgn,[hwnddlg],NULL,TRUE
Code (Assembler) : Убрать нумерацию
- ; Сворачиваем окно. Для этого установим регион
- ; в цикле от края до центра окна
- ; Текущие смещения окна
- mov [cur_x],0
- mov [cur_y],0
- loc_loop_close:
- ; Создать главный регион диалогового окна
- invoke CreateRectRgn,0,0,[width],[height]
- mov [hRMain],eax
- ; Вырезать все окно
- invoke CreateRectRgn,0,0,[width],[height]
- push eax
- invoke CombineRgn,[hRMain],[hRMain],eax,RGN_DIFF
- ; Освободить хэндл и память региона
- invoke DeleteObject
- ; Добавить прямоугольный регион (режим RGN_OR)
- mov eax,[height]
- sub eax,[cur_y]
- push eax
- mov eax,[width]
- sub eax,[cur_x]
- push eax
- invoke CreateRectRgn,[cur_x],[cur_y]
- push eax
- invoke CombineRgn,[hRMain],[hRMain],eax,RGN_OR
- ; Освободить хэндл и память региона
- invoke DeleteObject
- ; Установить новый регион для окна и перерисовать его
- invoke SetWindowRgn,[hwnddlg],[hRMain],TRUE
- ; Освободить хэндл и память главного региона
- invoke DeleteObject,[hRMain]
- ; Добавить шаг по горизонтали и вертикали
- mov eax,[delta_x]
- add [cur_x],eax
- mov eax,[delta_y]
- add [cur_y],eax
- ; Дошли до центра окна по какой-нибудь координате?
- mov eax,[width]
- shr eax,1
- cmp [cur_x],eax
- ja loc_close
- mov eax,[height]
- shr eax,1
- cmp [cur_y],eax
- ja loc_close
- ; Небольшая пауза
- invoke Sleep,1
- jmp loc_loop_close
- loc_close:
- ; Закрыть окно
Просмотров: 6494 | Комментариев: 6
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
NT_Header
(06.04.2012 в 22:23):
Очень круто!
некто
(12.03.2012 в 15:57):
А у меня не поехала
Андрей
(14.02.2011 в 00:18):
Если программист в девять утра уже на работе, значит он там же и ночевал -это не просто истина - это какая-то закономерность или напасть!
Alex81524
(23.12.2010 в 09:45):
Программа не просто шикарная. Эффект оригинальный, а автор - почти гений :)
ManHunter
(10.12.2010 в 23:04):
Это не наш метод :) Это ж Ассемблер!
zummenix
(10.12.2010 в 19:26):
А ещё можно использовать стандартную анимацию виндовса :)
Добавить комментарий
Заполните форму для добавления комментария