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.
Активизация окна
Теперь рассмотрим другой, гораздо более гибкий способ привлечения внимания к окну приложения. Он базируется на использовании API-функции SetForegroundWindow. Данная функция принимает один единственный параметр – дескриптор окна. Если выполняется ряд условий, то окно в заданным дескриптором будет выведено на передний план, и пользовательский ввод будет направлен в это окно. Функция возвращает нулевое значение, если не удалось сделать окно активным.
В приведенном ниже примере окно активизируется при каждом срабатывании таймера (листинг 1.4).
procedure TForm1.Timer1Timer(Sender: TObject);
begin
SetForegroundWindow(Handle);
end;
В операционных системах старше Windows 95 и Windows NT 4.0 введен ряд ограничений на действие функции SetForegroundWindow. Приведенный выше пример как раз и является одним из случаев недружественного использования активизации окна – но это всего лишь пример.
Чтобы активизировать окно, процесс не должен быть фоновым либо должен иметь право устанавливать активное окно, назначенное ему другим процессом с таким правом, и т. д. Все возможные нюансы в пределах одного трюка рассматривать не имеет смысла. Стоит отметить, что в случае, когда окно не может быть активизировано, автоматически вызывается функция FlashWindow для окна приложения (эта функция заставляет мигать кнопку приложения на Панели задач). Поэтому даже при возникновении ошибки при вызове функции SetForegroundWindow приложение, нуждающееся во внимании, не останется незамеченным.
Окно приложения
Обратите внимание на то, что название приложения, указанное на кнопке, расположенной на Панели задач, совпадает в названием проекта (можно установить на вкладке Application окна Project options, вызываемого командой меню Project ► Options). Но это название не совпадает с заголовком главной формы приложения. Взгляните на приведенный ниже код, который можно найти в DPR-файле (несущественная часть опущена).
program ...
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end;
В конструкторе класса TApplication, экземпляром которого является глобальная переменная Application (ее объявление находится в модуле Forms), происходит неявное создание главного окна приложения. Заголовок именно этого окна отображается на Панели задач (кстати, этот заголовок можно также изменить с помощью свойства Title объекта Application). Дескриптор главного окна приложения можно получить с помощью свойства Handle объекта Application.
Главное окно приложения делается невидимым (оно имеет нулевую высоту и ширину), чтобы создавалась иллюзия его отсутствия и можно было считать, что главной является именно форма, создаваемая первой.