Это простая функция, которая возвращает новую область (регион), повернутую на угол, какой Вы задаете относительно исходной области. Исходная область не изменяется.
Вторая процедура делает то же самое с исходной областью без создания новой области (региона).
function _RotateRgn(ARgn : HRGN; ADegree : Real) : HRGN;
var
wXFORM : XFORM; // структура трансформации, см. Windows API
kRgnD : DWord; // количество структур RGNDATA в регионе
RgnData : PRgnData; // указатель на данные региона
Rt : TRect;
kX, kY : Integer;
begin
if (ARgn = 0) or (ADegree = 0) then
Exit;
// Получить окружность прямоугольной области
GetRgnBox(ARgn, Rt);
// Переместить исходный регион так, чтобы центр окружности проходил
// по левому верхнему углу окна
kX := Rt.Left+(Rt.Right -Rt.Left) div 2;
kY := Rt.Top +(Rt.Bottom-Rt.Top) div 2;
OffsetRgn(ARgn, -kX, -kY);
// Заполнить XFORM согласно задаче (повернуть регион)
FillChar(wXFORM, SizeOf(wXFORM), #0);
wXFORM.eM11 := Cos(ADegree/180*pi);
wXFORM.eM12 := -Sin(ADegree/180*pi);
wXFORM.eM21 := -wXFORM.eM12;
wXFORM.eM22 := wXFORM.eM11;
// Подготовить буфер для хранения данных региона
kRgnD := GetRegionData(ARgn, 0, nil);
GetMem(RgnData, SizeOf(RGNDATA) * kRgnD);
// ..и заполнить буфер данными региона
GetRegionData(ARgn, kRgnD, RgnData);
// ..переместить начальный регион в его начальную позицию
OffsetRgn(ARgn, kX, kY);
// Создать выходной регион, используя данные в буфере и преобразованном wXFORM
Result := ExtCreateRegion(@wXFORM, kRgnD, RgnData^);
// Переместить выходной регион на место исходного
OffsetRgn(Result, kX, kY);
FreeMem(RgnData);
end;
procedure _RotateRgnEx(Var ARgn : HRGN; ADegree : Real);
var
wXFORM : XFORM;
kRgnD : DWord;
RgnData : PRgnData; // указатель на данные региона
Rt : TRect;
kX, kY : Integer;
begin
if (ARgn = 0) or (ADegree = 0) then
Exit;
GetRgnBox(ARgn, Rt);
kX := Rt.Left+(Rt.Right -Rt.Left) div 2;
kY := Rt.Top +(Rt.Bottom-Rt.Top) div 2;
OffsetRgn(ARgn, -kX, -kY);
FillChar(wXFORM, SizeOf(wXFORM), #0);
wXFORM.eM11 := Cos(ADegree/180*pi);
wXFORM.eM12 := -Sin(ADegree/180*pi);
wXFORM.eM21 := -wXFORM.eM12;
wXFORM.eM22 := wXFORM.eM11;
kRgnD := GetRegionData(ARgn, 0, nil);
GetMem(RgnData, SizeOf(RGNDATA) * kRgnD);
GetRegionData(ARgn, kRgnD, RgnData);
DeleteObject(ARgn);
ARgn := ExtCreateRegion(@wXFORM, kRgnD, RgnData^);
// Перемещаем выходной регион на место оригинала
OffsetRgn(ARgn, kX, kY);
FreeMem(RgnData);
end;
|