unit AppsLayout; interface uses Windows, Classes, SysUtils, StrUtils, Controls, Math; type /// /// 控制所以APP按钮的布局 /// TAppsLayout = class private FCol, FRow, FPageCount, FPageIndex: Integer; FClientRect: TRect; FApps: TStringList; FAppCountInPage: Integer; FFirstAppRect: TRect; FVisible: Boolean; procedure SetClientRect(const Value: TRect); procedure SetCol(const Value: Integer); procedure SetPageIndex(const Value: Integer); procedure SetRow(const Value: Integer); procedure SetVisible(const Value: Boolean); procedure SetAllControlCanntVisible; /// /// 根据FCol、FRow和FClientRect,得到PageCount、首个App显示区域和单页可以显示个数 /// 如果PageCount < PageIndex, 需要重置PageIndex /// procedure Calculate; /// /// 更具FPageIndex显示页数 /// procedure ShowPage; public constructor Create; destructor Destroy; override; procedure AddAppBtn(AAppBtn: TControl); procedure RemoveAppBtn(AAppBtn: TControl); /// /// 根据首个App显示区域、FCol和FRow,布局好引用 /// procedure Layout; property Col: Integer read FCol write SetCol; property Row: Integer read FRow write SetRow; property PageIndex: Integer read FPageIndex write SetPageIndex; property ClientRect: TRect read FClientRect write SetClientRect; property Visible: Boolean read FVisible write SetVisible; property PageCount: Integer read FPageCount; property Apps: TStringList read FApps; end; implementation { TAppLayout } procedure TAppsLayout.AddAppBtn(AAppBtn: TControl); begin AAppBtn.Visible := False; FApps.AddObject(IntToStr(FApps.Count), AAppBtn); end; procedure TAppsLayout.Calculate; var w, h: Integer; begin //如果区域没显示就不进行计算,也不进行显示 if (FClientRect.Left >= FClientRect.Right) or (FClientRect.Top >= FClientRect.Bottom) or (FCol <= 0) or (FRow <= 0) then begin FPageCount := 0; FPageIndex := -1; FAppCountInPage := 0; FFirstAppRect.Left := 0; FFirstAppRect.Right := 0; FFirstAppRect.Top := 0; FFirstAppRect.Bottom := 0; Exit; end; w := Round((FClientRect.Right - FClientRect.Left) div FCol); h := Round((FClientRect.Bottom - FClientRect.Top) div FRow); FFirstAppRect.Top := FClientRect.Top; FFirstAppRect.Left := FClientRect.Left; FFirstAppRect.Bottom := FFirstAppRect.Top + h; FFirstAppRect.Right := FFirstAppRect.Left + w; FAppCountInPage := FCol * FRow; Layout; end; constructor TAppsLayout.Create; begin FApps := TStringList.Create; inherited Create; end; destructor TAppsLayout.Destroy; begin FreeAndNil(FApps); inherited; end; procedure TAppsLayout.Layout; var iLoop, jLoop, zLoop, iIndex : Integer; w, h: Integer; begin if FApps.Count = 0 then Exit; FPageCount := Ceil(FApps.Count / FAppCountInPage); if (FPageIndex < 0) and (FPageCount > 0) then FPageIndex := 0 else if FPageIndex >= FPageCount then FPageIndex := FPageCount - 1; w := FFirstAppRect.Right - FFirstAppRect.Left; h := FFirstAppRect.Bottom - FFirstAppRect.Top; iIndex := 0; for zLoop := 0 to FPageCount - 1 do for iLoop := 0 to FRow - 1 do for jLoop := 0 to FCol - 1 do begin with FApps.Objects[iIndex] as TControl do begin Top := FFirstAppRect.Top + iLoop * h + Round((h - Height) div 2); Left := FFirstAppRect.Left + jLoop * w + Round((w - Width) div 2); BringToFront; end; if iIndex >= (FApps.Count - 1) then begin ShowPage; Exit; end; Inc(iIndex); end; end; procedure TAppsLayout.RemoveAppBtn(AAppBtn: TControl); var i: Integer; begin i := FApps.IndexOfObject(AAppBtn); if i < 0 then Exit; FApps.Delete(i); Layout; end; procedure TAppsLayout.SetAllControlCanntVisible; var iLoop: Integer; begin for iLoop := 0 to FApps.Count - 1 do (FApps.Objects[iLoop] as TControl).Visible := False; end; procedure TAppsLayout.SetClientRect(const Value: TRect); begin if EqualRect(FClientRect, Value) then Exit; FClientRect := Value; Calculate; end; procedure TAppsLayout.SetCol(const Value: Integer); begin if FCol = Value then Exit; FCol := Value; Calculate; end; procedure TAppsLayout.SetPageIndex(const Value: Integer); begin if (Value < 0) or (Value > FPageCount - 1) then Exit; if Value = FPageIndex then Exit; FPageIndex := Value; ShowPage; end; procedure TAppsLayout.SetRow(const Value: Integer); begin if FRow = Value then Exit; FRow := Value; Calculate; end; procedure TAppsLayout.SetVisible(const Value: Boolean); var iLoop: Integer; begin if FVisible = Value then Exit; FVisible := Value; if FVisible then ShowPage else SetAllControlCanntVisible; end; procedure TAppsLayout.ShowPage; var iLoop: Integer; begin if (FClientRect.Left >= FClientRect.Right) or (FClientRect.Top >= FClientRect.Bottom) or (FCol <= 0) or (FRow <= 0) or (FPageIndex < 0)then Exit; SetAllControlCanntVisible; for iLoop := FPageIndex * FAppCountInPage to (FPageIndex + 1) * FAppCountInPage - 1 do begin if iLoop > FApps.Count - 1 then Exit; (FApps.Objects[iLoop] as TControl).Visible := True; (FApps.Objects[iLoop] as TControl).Invalidate; end; end; end.