Главная » C++, C++ Builder » Реализация круглой кнопки в CBuilder

0

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

В процессе изменения образа кнопки есть два шага и используются две функции API. Первый шаг — создание образа (shape), который будет  потом  применен  к кнопке. Можете считать, что на этом шаге мы делаем заготовку из теста. Вы делаете заготовку, а затем раскатываете ее и придаете ей форму (ну, например, у моих детей получается в таком случае наполовину съеденная заготовка, но это отдельный рассказ). Второй шаг — «раскатать» заготовку на   окне.   Первый   шаг   реализуется   с   помощью   функции   API   CreateEllipticRgn   (создать эллиптическую область). Эта функция — вариант функции CreatePolygonRgn (создать многоугольную область). На самом деле функций, создающих области, мало: CreateRectRgn, CreateEllipticRgn, CreateRoundRectRgn и CreatePolygonRgn. Каждая из них, как вы  можете узнать из файла Win32SDK.hlp, создает свой тип отображаемой области. Если вы хотите получить хитрую область, то можете вызвать несколько этих функций для создания нескольких областей, а затем скомбинировать их функцией API CombineRgn. Это позволит вам, например, создать область в виде бублика. Когда вы создали область, вы применяете ее  к  окну  («раскатываете тесто»), используя функцию SetWindowRgn.

Лучше всего создавать область для окна при создании формы. Создайте обработчик события формы OnCreate и добавьте в метод FormCreate следующий код:

void __fastcall TForm1::FormCreate(TObject *Sender)

{

HRGN hRgn = CreateEllipticRgn(

0, // x-координата левого верхнего угла

// ограничивающего прямоугольника

0, // y-координата левого верхнего угла

// ограничивающего прямоугольника

Button1->Width, // x-координата правого нижнего

// угла ограничивающего прямоугольника

Button1->Height // y-координата правого нижнего

// угла ограничивающего прямоугольника

);

SetWindowRgn (Button1->Handle, hRgn, TRUE);

}

Этот код создает эллиптическую область внутри границ кнопки и затем присваивает ее кнопке как новую область окна. Заметьте, что область должна быть определена в координатах относительно кнопки, а не относительно экрана. Точка 0,0 — это левый верхний угол кнопки, а точка Width,Height — правый нижний угол кнопки.

Замечание

Очень важно, чтобы вы больше ничего не делали со ссылкой (handle) на область после присваивания ее окну. Самое невинное, что случится при изменении или удалении этой ссылки, — падение программы, самое худшее — обвал системы. В данный момент у вас  есть кнопка  на форме, которая отображает себя как эллипс, и следующим шагом является написание кода, делающего то же самое с формой. Перед тем как это cделать, установите свойство формы BorderStyle (стиль рамки) в bsNone (то есть без рамки). Иначе вы будете видеть  части  рамки формы, вылезающие за эллипс, что выглядит некрасиво. Кроме того, заметьте, что на картинку, положенную на форму, также оказывает влияние округлость формы: картинка  отрисовывается только внутри области формы.

Добавьте этот код в метод FormCreate (после кода, который вы только что ввели для кнопки), который делает форму эллиптической:

HRGN hRgn1 = CreateEllipticRgn(

0, // x-координата левого верхнего угла

// ограничивающего прямоугольника

0, // y-координата левого верхнего угла

// ограничивающего прямоугольника

Width, // x-координата правого нижнего

// угла ограничивающего прямоугольника

Height // y-координата правого нижнего

// угла ограничивающего прямоугольника

);

SetWindowRgn (Handle, hRgn1, TRUE);

Код в точности такой же, как и для кнопки. Единственное, что не упоминается Button при обращении к свойствам. Это не так уж удивительно. Все окна одинаковы с точки зрения областей (regions), которые их ограничивают. Например, вы могли бы создать круглое окно списка, круглый список каталогов или окно диалога. Это может странно выглядеть, но такие вещи возможны.

Вы, вероятно, заметите, что кнопка выглядит странно,  когда она отображена  в  эллиптическом виде. Это из-за рамки у кнопки. Напрямую невозможно изменить рамку кнопки, только наследуя новый компонент от класса button. Это можно сделать, но это далеко не так просто, как сделать кнопку круглой.

Этим мы завершаем дискуссию о круглой форме. Все, что потребовалось, — по два вызова двух разных функций Windows API. Теперь вы понимаете, почему так важно знать, что можно сделать с помощью Windows API? Представьте себе, каких трудов стоило бы создать круглую форму без этих двух функций.

Источник: Теллес М. – Borland C++ Builder. Библиотека программиста – 1998

По теме:

  • Комментарии