![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
форма нестандартной формы.
syte_ser78 © (2005-05-19 22:59:00)подскажите, как создать окно - непрямоугольной формы?
kat (2005-05-19 23:12:00) [1]Как создать регион(HRNG) по маске
Ниже приведена функция, которая создаёт HRGN из чёрно-белого битмапа. Все чёрные пиксели становятся регионом, а белые становятся прозрачными. Так же не составит труда сделать преобразования для поддержки всех цветов и чтобы один из них был прозрачным.
По окончании необходимо освободить регион при помощи функции DeleteObject.
function BitmapToRgn(Image: TBitmap): HRGN;
var
TmpRgn: HRGN;
x, y: integer;
ConsecutivePixels: integer;
CurrentPixel: TColor;
CreatedRgns: integer;
CurrentColor: TColor;
begin
CreatedRgns := 0;
Result := CreateRectRgn(0, 0, Image.Width, Image.Height);
inc(CreatedRgns);
if (Image.Width = 0) or (Image.Height = 0) then exit;
for y := 0 to Image.Height - 1 do
begin
CurrentColor := Image.Canvas.Pixels[0,y];
ConsecutivePixels := 1;
for x := 0 to Image.Width - 1 do
begin
CurrentPixel := Image.Canvas.Pixels[x,y];
if CurrentColor = CurrentPixel
then inc(ConsecutivePixels)
else begin
// Входим в новую зону
if CurrentColor = clWhite then
begin
TmpRgn := CreateRectRgn(x-ConsecutivePixels, y, x, y+1);
CombineRgn(Result, Result, TmpRgn, RGN_DIFF);
inc(CreatedRgns);
DeleteObject(TmpRgn);
end;
CurrentColor := CurrentPixel;
ConsecutivePixels := 1;
end;
end;
if (CurrentColor = clWhite) and (ConsecutivePixels > 0) then
begin
TmpRgn := CreateRectRgn(x-ConsecutivePixels, y, x, y+1);
CombineRgn(Result, Result, TmpRgn, RGN_DIFF);
inc(CreatedRgns);
DeleteObject(TmpRgn);
end;
end;
end;
Как создавать не квадратные формы и контролы
Всё, что нам нужно, это HRGN и дескриптор (handle) элемента управления. SetWindowRgn имеет три параметра: дескриптор окна, которое будем менять, дескритор региона и булевый (boolean) параметр, который указывает - перерисовывать или нет после изменения. Как только у нас есть дескриптор и регион, то можно вызвать SetWindowRgn(Handle, Region, True) и вуаля!
Здесь приведён пример использования функции BitmapToRgn (описанной в примере Как создать регион(HRNG) по маске).
Заметьте, что Вы не должны освобождать регион при помощи DeleteObject, так как после вызова SetWindowRgn владельцем региона становится операционная система.
var
MaskBmp: TBitmap;
begin
MaskBmp := TBitmap.Create;
try
MaskBmp.LoadFromFile('FormShape.bmp');
Height := MaskBmp.Height;
Width := MaskBmp.Width;
// ОС владеет регионом, после вызова SetWindowRgn
SetWindowRgn(Self.Handle, BitmapToRgn(MaskBmp), True);
finally
MaskBmp.Free;
end;
end;
syte_ser78 (2005-05-19 23:08:00) [2]СПАСИБО!!!!
easy (2005-05-19 23:05:00) [3]
procedure TForm1.FormCreate(Sender: TObject);
var
rgn:HRGN;
begin
rgn:=CreateEllipticRgn(0,0,width,height);
setwindowrgn(handle,rgn,true);
deleteobject(rgn);
end;
Eraser (2005-05-19 23:04:00) [4]syte_ser78 ©
property TransparentColor: TColor;
palva (2005-05-19 23:03:00) [5]Сделать форму без рамки с прозрачным фоном, на ней разместить рисунок нужной формы, а уже на нем остальные контролы. Только, боюсь, клик по прозрачной части окна будет обрабатываться именно этим окном, а не тем, что просвечивает сквозь него.