Во время выступлений, когда на большом экране у вас представлена презентация, хорошо бы соблюдать регламент. Спикеры бывают разные: кто-то имеет чувство времени, кого-то нужно останавливать, а кто-то просто пытается быстро прочесть слайды для гостей форума или конференции. Имея достаточный опыт выступлений, иногда не достает какого-то маленького таймера-помощника спикера, чтобы ненавязчиво, но явно должен уведомлять выступающего о временном регламенте. Поэтому я решил написать небольшую утилиту, которая умеет всегда присутствовать на любом экране, представляться всегда в верхнем слое форм приложений, т.е. "быть всегда сверху" и быстро настраиваться под любой регламент. Использовал я среду разработки для 32-рязрядный приложений Embarcadero Delphi 10.2. Что из этого вышло и какие интересные простые моменты программирования я открыл в новой среде, работая с формами и временем?
Просмотров: 3571
Приложение несложное и очень полезное на мероприятиях. Решались две задачи, которые требовали внимания в реализации программного кода:
- Заставить форму приложения перекрывать окна/формы других приложений ОС Windows.
- Эффективно организовать функции информирования о времени без перегрузки программного кода.
Если говорить о форме::
- Размер 230 х 110 пикс.
- 1 компонент панели
TPanel
, 2 таймера (можно обойтись и одним)TTimer, TTrayIcon
иTPopupMenu
. - В блоке
uses
указываем библиотеку System.DateUtils.
Задача 1. Форма моего приложения всегда поверх остальных
Для решения первой задачи необходимо использовать возможности WinApi в функции SetWindowPos
. Поэтому на первый таймер, который получает активный статус после запуска, указываем функцию:
SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NoMove or SWP_NoSize);
HWND_TOPMOST - позволяет разместить окно поверх всех других окон в Z-последовательности и таймер каждую секунду вызывает эту функцию, не давай другим приложениям перекрыть нашу форму.
SWP_NOACTIVATE - флаг указывает на то, что наша форма не перехватывает фокус на себя, позволяя работать в других приложениях, а для ведения презентации в PowerPoint обычно используют "презентер", у которого управление слайдами построено как раз от статуса приложения PowerPoint, чтобы оно находилось в активном состоянии (было в фокусе).
SWP_NoSize - флаг, указывающий не неизменность исходного размера формы приложения.
Данная функция исправно работает на Windows 7 и 10 на двух экранах (это из тех, что проверил).
Задача 2. Эффективные функции работы со временем в Delphi 10.x
Не могу сказать точно, когда библиотека работы со временем пополнилась в Embarcadero новыми функциями. Но то, что появилось их достаточное множество и очень полезных, это факт.
Исходя из назначения моего приложения нужно позволить пользователю указать длительность своего выступления, допустим переменная T1 (TTime
). Для реализации обратного отсчета нужно всего лишь установить на второй таймер (можно и первый) общее время ActualTime
(текущее + T1) за минусом длительности. Чтобы не раздражать сильно зрителей, то заставляем секунды не меняться на экране до критичного для нас момента:
S:=TimeToStr(RecodeSecond(ActualTime-Time,0));
RecodeSecond
- замена секунд на нужное нам значение, а в данном случае 00.
За несколько минут до окончания (я установил 2 переменных Alarm1==5 минут, Alarm2==1 минуту. Используя функцию CompareTime
можно несложным кодом выставить пороги срабатывания и внести изменения в дизайн и поведение формы ,которые смогут привлечь внимание выступающего и напомнить ему о регламенте (фон, цвет. эффекты и т.п.).
CompareTime
- функция, позволяющая сравнивать значения, возвращаемые от переменных типа TDateTime
. Согласитесь, что наличие такой функции в Embarcadero Delphi упрощает написание кода. Иначе пришлось бы конвертировать, парсить, сплитовать и конкатинировать значения, чтобы добиться результатов. Не то, чтобы это совсем трудоемко, но код получается эффективнее, когда мы можем использовать уже имеющиеся функции и библиотеки.
if CompareTime(Actualtime-Alarm1, time)<1 then
begin
Panel1.color:=ClYellow;
Panel1.Font.color:=ClSilver;
panel1.Caption:=TimeToStr(ActualTime-Time);
end;
CompareTime
имеет 3 значения:
-1 - Дата/время уже в прошлом по отношению к сравниваемому
0 - Дата/время уже идентичны со сравниваемым
1 - Дата/время еще не наступили по отношению к сравниваемому
Удачного программирования и выступлений!