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