• добавить в избранное •
abyss-group

Звездные окна. ifcity.info

Вы хотите чтобы ваше приложение было замечено потребителем ? Немалую роль в этом играет оформление. Оформление это не только удобный интерфейс и красивые картинки. Как правило запоминаются приложения, которые выделяются из общей массы чем-то особенным. Предлагаю Вам создать формы нестандартной формы. Если Вас интересует создание окон в виде звезды или еще более вычурной формы, то располагайтесь поудобнее и читайте дальше эту статью.

Начнем мы с рассмотрения работы с регионами в Windows. Регион в Windows представляет собой некоторую замкнутую фигуру. Например круг или звезда, или прямоугольник и т.д. Давайте рассмотрим примеры построения таких регионов. Первая функция для построения регионов:

function CreateEllipticRgn (Left,Top,Right,Bottom: integer) : HRGN
Данная функция создает область представляющую собой элипс вписаный в прямоугольник, координаты которого задаются с помощью параметров Left,Top,Right,Bottom. Функция возвращает дескриптор области, с помощью которого можно будет в дальнейшем с ней работать.

function CreateEllipticRgnIndirect( Rect: TRect) : HRGN;
Данная функция по действию аналогична предыдущей, только параметры прямоугольника задаются структурой TRect.

function CreatePolygonRgn(const Points; nPoints, FillMode: integer): HRGN;
Создает регион, форма которого определяется массивом Points, который задается слеующим образом: Points: array [1..nPoints] of TPoint; nPoints , как Вы уже поняли, это количество точек. FillMode - определет какая именно область войдет в регион. Здесь как мне кажется этот параметр особого значения не имеет и как правило устанавливается равным ALTERNATE.

function CreatePolyPolygonRgn(const pPtStruct; const pIntArray; nCount, FillMode: integer): HRGN;
Создает регион, который состоит из нескольких регионов. pPtStruct - это как бы массив массивов, т.е. массив элементами которого являются массивы вида array [1..n] of TPoint, каждый такой элемент представляет собой отдельный регион. pIntArray - массив, элементы которого показывают количестов вершин в соответствующем регионе nCount - количество задаваемых регионов. FillMode - режим заполнения.

function CreateRectRgn (Left,Top,Right,Bottom: integer) : HRGN;
Создает прямоугольный регион.

function CreateRectRgnIndirect( Rect: TRect) : HRGN;
Тоже создает прямоугольный регион, но его положение и размер задаются через структуру TRect.

function CreateRoundRectRgn (Left,Top,Right,Bottom, WidthEl,HeightEl: integer) : HRGN;
Создает прямоугольный регион (размеры Left,Top,Right,Bottom) с закругленными углами. Параметры WidthEl и HeightEl определяют параметры закругления.

Данные регионы можно использовать для построения более сложных регионов, путем комбинирования.

function CombineRgn( Dest, Source1, Source2: HRGN; mode: integer): integer;
Функция комбинирует два региона Source1 и Source2 и получает новый регион Dest. Mode - это режим комбинирования регионов, значения параметра приведены в таблице.

Значение Описание
RGN_AND Результат комбинирования - пересечение регионов
RGN_COPY Результат - копия региона Source1
RGN_DIFF Результат - часть региона Source1 которая не принадлежит региону Source2
RGN_OR Результат - объединение двух регионов
RGN_XOR Результат - объединение регионов минус их пересечение

Таким образом мы научились создавать регионы практически любой формы. А теперь научимся изменять форму окна. Для этого применяется следующая функция:

function SetWindowRgn(hWnd: THandle; Rgn: HRGN; RDraw: boolean): integer;
Данная функция для окна с дескриптором hWnd устанавливает новую область отображения, которую определяет созданный регион Rgn. Регион может быть любой формы. Параметр RDraw установленный в TRUE указывает операционной системе перерисовать окно после изменения его области отображения. Т.е. теперь все что есть на форму будет так же работать как и всегда, но отображаться будет только то, что попало в указанный регион.

Сейчас мы рассмотрим еще две полезные функции и после этого построим форму в виде звезды, которая хорошо подойдет для окна About.

function PtInRegion (Rgn: HRGN; X,Y: integer): boolean;
Функция определяет попала ли точка (X,Y) в регион Rgn.

function FrameRgn(DC:THandle;Rgn:HRGN;Brush:THandle;W,H:integer):boolean;
Функция рисует рамку для региона Rgn; DC - дескриптор плотна, на котором рисуем рамку; Brush - кисть которой рисуем; W, H - параметры рамки (ширина и высота).

Ну а теперь построим форму, которая имеет форму звезды и перетягивается только за заголовок, который будет обозначен на форме синим цветом. Для начала в обработчике OnCreate мы создаем нужный регион и присваиваем его нашей форме, ниже представлен листинг соответствующей процедуры:

Прошу не забыть предварительно объявит переменные rTitle и rBound. Это можно сделать в разделе private объявления класса:

Таким образом, мы создали окно не стандартной формы, теперь научимся рисовать ему рамку и перетаскивать за заголовок. Отображение рамки и заголовка производится в обработчике события onPaint.

Надеюсь листинг комментирован достаточно для хорошего понимания, тем более что функции были описаны в начале статьи. Теперь рассмотрим принцип перетаскивания окна за новый заголовок, для этого нам надо обрабатывать сообщение WM_NCHITTEST (как это сделать см. статью 'Перетаскивание окна за рабочую область'), теперь задача стоит немного другая и с ней справляется слеующий листинг:

Также перед запуском приложения следует предусмотреть его закрытие, для этого бросьте на форму кнопку и приспособьте ее для закрытия окна. Следует помнить, что в результирующем окне будет отображаться все, что попадает в новый регион, т.е. вы можете также мастерить интерфейс в среде Delphi, создавать кнопки, статический текст и т.д., но в итоге будет отображено только то, что попадет пределы нового региона. Будьте внимательны. А теперь можете приступить к созданию своих окон необычной формы.

• программирование •

• copyright © 2002-2003 «abyss-group» •
Hosted by uCoz