|

Переключающиеся экраны на службе у Х-парней
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
|