Нужно также уточнить, что в этой главе термины «окно» и «форма» употребляются как синонимы, когда речь идет о форме. Когда же речь идет об элементах управления, то так и говорится: «окно элемента управления».
Привлечение внимания к приложению
Начнем с простых примеров, позволяющих привлечь внимание пользователя к определенному окну приложения. Это может пригодиться в различных ситуациях: начиная от необходимости уведомления пользователя об ошибке программы и заканчивая простой сигнализацией ему, какое окно в данный момент времени ожидает пользовательского ввода.
Инверсия заголовка окна
Вероятно, вы не раз могли наблюдать, как некоторые приложения после выполнения длительной операции или при возникновении ошибки как бы подмигивают. При этом меняется цвет кнопки приложения на Панели задач, а состояние открытого окна меняется с активного на неактивное. Такой эффект легко достижим при использовании API-функции FlashWindow или ее усовершенствованного, но более сложного варианта функции FlashWindowEx.
Примечание
Здесь сказано, что функции изменяют цвет кнопки приложения на Панели задач. Однако этого не происходит при выполнении приведенных ниже примеров. Почему так получается и как это изменить, рассказано в следующем разделе этой главы (стр. 15).
Первая из этих функций позволяет один раз изменить состояние заголовка окна и кнопки на Панели задач (листинг 1.1).
Листинг 1.1. Простая инверсия заголовка окнаprocedure TForm1.cmbFlashOnceClick(Sender: TObject);
begin
FlashWindow(Handle, True);
end;
Как видите, функция принимает дескриптор нужного окна и параметр (тип BOOL) инверсии. Если значение флага равно T rue, то состояние заголовка окна изменяется на противоположное (из активного становится неактивным и наоборот). Если значение флага равно False, то состояние заголовка окна дважды меняет свое состояние, то есть восстанавливает свое первоначальное значение (активно или неактивно).
Более сложная функция FlashWindowEx в качестве дополнительного параметра (кроме дескриптора окна) принимает структуру FLASHWINFO, заполняя поля которой можно настроить параметры мигания кнопки приложения и/или заголовка окна.
В табл. 1.1 приведено описание полей структуры FLASHWINFO.
Таблица 1.1. Поля структуры FLASHWINFOЗначение параметра dwFlags формируется из приведенных ниже флагов с использованием операции побитового ИЛИ:
FLASHW_CAPTION инвертирует состояние заголовка окна;
FLASHW_TRAY заставляет мигать кнопку на Панели задач;
FLASHW_ALL сочетание FLASHW_CAPTION и FLASHW_TRAY;
FLASHW_TIMER периодически измененяет состояния заголовка окна и/или кнопки на Панели задач до того момента, пока функция FlashWindowEx не будет вызвана с флагом FLASHW_STOP;
FLASHW_TIMERNOFG периодически измененяет состояния заголовка окна и/или кнопки на Панели задач до тех пор, пока окно не станет активным;
FLASHW_STOP восстанавливает исходное состояние окна и кнопки на Панели задач.
Далее приведены два примера использования функции FlashWindowEx.
В первом примере состояние заголовка окна и кнопки на Панели задач изменяется десять раз в течение двух секунд (листинг 1.2).
Листинг 1.2. Десятикратная инверсия заголовка окнаprocedure TForm1.cmbInverse10TimesClick(Sender: TObject);
var
fl: FLASHWINFO;
begin
fl.cbSize:= SizeOf(fl);
fl.hwnd:= Handle;
fl.dwFlags:= FLASHW_CAPTION or FLASHW_TRAY; //аналогично FLASHW_ALL
fl.uCount:= 10;
fl.dwTimeout:= 200;
FlashWindowEx(fl);
end;
Второй пример демонстрирует использование флагов FLASHW_TIMER и FLASHW_ STOP для инверсии заголовка окна в течение заданного промежутка времени (листинг 1.3).
Листинг 1.3. Инверсия заголовка окна в течение определенного промежутка времени//Запуск процесса периодической инверсии заголовка
procedure TForm1.cmbFlashFor4SecClick(Sender: TObject);
var
fl: FLASHWINFO;
begin
fl.cbSize:= SizeOf(fl);
fl.hwnd:= Handle;
fl.dwTimeout:= 200;
fl.dwFlags:= FLASHW_ALL or FLASHW_TIMER;
fl.uCount:= 0;
FlashWindowEx(fl);
Timer1.Enabled:= True;
end;
//Остановка инверсии и заголовка
procedure TForm1.Timer1Timer(Sender: TObject);
var
fl: FLASHWINFO;
begin
fl.cbSize:= SizeOf(fl);
fl.hwnd:= Handle;
fl.dwFlags:= FLASHW_STOP;
FlashWindowEx(fl);
Timer1.Enabled:= False;
end;
В данном примере используется таймер, срабатывающий каждые четыре секунды. Таймер первоначально неактивен. Конечно, можно было бы не использовать его, а просто посчитать количество инверсий, совершаемых в течение требуемого интервала времени (в данном случае четырех секунд) и задать его в поле uCount. Но приведенный пример предназначен именно для демонстрации использования флагов FLASHW_TIMER и FLASHW_STOP.