BidiUtils.pas 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. unit BidiUtils;
  2. {
  3. Inno Setup
  4. Copyright (C) 1997-2025 Jordan Russell
  5. Portions by Martijn Laan
  6. For conditions of distribution and use, see LICENSE.TXT.
  7. Bidi utility functions
  8. }
  9. interface
  10. uses
  11. Windows, SysUtils, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
  12. procedure FlipControls(const AParentCtl: TWinControl);
  13. procedure FlipRect(var Rect: TRect; const ParentRect: TRect; const UseRightToLeft: Boolean);
  14. function IsParentFlipped(const AControl: TControl): Boolean;
  15. var
  16. { This callback should be set by the caller. Inno Setup: set by the Setup.SetupForm unit: }
  17. IsParentFlippedFunc: function(AControl: TControl): Boolean;
  18. implementation
  19. procedure FlipRect(var Rect: TRect; const ParentRect: TRect; const UseRightToLeft: Boolean);
  20. var
  21. W: Integer;
  22. begin
  23. if UseRightToLeft then begin
  24. W := Rect.Right - Rect.Left;
  25. Rect.Left := ParentRect.Right - (Rect.Left - ParentRect.Left) - W;
  26. Rect.Right := Rect.Left + W;
  27. end;
  28. end;
  29. function IsParentFlipped(const AControl: TControl): Boolean;
  30. begin
  31. if Assigned(IsParentFlippedFunc) then
  32. Result := IsParentFlippedFunc(AControl)
  33. else
  34. Result := False;
  35. end;
  36. type
  37. TControlAccess = class(TControl);
  38. procedure FlipControls(const AParentCtl: TWinControl);
  39. var
  40. ParentWidth, I: Integer;
  41. Ctl: TControl;
  42. begin
  43. if AParentCtl.ControlCount = 0 then
  44. Exit;
  45. AParentCtl.DisableAlign;
  46. try
  47. ParentWidth := AParentCtl.ClientWidth;
  48. for I := 0 to AParentCtl.ControlCount-1 do begin
  49. Ctl := AParentCtl.Controls[I];
  50. if (akLeft in Ctl.Anchors) and not (akRight in Ctl.Anchors) then
  51. Ctl.Anchors := Ctl.Anchors - [akLeft] + [akRight]
  52. else if not (akLeft in Ctl.Anchors) and (akRight in Ctl.Anchors) then begin
  53. { Before we can set Anchors to [akLeft, akTop] (which has a special
  54. 'no anchors' meaning to VCL), we first need to update the Explicit*
  55. properties so the control doesn't get moved back to an old position. }
  56. if Ctl.Anchors = [akTop, akRight] then
  57. TControlAccess(Ctl).UpdateExplicitBounds;
  58. Ctl.Anchors := Ctl.Anchors - [akRight] + [akLeft];
  59. end;
  60. Ctl.Left := ParentWidth - Ctl.Width - Ctl.Left;
  61. end;
  62. finally
  63. AParentCtl.EnableAlign;
  64. end;
  65. for I := 0 to AParentCtl.ControlCount-1 do
  66. if AParentCtl.Controls[I] is TWinControl then
  67. FlipControls(TWinControl(AParentCtl.Controls[I]));
  68. end;
  69. end.