Einzelnen Beitrag anzeigen

Alter Mann

Registriert seit: 15. Nov 2003
Ort: Berlin
946 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#9

AW: Compare TRect, wie am besten angehen?

  Alt 24. Jun 2015, 19:17
Hallo,

Ja das sieht komisch aus, aber dankR := Control.ClientRect; werden genau(nur) R.Right und R.Bottom gesetzt.
Nur R.Top und R.Left muss man sich 'umständlich' via R.TopLeft := Self.ScreenToClient(Control.ClientToScreen(Point(0, 0))); holen.
Auf Height und Width bin ich in diesem Zusammenhang gar nicht gekommen.

Ich habe aber das ursprüngliche Problem anders gelöst und eine Anleihe bei TObjectList genommen. Heraus gekommen sind:
Delphi-Quellcode:
  TRectEntry = class(TObject)
  private
    FLeft : Integer;
    FTop : Integer;
    FRight : Integer;
    FBottom : Integer;
    FControl : TControl;
  public
    constructor Create(Control : TControl; Rect : TRect);
    destructor Destroy; override;

    property Left : Integer read FLeft;
    property Top : Integer read FTop;
    property Right : Integer read FRight;
    property Bottom : Integer read FBottom;
    property Control: TControl read FControl;
  end;

  TSortOrder = (soTopBottom, soLeftRight);

  TRectList = class(TList)
  private
    FOwnsObjects: Boolean;
    FSortOrder : TSortOrder;
    procedure SetSortOrder(Value : TSortOrder);
  protected
    procedure Notify(Ptr: Pointer; Action: TListNotification); override;
    function GetItem(Index: Integer): TRectEntry;
    function FindNextIndex(X : Integer) : Integer;
  public
    constructor Create; overload;
    constructor Create(AOwnsObjects: Boolean); overload;

    function Add(aRectEntry : TRectEntry): Integer;

    property Items[Index: Integer]: TRectEntry read GetItem;
    property OwnsObjects: Boolean read FOwnsObjects write FOwnsObjects;
    property SortOrder : TSortOrder read FSortOrder write SetSortOrder default soTopBottom;
  end;
In der RectList sind die beiden Funktionen Add und FindNextIndex, die jenigen, die
bei mir zum Ziel führen:
Delphi-Quellcode:
...
constructor TRectEntry.Create(Control : TControl; Rect : TRect);
begin
  inherited Create;
  FControl := Control;
  FLeft := Rect.Left;
  FTop := Rect.Top;
  FRight := Rect.Right;
  FBottom := Rect.Bottom;
end;
...
function TRectList.FindNextIndex(X : Integer) : Integer;
var
  I : Integer;
begin
  Result:= -1;
  case SortOrder of
    soTopBottom : begin
                    for I := 0 to Count - 1 do
                    begin
                      if Items[I].Top > X then
                      begin
                        Result := I;
                        Break;
                      end
                      else
                      if Items[I].Bottom = X then
                      begin
                        if I = Count-1 then Result := -1
                                       else Result := I+1;
                        Break;
                      end;
                    end;
                  end;
    soLeftRight : begin
                    for I := 0 to Count - 1 do
                    begin
                      if Items[I].Left > X then
                      begin
                        Result := I;
                        Break;
                      end
                      else
                      if Items[I].Right = X then
                      begin
                        if I = Count-1 then Result := -1
                                       else Result := I+1;
                        Break;
                      end;
                    end;
                  end;
  end;
end;

function TRectList.Add(aRectEntry : TRectEntry): Integer;
var
  Idx : Integer;
begin
  Result := -1;
  case SortOrder of
    soTopBottom: if Count > 0 then
                 begin
                  Idx := FindNextIndex(aRectEntry.Top);
                  if (Idx > -1) then
                  begin
                    Insert(Idx, aRectEntry);
                    Result := IndexOf(aRectEntry);
                  end
                  else
                    Result := inherited Add(aRectEntry);
                 end
                 else
                 Result := inherited Add(aRectEntry);
    soLeftRight: if Count > 0 then
                 begin
                  Idx := FindNextIndex(aRectEntry.Left);
                  if (Idx > -1) then
                  begin
                    Insert(Idx, aRectEntry);
                    Result := IndexOf(aRectEntry);
                  end
                  else
                    Result := inherited Add(aRectEntry);
                 end
                 else
                 Result := inherited Add(aRectEntry);
  end;
end;
Gefüllt wird die RectList über so:
Delphi-Quellcode:
  
...
  for I := 0 to ControlCount - 1 do
  begin
    R := Controls[I].ClientRect;
    R.TopLeft := ScreenToClient(Controls[I].ClientToScreen(Point(0,0)));
    R.Right := R.Left + R.Right;
    R.Bottom := R.Top + R.Bottom;
    FRectList.Add(TRectEntry.Create(Controls[I], R));
  end;
Etwas besseres ist mir nicht eingefallen, aber vielleicht weiß ja hier jemand wie
das Problem eleganter gelöst werden kann.
Angehängte Dateien
Dateityp: zip RectSort.zip (16,1 KB, 0x aufgerufen)
  Mit Zitat antworten Zitat