скачать книгу бесплатно
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 при включенном параметре прозрачности окон).
Окна и кнопки нестандартной формы
Далее будут рассмотрены некоторые стандартные возможности Windows, которые можно использовать для достижения большего разнообразия и привлекательности элементов оконного интерфейса. Приведенные здесь примеры измененяют формы элементов управления и, естественно, формы самих окон приложений.
Регионы. Создание и использование
Рассматриваемые эффекты по изменению формы окон базируются на использовании регионов (областей) отсечения – в общем случае сложных геометрических фигур, ограничивающих область рисования окна. По умолчанию окна (в том числе и окна элементов управления) имеют область отсечения, заданную прямоугольным регионом с высотой и шириной, равной высоте и ширине самого окна.
Однако использование прямоугольных регионов для указания областей отсечения совсем не обязательно. Использование отсечения по заданному непрямоугольному региону при рисовании произвольного окна наглядно представлено на рис. 1.3: а – исходный прямоугольный вид формы; б – используемый регион, формирующий область отсечения; в – вид формы, полученный в результате рисования с отсечением по границам заданного региона.
Рис. 1.3. Использование области отсечения при рисовании окна
Рассмотрим операции, позволяющие создавать, удалять и модифицировать регионы.
Создание и удаление регионов
Создать несложные регионы различной формы можно с помощью следующих API-функций:
function CreateRectRgn(p1, p2, p3, p4: Integer): HRGN;
function CreateEllipticRgn(p1, p2, p3, p4: Integer): HRGN;
function CreateRoundRectRgn(p1, p2, p3, p4, p5, p6: Integer): HRGN;
Все перечисленные здесь и ниже функции создания регионов возвращают дескриптор GDI-объекта «регион». Он впоследствии и передается в различные функции, работающие с регионами.
Первая из приведенных функций (CreateRectRgn) предназначена для создания регионов прямоугольной формы. Параметры этой функции необходимо толковать следующим образом:
• p1 и p2 – горизонтальная и вертикальная координаты левой верхней точки прямоугольника;
• p3 и p4 – горизонтальная и вертикальная координаты правой нижней точки прямоугольника.
Следующая функция (CreateEllipticRgn) предназначена для создания региона в форме эллипса. Параметры этой функции – координаты прямоугольника (аналогично функции CreateRectRgn), в который вписывается требуемый эллипс.
Третья функция (CreateRoundRectRgn) создает регион в виде прямоугольника с округленными углами. При этом первые четыре параметра функции аналогичны соответствующим параметрам функции CreateRectRgn. Параметры p5 и p6 – ширина и высота сглаживающих углы эллипсов (рис. 1.4).
Рис. 1.4. Округление прямоугольника функцией CreateRoundRectRgn
Трех приведенных функций достаточно даже в том случае, если нужно создавать регионы очень сложной формы. Это достигается с помощью применения многочисленных операций над простыми регионами, как в приведенном далее примере создания региона по битовому шаблону. Однако рассмотрим еще одну несложную функцию, которая позволяет сразу создавать регионы-многоугольники по координатам точек вершин многоугольников:
function CreatePolygonRgn(const Points; Count, FillMode: Integer): HRGN;
Функция CreatePolygonRgn использует следующие параметры:
• Points – указатель на массив записей типа TPoint, каждый элемент которого описывает одну вершину многоугольника (координаты не должны повторяться);
• Count – количество записей в массиве, на который указывает параметр Points;
• FillMode – способ заливки региона (в данном случае определяет, попадает ли внутренняя область многоугольника в регион).
Параметр FillMode принимает значения WINDING (попадает любая внутренняя область) и ALTERNATE (попадает внутренняя область, если она находится между нечетной и следующей четной сторонами многоугольника).
Примечание
При создании регионов с помощью любой из указанных выше функций координаты точек задаются в системе координат того окна, в котором предполагается использовать регион. Так, если у вас есть кнопка размером 40 х 30 пикселов, левый верхний угол которой расположен на форме в точке (100; 100), то для того, чтобы создать для кнопки прямоугольный регион 20 х 15 пикселов с левой верхней точкой (0;0) относительно начала координат кнопки, следует вызвать функцию CreateRectRgn с параметрами (0, 0, 19, 14), а не (100, 100, 119, 114).
Поскольку регион является GDI-объектом (подробнее в гл. 6), то для его удаления, если он не используется системой, применяется функция удаления GDI-объектов DeleteObject:
function DeleteObject(p1: HGDIOBJ): BOOL;
Регион как область отсечения при рисовании окна
Обычно регион нужно удалять в том случае, если он не используется системой, однако после того, как регион назначен окну в качестве области отсечения, удалять его не следует. Функция назначения региона окну имеет следующий вид:
function SetWindowRgn(hWnd: HWND; hRgn: HRGN; bRedraw: BOOL): Integer;
Функция возвращает 0, если произвести операцию не удалось, и ненулевое значение в случае успешного выполнения операции. Параметры функции SetWindowRgn следующие:
• hWnd – дескриптор окна, для которого устанавливается область отсечения (свойство Handle формы или элемента управления);
• hRgn – дескриптор региона, назначаемого в качестве области отсечения (в простейшем случае является значением, возвращенным одной из функций создания региона);
• bRedraw – флаг перерисовки окна после назначения новой области отсечения (для видимых окон обычно используется значение True, для невидимых – False).
Чтобы получить копию региона, формирующего область отсечения окна, можно использовать API-функцию GetWindowRgn:
function GetWindowRgn(hWnd: HWND; hRgn: HRGN): Integer;
Первый параметр функции – дескриптор (Handle) интересующего окна. Второй параметр – дескриптор предварительно созданного региона, который в случае успеха модифицируется функцией GetWindowRgn так, что становится копией региона, формирующего область отсечения окна. Значения целочисленных констант – возможных возвращаемых значений функции – следующие:
• NULLREGION – пустой регион;
• SIMPLEREGION – регион в форме прямоугольника;
• COMPLEXREGION – регион сложнее, чем прямоугольник;
• ERROR – при выполнении функции возникла ошибка либо окну задана область отсечения.
Далее приведен пример использования функции GetWindowRgn (предполагается, что приведенный ниже код является телом одного из методов класса формы).
var rgn: HRGN;
begin
rgn:= CreateRectRgn(0,0,0,0); //Первоначальная форма региона не важна
if GetWindowRgn(Handle, rgn) <> ERROR then
begin
//Операции с копией региона, формирующего область отсечения окна…
end;
DeleteObject(rgn); //Мы пользовались копией региона, которую должны
//удалить (здесь или в ином месте, но сами)
end;
Операции над регионами
При рассказе о функциях создания регионов неоднократно упоминалось о возможности комбинирования регионов для получения сложных форм. Пришло время кратко рассмотреть операции над регионами. Все операции по комбинированию регионов осуществляются с помощью функции CombineRgn:
function CombineRgn(p1, p2, p3: HRGN; p4: Integer): Integer;
Параметры этой функции следующие:
• p1 – регион (предварительно созданный), предназначенный для сохранения результата;
• p2, p3 – регионы-аргументы операции;
• p4 – тип операции над регионами.
Более подробно действие функции CombineRgn при различных значениях параметра p4 поясняется в табл. 1.2.
Таблица 1.2. Операции функции CombineRgn
Кроме приведенных в табл. 1.2 констант, в качестве параметра p4 функции CombineRgn можно использовать параметр RGN_COPY. При его использовании копируется регион, заданный параметром p2, в регион, заданный параметром p1.
Тщательно рассчитывая координаты точек регионов-аргументов, можно с использованием функции CombineRgn создавать регионы самых причудливых форм, в чем вы сможете убедиться ниже.
Наконец, после теоретического отступления можно рассмотреть несколько примеров создания и преобразования регионов, предназначенных для формирования области отсечения окон (форм и элементов управления на формах).
Закругленные окна и многоугольники