Aufgrund einer Frage im englischen Forum (rotate any control) habe ich mich mal rangesetzt um so etwas zu realisieren aber stoße an meine Grenzen und würde gerne mal Wissen wie es richtig gemacht wird und ob es dafür auch eine crossplatform variante gibt, ich habe es mit Hilfe der Windows API versucht zu lösen.
Im Anhang ist mein komplettes Demo projekt, es funktioniert soweit auch ganz gut aber ich habe arge probleme das wenn ich mein control drehe es nicht mehr in die Dimensionen passt und somit abgeschnitten gezeichnet wird.
Ich habe es kommentiert so gut ich konnte damit man nachvollziehen kann was ich da so versuche

Hier der problematische Teil:
Code: Alles auswählen
procedure TMyButton.Paint;
var
SavedLeft, SavedTop: Integer;
SavedDC: Integer;
XForm: TXForm;
R: TRect;
Size: TSize;
lp: TPoint;
dp: TPoint;
begin
SavedDC := SaveDC(Self.Canvas.Handle);
try
SetGraphicsMode(Self.Canvas.Handle, GM_ADVANCED);
// Save the current transformation matrix
GetWorldTransform(Self.Canvas.Handle, XForm);
XForm.eM11 := Cos(DegToRad(FAngle));
XForm.eM12 := Sin(DegToRad(FAngle));
XForm.eM21 := -Sin(DegToRad(FAngle));
XForm.eM22 := Cos(DegToRad(FAngle));
XForm.eDx := 0;
XForm.eDy := 0;
// Save the original Left and Top properties
SavedLeft := Self.Left;
SavedTop := Self.Top;
// Apply the rotation transformation
SetWorldTransform(Self.Canvas.Handle, XForm);
// Get the bounding rectangle of the rotated text
GetTextExtentPoint32(Self.Canvas.Handle, PChar(FText), Length(FText), Size);
lp.x := Size.cx;
lp.y := Size.cy;
LPtoDP(Self.Canvas.Handle, lp, 1);
// Calculate the new width and height
dp.x := Round(lp.x * XForm.eM11 + lp.y * XForm.eM21);
dp.y := Round(lp.x * XForm.eM12 + lp.y * XForm.eM22);
// Set the bounding rectangle
SetRect(R, 0, 0, dp.x, dp.y);
// Restore the original transformation matrix
SetWorldTransform(Self.Canvas.Handle, XForm);
// Draw the background
Self.Canvas.Brush.Color := clBtnFace; // Set the background color
Self.Canvas.FillRect(Rect(0, 0, Self.Width, Self.Height)); // Fill the control with the background color
// Draw the border
Self.Canvas.Pen.Color := clWindowFrame; // Set the border color
Self.Canvas.Rectangle(0, 0, Self.Width-1, Self.Height-1); // Draw the border
// Draw the text
Self.Canvas.Pen.Color := clBtnText; // Set the font color
R := Rect(0, 0, Self.Width, Self.Height);
DrawText(Self.Canvas.Handle, PChar(FText), Length(FText), R, DT_CENTER or DT_VCENTER or DT_SINGLELINE);
// Restore the original Left and Top properties
Self.Left := SavedLeft;
Self.Top := SavedTop;
finally
RestoreDC(Self.Canvas.Handle, SavedDC);
end;
end;