...
Листинг 1.5. Показываем окно приложения
procedure TForm1.Button1Click(Sender: TObject);
begin
SetWindowPos(Application.Handle, 0, 0, 0, 200, 100,
SWP_NOZORDER or SWP_NOMOVE);
end;
В результате ширина окна станет равной 200, а высота – 100, и мы сможем посмотреть на главное окно. Кстати, можно заметить, что при активизации этого окна (например, щелчке кнопкой мыши на заголовке) фокус ввода немедленно передается созданной первой, то есть главной, форме.
Теперь должно стать понятно, почему не мигала кнопка приложения при использовании функций FlashWindow или FlashWindowEx. Недостаток этот можно легко устранить, например, следующим образом (листинг 1.6).
...
Листинг 1.6.
Мигание кнопки приложения на Панели задач
procedure TForm1.Button2Click(Sender: TObject);
var
fl: FLASHWINFO;
begin
fl.cbSize:= SizeOf(fl);
fl.hwnd:= Application.Handle;
fl.dwFlags:= FLASHW_ALL;
fl.uCount:= 10;
fl.dwTimeout:= 200;
FlashWindowEx(fl);
end;
В данном случае будет одновременно инвертироваться заголовок окна приложения. Убедиться в этом можно, предварительно применив листинг 1.5. Наконец, чтобы добиться одновременного мигания кнопки приложения на Панели задач и заголовка формы (произвольной, а не только главной), можно применить листинг 1.7.
...
Листинг 1.7.
Мигание кнопки приложения и инверсия заголовка формы
procedure TForm1.Button3Click(Sender: TObject);
var
fl: FLASHWINFO;
begin
//Мигание кнопки
fl.cbSize:= SizeOf(fl);
fl.hwnd:= Application.Handle;
fl.dwFlags:= FLASHW_TRAY;
fl.uCount:= 10;
fl.dwTimeout:= 200;
FlashWindowEx(fl);
//Инверсия заголовка
fl.cbSize:= SizeOf(fl);
fl.hwnd:= Handle;
fl.dwFlags:= FLASHW_CAPTION;
fl.uCount:= 10;
fl.dwTimeout:= 200;
FlashWindowEx(fl);
end;
В данном случае инвертируется заголовок формы Forml. Кнопка на Панели задач может не только мигать, но и, например, быть скрыта или показана, когда в этом есть необходимость. Так, для скрытия кнопки приложения можно применить API-функцию ShowWindow следующим образом:
...
ShowWindow(Application.Handle, SW_HIDE);
Чтобы показать кнопку приложения, можно ту же функцию ShowWindow вызвать со вторым параметром, равным SW_NORMAL.
1.3. Полупрозрачные окна
В Windows 2000 впервые появилась возможность использования прозрачности окон (в англоязычной документации такие полупрозрачные окна называются Layered windows). Достигается это заданием дополнительного стиля окна (о назначении и использовании оконных стилей можно узнать в гл. 2). Здесь мы не будем рассматривать использование API-функций для работы с полупрозрачными окнами, так как их поддержка реализована для форм Delphi. Соответствующие свойства включены в состав класса TForm.
• AlphaBlend – включение/выключение прозрачности. Если True, то прозрачность включена, если False, то выключена.
• AlphaBlendValue – значение, обратное прозрачности окна (от 0 до 255). Если 0, то окно полностью прозрачно, если 255, то окно непрозрачно.
Значения перечисленных свойств можно изменять как из окна Object Inspector, так и во время выполнения программы (рис. 1.1).
Рис. 1.1. Свойства для настройки прозрачности в окне Object Inspector
На рис. 1.2 наглядно продемонстрировано, как может выглядеть полупрозрачное окно (форма Delphi).
Рис. 1.2. Форма, прозрачная на 14 %
Ниже для примера рассмотрим, как применяются свойства AlphaBl end, а также AlphaBlendValue для задания прозрачности окна во время выполнения программы (сочетание ползунка tbAlpha, флажка chkEnableAlpha и подписи lblCurAlpha на форме рис. 1.2) (листинг 1.8).
...
Листинг 1.8.
Динамическое изменение прозрачности окна
procedure TForm1.chkEnableAlphaClick(Sender: TObject);
begin
AlphaBlendValue:= tbAlpha.Position;
AlphaBlend:= chkEnableAlpha.Checked;
end;
procedure TForm1.tbAlphaChange(Sender: TObject);
var
pos, perc: Integer;
begin
pos:= tbAlpha.Position;
//Новое значение прозрачности
AlphaBlendValue:= pos;
//Обновим подпись под ползунком
perc:= pos * 100 div 255;
lblCurAlpha.Caption:= IntToStr(pos) + из 255 ( +
IntToStr(perc) + %) ;
end;
Довольно интересный эффект постепенного исчезновения, а затем появления формы можно реализовать, применив следующий код (листинг 1.9).
...
Листинг 1.9.
Исчезновение и появление формы
implementation
var
isInc: Boolean; // Если True, то значение AlphaBlend формы
// увеличивается, если False, то уменьшается
//(форма скрывается)
procedure TForm1.cmbHideAndShowClick(Sender: TObject);
begin
if AlphaBlend then chkEnableAlpha.Checked:= False;
//Включаем прозрачность (подготовка к плавному скрытию)
AlphaBlendValue:= 255;
AlphaBlend:= True;
Refresh;
//Запускаем процесс скрытия формы
isInc:= False;
Timer1.Enabled:= True;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var val: Integer;
begin
if not isInc then
begin
//"Растворение" окна
val:= AlphaBlendValue;
Dec(val, 10);
if val <= 0 then
begin
//Окно полностью прозрачно
val:= 0;
isInc:= True;
end
end
else begin
//Появление окна
val:= AlphaBlendValue;
Inc(val, 10);
if val >= 255 then
begin
//Окно полностью непрозрачно
val:= 255;
Timer1.Enabled:= False; //Процесс закончен
AlphaBlend:= False;
end
end;
AlphaBlendValue:= val;
end;
Главная сложность приведенного в листинге 1.9 алгоритма кроется в использовании таймера (Timerl) для инициирования изменения прозрачности окна. Так сделано для того, чтобы окно могло принимать пользовательский ввод, даже когда оно скрывается или постепенно показывается, и чтобы приложение не "съедало" все ресурсы на относительно слабой машине. Попробуйте сделать плавное изменение прозрачности в простом цикле, запустите его на каком-нибудь Pentium III 600 МГц без навороченной видеокарты и сами увидите, что станет с бедной машиной.
Грамотное, а главное уместное, использование прозрачности окон может значительно повысить привлекательность интерфейса приложения (взгляните хотя бы на Winamp 5 при включенном параметре прозрачности окон).
1.4. Окна и кнопки нестандартной формы
Сейчас мы рассмотрим некоторые стандартные возможности Windows, которые можно использовать для достижения большего разнообразия и привлекательности элементов оконного интерфейса за счет изменения формы элементов управления и, естественно, самих окон приложений.
Регионы. Создание и использование
Рассматриваемые далее эффекты по изменению формы окон базируются на использовании регионов (областей) отсечения – в общем случае сложных геометрических фигур, ограничивающих область рисования окна. По умолчанию окна (в том числе и окна элементов управления) имеют область отсечения, заданную прямоугольным регионом с высотой и шириной, равн ыми высоте и ширине самого окна.
Однако использование прямоугольных регионов для указания областей отсечения совсем не обязательно. Использование отсечения по заданному непрямоугольному региону при рисовании произвольного окна наглядно представлено на рис. 1.3: а – изначальный прямоугольный вид формы; б – используемый регион, формирующий область отсечения; в – настоящий вид формы в результате рисования с отсечением по границам заданного региона.
Рис. 1.3. Использование области отсечения при рисовании окна
Рассмотрим операции, позволяющие создавать, удалять и модифицировать регионы. Создание и удаление регионов Создать регионы различной формы можно с помощью следующих API-функций: