Простой способ поворота области (региона)
Вторая процедура делает то же самое с исходной областью без создания новой области (региона).
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;
Комментарии