То,что необходимо программисту... Море самой разнообразной информации по самым разным вопросам...
Главная Новости Delphi C&C++ Графы.. Web-design Математика Исходники Lisp&Prolog Ссылки
Портал >> Программирование под Дельфи >> Как создать прозрачную форму в приложениях WINDOWS.
Быстрая навигация:
В разделы математики могут быть помещены и ваши статьи! Для этого достаточно прислать их по адресу mportal@yandex.ru.
Если статья по тематике, то мы опубликуем её! Ваше авторство будет обязательно указано.


Материал предоставлен: HTPI MEDIA STUDIO Inc.
Связь с нами:
Гостевая книга..
Media Studio.. io
Bear Corp.
Рейтинг ресурса:

Rambler's Top100
Rambler's Top100 Каталог Интернет ресурсов
Каталог Интернет ресурсов
be number one
Our Site Is Listed at WWW.RU
Сайт разработан:
Дизайн: Media Sudio & Bear Corner, Inc.

Последнее обновление: 5.05.2001.


Надеюсь,что читающий эту статью знает что такое form и form.handle (form->handle). Кроме того нам потребуется понятие region или по-русски регион. Регион, это многоугольник, эллипс или комбинация двух или более фигур из приведенного списка. Регионы используются для заливки, отсечения и других, не менее полезных операций.
Для работы с ними предусмотрены функции:
CreateRectRgn - создает прямоугольную область;
CreateEllipticRgn - создает эллиптическую область;
CreatePolygonRgn - создает многоугольник;
CombineRgn - позволяет объединять регионы между собой.
Этих пожалуй хватит.При помощи этих несложных функций программист может создать любую область (кому какая нравится). Теперь неплохо-бы связать с этой областью внешний вид нашей формы. Для этого нужно вызвать функцию SetWindowsRgn В которую следует передать handle нашей формы и region задающий её вид.

Ну вот скажите вы прочитав мое вступление. Я же замучаюсь комбинировать эти дурацкие регионы если мне нужно создать форму довольно сложного вида (к примеру в виде кролика или еще чего-нибудь) Интуитивно приходит решение и этой задачи. А что если мы будем создавать регионы из растровой картинки? Нарисовал рисунок, а дальше пусть машина сама создаст по нему форму (учитывая один или несколько прозрачных цветов). Но вот в чем проблема - WINDOWS не знает никакой функции типа BitmapToRigion или RegionFromBMP.. Придется написать самим..

(Далее я просто приведу функции для Delphi и CBuilder которые вы можете просто встроить в свои программы)

Для DELPHI:

//Преобразование растровой картинки в region
function BitmapToRegion(Bitmap: TBitmap; TransColor: TColor): HRGN;
var X,Y:Integer;
XStart:Integer;
begin
Result := 0;
with Bitmap do
for Y:=0 to Height-1 do begin
X := 0;
while X do begin
// Пропускаем прозрачные точки
while(X<Width and (Canvas.Pixels[X,Y]=TransColor)do Inc(X);
if X >= Width then Break;
XStart := X;
// Пропускаем непрозрачные точки
while(X<Width and (Canvas.Pixels[X,Y]<>TransColor)do Inc(X);
// Создаем новый прямоугольный регион и добавляем его к
// региону всей картинки
if Result=0 then Result:=CreateRectRgn(XStart, Y, X, Y + 1)
else CombineRgn(Result, Result,CreateRectRgn(XStart, Y, X, Y + 1), RGN_OR);
end;end;end;

Чтобы проверить работу функции создайте такой обработчик FormCreate

procedure TForm1.FormCreate(Sender: TObject);
var rgn:HRGN;
begin
rgn:=BitmapToRegion(image1.picture.bitmap,clLime);
setwindowrgn(form1.handle,rgn,true);
end;

Для CBUILDER
//Преобразование растровой картинки в region
HRGN ConvertBMPToRegion(TPicture *picture,TColor nulcolor) {

int x=0;
HRGN Result = 0;
for(int y=0;y<Bitmap->Height;y++)
{
x=0;
while(x<Bitmap->Width)
{
// Пропускаем прозрачные точки
while((x<Bitmap->Width)&&(picture->Bitmap->Canvas->Pixels[x][y]==nulcolor)) x++;
if(x>=picture->Bitmap->Width) break;
int XStart=x;
// Пропускаем непрозрачные точки
while((x<Bitmap->Width)&&(picture->Bitmap->Canvas->Pixels[x][y]!=nulcolor)) x++;
// Создаем новый прямоугольный регион и добавляем его к
// региону всей картинки
if(Result==0)
{
Result=CreateRectRgn(XStart, y, x, y + 1);
}else{
CombineRgn(Result, Result,CreateRectRgn(XStart, y, x, y + 1), RGN_OR);
}
}
}
return Result;
}

Ну и напоследок.. Если нужно создать форму на котрой видны только её компоненты то можно использовать например такую процедуру, которую следует вызвать при создании такой формы:
procedure TForm1.RebuildWindowRgn;
var
FullRgn, Rgn: THandle;
ClientX, ClientY, I: Integer;
begin
// определяем относительные координаты клиенской части
ClientX:= (Width - ClientWidth) div 2;
ClientY:= Height - ClientHeight - ClientX;
// создаем регион для всей формы
FullRgn:= CreateRectRgn(0, 0, Width, Height);
// создаем регион для клиентской части формы
// и вычитаем его из FullRgn
Rgn:= CreateRectRgn(ClientX, ClientY, ClientX + ClientWidth, ClientY +ClientHeight);
CombineRgn(FullRgn, FullRgn, Rgn, rgn_Diff);
// теперь добавляем к FullRgn регионы каждого контрольного элемента
for I:= 0 to ControlCount -1 do
with Controls[I] do begin
Rgn:= CreateRectRgn(ClientX + Left, ClientY + Top, ClientX + Left + Width, ClientY + Top + Height);
CombineRgn(FullRgn, FullRgn, Rgn, rgn_Or);
end;
// устанавливаем новый регион окна
SetWindowRgn(Handle, FullRgn, True);
end;
end.


Скачать исходники примера.

©Media Studio, 2001.

 

 

Hosted by uCoz