Stefan M. Huber
2017-02-28 11:03:44 UTC
Servus!
Wir migrieren gerade von XE7 zu Berlin. Leider gibt es mit ScaleBy
Probleme, die auch bereits dokumentiert sind:
https://quality.embarcadero.com/browse/RSP-15414
https://quality.embarcadero.com/browse/RSP-15462
oder halt gleich
https://quality.embarcadero.com/browse/RSP-15092?jql=text%20~%20%22scaleby%22
Kurz umrissen: ScaleBy verhaut komplett das UI, je nachdem, ob man
AutoSize, Align oder Anchors verwendet. Grausam.
Ich versuche gerade da irgendwie rumzuarbeiten, aber so richtig will das
nicht. Hat jemand schon Gehversuche, die funktionieren?
Momentan machen wir das hier (Wir haben eine zentrale Funktion, die das
Skalieren übernimmt):
Formular.PixelsPerInch := Round(StartPBI*SkalierFaktor);
// instead of default FormScaleBy(Formular, Round(SkalierFaktor*100),
100) we do this:
HF := THackForm(Formular);
HF.ScaleBy(Round(SkalierFaktor*100), 100);
wobei das THackForm in der Unit liegt, wo auch die Funktion zu finden
ist und so ausschaut:
type THackForm = class(TForm)
protected
procedure ScaleBy(M, D: Integer);
procedure ChangeScale(M, D: Integer);
end;
end;
[...]
procedure THackForm.ChangeScale(M, D: Integer);
var
X, Y, W, H: Integer;
Flags: TScalingFlags;
begin
if M <> D then
begin
if csLoading in ComponentState then
Flags := ScalingFlags else
Flags := DefaultScalingFlags;
if sfLeft in Flags then
X := MulDiv(Left, M, D) else
X := Left;
if sfTop in Flags then
Y := MulDiv(Top, M, D) else
Y := Top;
if (sfWidth in Flags) and not (csFixedWidth in ControlStyle) then
if sfLeft in Flags then
W := MulDiv(Left + Width, M, D) - X else
W := MulDiv(Width, M, D)
else W := Width;
if (sfHeight in Flags) and not (csFixedHeight in ControlStyle) then
if sfTop in Flags then
H := MulDiv(Top + Height, M, D) - Y else
H := MulDiv(Height, M, D)
else H := Height;
ScaleConstraints(M, D);
ScaleMargins(M, D);
SetBounds(X, Y, W, H);
if [sfLeft, sfWidth] * Flags <> [] then
FOriginalParentSize.X := MulDiv(FOriginalParentSize.X, M, D);
if [sfTop, sfHeight] * Flags <> [] then
FOriginalParentSize.Y := MulDiv(FOriginalParentSize.Y, M, D);
if not ParentFont and (sfFont in Flags) then
Font.Size := MulDiv(Font.Size, M, D);
end;
ScalingFlags := [];
end;
procedure THackForm.ScaleBy(M, D: Integer);
const
SWP_HIDE = SWP_NOSIZE + SWP_NOMOVE + SWP_NOZORDER + SWP_NOACTIVATE +
SWP_HIDEWINDOW;
SWP_SHOW = SWP_NOSIZE + SWP_NOMOVE + SWP_NOZORDER + SWP_NOACTIVATE +
SWP_SHOWWINDOW;
var
IsVisible: Boolean;
R: TRect;
HF: THackForm;
begin
HF := THackForm(Self);
IsVisible := HandleAllocated and IsWindowVisible(Handle);
if IsVisible then SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_HIDE);
R := BoundsRect;
HF.ChangeScale(M, D);
SetBounds(R.Left, R.Top, Width, Height);
if IsVisible then SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_SHOW);
end;
Wir migrieren gerade von XE7 zu Berlin. Leider gibt es mit ScaleBy
Probleme, die auch bereits dokumentiert sind:
https://quality.embarcadero.com/browse/RSP-15414
https://quality.embarcadero.com/browse/RSP-15462
oder halt gleich
https://quality.embarcadero.com/browse/RSP-15092?jql=text%20~%20%22scaleby%22
Kurz umrissen: ScaleBy verhaut komplett das UI, je nachdem, ob man
AutoSize, Align oder Anchors verwendet. Grausam.
Ich versuche gerade da irgendwie rumzuarbeiten, aber so richtig will das
nicht. Hat jemand schon Gehversuche, die funktionieren?
Momentan machen wir das hier (Wir haben eine zentrale Funktion, die das
Skalieren übernimmt):
Formular.PixelsPerInch := Round(StartPBI*SkalierFaktor);
// instead of default FormScaleBy(Formular, Round(SkalierFaktor*100),
100) we do this:
HF := THackForm(Formular);
HF.ScaleBy(Round(SkalierFaktor*100), 100);
wobei das THackForm in der Unit liegt, wo auch die Funktion zu finden
ist und so ausschaut:
type THackForm = class(TForm)
protected
procedure ScaleBy(M, D: Integer);
procedure ChangeScale(M, D: Integer);
end;
end;
[...]
procedure THackForm.ChangeScale(M, D: Integer);
var
X, Y, W, H: Integer;
Flags: TScalingFlags;
begin
if M <> D then
begin
if csLoading in ComponentState then
Flags := ScalingFlags else
Flags := DefaultScalingFlags;
if sfLeft in Flags then
X := MulDiv(Left, M, D) else
X := Left;
if sfTop in Flags then
Y := MulDiv(Top, M, D) else
Y := Top;
if (sfWidth in Flags) and not (csFixedWidth in ControlStyle) then
if sfLeft in Flags then
W := MulDiv(Left + Width, M, D) - X else
W := MulDiv(Width, M, D)
else W := Width;
if (sfHeight in Flags) and not (csFixedHeight in ControlStyle) then
if sfTop in Flags then
H := MulDiv(Top + Height, M, D) - Y else
H := MulDiv(Height, M, D)
else H := Height;
ScaleConstraints(M, D);
ScaleMargins(M, D);
SetBounds(X, Y, W, H);
if [sfLeft, sfWidth] * Flags <> [] then
FOriginalParentSize.X := MulDiv(FOriginalParentSize.X, M, D);
if [sfTop, sfHeight] * Flags <> [] then
FOriginalParentSize.Y := MulDiv(FOriginalParentSize.Y, M, D);
if not ParentFont and (sfFont in Flags) then
Font.Size := MulDiv(Font.Size, M, D);
end;
ScalingFlags := [];
end;
procedure THackForm.ScaleBy(M, D: Integer);
const
SWP_HIDE = SWP_NOSIZE + SWP_NOMOVE + SWP_NOZORDER + SWP_NOACTIVATE +
SWP_HIDEWINDOW;
SWP_SHOW = SWP_NOSIZE + SWP_NOMOVE + SWP_NOZORDER + SWP_NOACTIVATE +
SWP_SHOWWINDOW;
var
IsVisible: Boolean;
R: TRect;
HF: THackForm;
begin
HF := THackForm(Self);
IsVisible := HandleAllocated and IsWindowVisible(Handle);
if IsVisible then SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_HIDE);
R := BoundsRect;
HF.ChangeScale(M, D);
SetBounds(R.Left, R.Top, Width, Height);
if IsVisible then SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_SHOW);
end;