Переключающиеся экраны на службе у Х-парней

Xakep, номер #039, стр. 039-071-2


Внутри цикла я первым делом очищаю список видимых окон - WindowsList - и заполняю его новыми значениями. Для поиска видимых окон я использую GetWindow, которая может искать все окна, включая главные и подчиненные. Идентификатор найденного окна я сохраняю в переменной W. Видимость окна можно проверять с помощью вызова функции IsWindowVisible, передав в качестве параметра идентификатор окна. Если функция возвращает true, значит, окно видимо и его можно будет двигать. Если нет, то окно или невидимо, или свернуто, а такие окна двигать бесполезно.

Сдвиг по фазе

А теперь сам сдвиг. Он начинается с вызова API функции BeginDeferWindowPos. Эта функция выделяет память для нового окна рабочего стола, куда мы будем сдвигать все видимые окна. В качестве параметра нужно указать, сколько окон мы будем двигать.

Если предыдущие шаги выполнены успешно, то я перебираю все окна из подготовленного списка и сдвигаю их. Для сдвига окна в подготовленную область памяти используется функция DeferWindowPos. В данный момент не происходит никаких реальных перемещений окон, а изменяется только информация о позиции и размерах.

После перемещения всех окон я вызываю API функцию EndDeferWindowPos. Вот тут окна реально перескакивают в новое место. Это происходит практически моментально. Если бы ты использовал простую API функцию SetWindowPos для установки позиции каждого окна в отдельности, то прорисовка происходила бы намного медленнее.

Хитрим однакос

Я всегда тебе говорил, что все переменные типа объектов должны инициализироваться и уничтожаться. Во время инициализации выделяется память, а во время уничтожения память освобождается. В моем примере я создал переменную WindowsList типа TList, но нигде не уничтожаю. Почему, Ведь я расходую память? Все очень просто, программа выполняется бесконечно, и ее работа может прерваться только по двум причинам:

1. Выключили компьютер. В этом случае, даже если я буду освобождать память, то она никому не понадобится, потому что компьютер выключат ;).

2. Кто-то умный снял процесс. Если кто-то додумается до этого, то программа закончит выполнение аварийно и память все равно не освободится.

Получается, что освобождать объект бесполезно, поэтому я этого не делаю. Но все же не советую тебе пренебрегать такими вещами и все же выполнять уничтожения объектов в любом случае.

ЗАДЕРЖКА

Это не задержка, о которой ты подумал. Это та, что останавливает работу проги на определенный промежуток времени. Состоит она из трех незамысловатых функций:

h:=CreateEvent(nil, true, false, '') - создает пустое событие.

WaitForSingleObject(h, 10000) - ожидание, пока не наступит событие. Так как событие пустое, ожидание будет идти столько времени, сколько указано во втором параметре.

CloseHandle(h) - уничтожаем событие.

Вот таким небольшим трюком мы делаем паузу в выполнении программы. Есть еще одна функция для осуществления задержки - sleep. Она проще в использовании, но грузит систему, поэтому я ее не использую.

Disconnect

Мне самому так понравился пример, что я целых полчаса играл с окнами. Они так прикольно исчезают. Но больше всего мне понравилось тренировать себя в скорости снятия приложения. Для этого я уменьшил задержку до 5 секунд.

Назад на стр. 039-071-1  Содержание  Вперед на стр. 039-071-3