📄 extctrls.pas
字号:
procedure TCustomPanel.AdjustClientRect(var Rect: TRect);
var
BevelSize: Integer;
begin
inherited AdjustClientRect(Rect);
InflateRect(Rect, -BorderWidth, -BorderWidth);
BevelSize := 0;
if BevelOuter <> bvNone then Inc(BevelSize, BevelWidth);
if BevelInner <> bvNone then Inc(BevelSize, BevelWidth);
InflateRect(Rect, -BevelSize, -BevelSize);
end;
procedure TCustomPanel.CMDockClient(var Message: TCMDockClient);
var
R: TRect;
Dim: Integer;
begin
if AutoSize then
begin
FAutoSizeDocking := True;
try
R := Message.DockSource.DockRect;
case Align of
alLeft: if Width = 0 then Width := R.Right - R.Left;
alRight: if Width = 0 then
begin
Dim := R.Right - R.Left;
SetBounds(Left - Dim, Top, Dim, Height);
end;
alTop: if Height = 0 then Height := R.Bottom - R.Top;
alBottom: if Height = 0 then
begin
Dim := R.Bottom - R.Top;
SetBounds(Left, Top - Dim, Width, Dim);
end;
end;
inherited;
Exit;
finally
FAutoSizeDocking := False;
end;
end;
inherited;
end;
function TCustomPanel.CanAutoSize(var NewWidth, NewHeight: Integer): Boolean;
begin
Result := (not FAutoSizeDocking) and inherited CanAutoSize(NewWidth, NewHeight);
end;
{ TPageAccess }
type
TPageAccess = class(TStrings)
private
PageList: TList;
Notebook: TNotebook;
protected
function GetCount: Integer; override;
function Get(Index: Integer): string; override;
procedure Put(Index: Integer; const S: string); override;
function GetObject(Index: Integer): TObject; override;
procedure SetUpdateState(Updating: Boolean); override;
public
constructor Create(APageList: TList; ANotebook: TNotebook);
procedure Clear; override;
procedure Delete(Index: Integer); override;
procedure Insert(Index: Integer; const S: string); override;
procedure Move(CurIndex, NewIndex: Integer); override;
end;
constructor TPageAccess.Create(APageList: TList; ANotebook: TNotebook);
begin
inherited Create;
PageList := APageList;
Notebook := ANotebook;
end;
function TPageAccess.GetCount: Integer;
begin
Result := PageList.Count;
end;
function TPageAccess.Get(Index: Integer): string;
begin
Result := TPage(PageList[Index]).Caption;
end;
procedure TPageAccess.Put(Index: Integer; const S: string);
begin
TPage(PageList[Index]).Caption := S;
end;
function TPageAccess.GetObject(Index: Integer): TObject;
begin
Result := PageList[Index];
end;
procedure TPageAccess.SetUpdateState(Updating: Boolean);
begin
{ do nothing }
end;
procedure TPageAccess.Clear;
var
I: Integer;
begin
for I := 0 to PageList.Count - 1 do
TPage(PageList[I]).Free;
PageList.Clear;
end;
procedure TPageAccess.Delete(Index: Integer);
var
Form: TCustomForm;
begin
TPage(PageList[Index]).Free;
PageList.Delete(Index);
NoteBook.PageIndex := 0;
if csDesigning in NoteBook.ComponentState then
begin
Form := GetParentForm(NoteBook);
if (Form <> nil) and (Form.Designer <> nil) then
Form.Designer.Modified;
end;
end;
procedure TPageAccess.Insert(Index: Integer; const S: string);
var
Page: TPage;
Form: TCustomForm;
begin
Page := TPage.Create(Notebook);
with Page do
begin
Parent := Notebook;
Caption := S;
end;
PageList.Insert(Index, Page);
NoteBook.PageIndex := Index;
if csDesigning in NoteBook.ComponentState then
begin
Form := GetParentForm(NoteBook);
if (Form <> nil) and (Form.Designer <> nil) then
Form.Designer.Modified;
end;
end;
procedure TPageAccess.Move(CurIndex, NewIndex: Integer);
var
AObject: TObject;
begin
if CurIndex <> NewIndex then
begin
AObject := PageList[CurIndex];
PageList[CurIndex] := PageList[NewIndex];
PageList[NewIndex] := AObject;
end;
end;
procedure TCustomPanel.SetParentBackground(Value: Boolean);
begin
{ TCustomPanel needs to not have csOpaque when painting
with the ParentBackground in Themed applications }
if Value then
ControlStyle := ControlStyle - [csOpaque]
else
ControlStyle := ControlStyle + [csOpaque];
FParentBackgroundSet := True;
inherited;
end;
{ TPage }
constructor TPage.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Visible := False;
ControlStyle := ControlStyle + [csAcceptsControls, csNoDesignVisible,
csParentBackground];
Align := alClient;
end;
procedure TPage.Paint;
begin
inherited Paint;
if csDesigning in ComponentState then
with Canvas do
begin
Pen.Style := psDash;
Brush.Style := bsClear;
Rectangle(0, 0, Width, Height);
end;
end;
procedure TPage.ReadState(Reader: TReader);
begin
if Reader.Parent is TNotebook then
TNotebook(Reader.Parent).FPageList.Add(Self);
inherited ReadState(Reader);
end;
procedure TPage.WMNCHitTest(var Message: TWMNCHitTest);
begin
if not (csDesigning in ComponentState) then
Message.Result := HTTRANSPARENT
else
inherited;
end;
{ TNotebook }
var
Registered: Boolean = False;
constructor TNotebook.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Width := 150;
Height := 150;
FPageList := TList.Create;
FAccess := TPageAccess.Create(FPageList, Self);
FPageIndex := -1;
FAccess.Add(SDefault);
PageIndex := 0;
Exclude(FComponentStyle, csInheritable);
ControlStyle := ControlStyle + [csParentBackground];
if not Registered then
begin
Classes.RegisterClasses([TPage]);
Registered := True;
end;
end;
destructor TNotebook.Destroy;
begin
FAccess.Free;
FPageList.Free;
inherited Destroy;
end;
procedure TNotebook.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
begin
Style := Style or WS_CLIPCHILDREN;
WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW);
end;
end;
function TNotebook.GetChildOwner: TComponent;
begin
Result := Self;
end;
procedure TNotebook.GetChildren(Proc: TGetChildProc; Root: TComponent);
var
I: Integer;
begin
for I := 0 to FPageList.Count - 1 do Proc(TControl(FPageList[I]));
end;
procedure TNotebook.ReadState(Reader: TReader);
begin
Pages.Clear;
inherited ReadState(Reader);
if (FPageIndex <> -1) and (FPageIndex >= 0) and (FPageIndex < FPageList.Count) then
with TPage(FPageList[FPageIndex]) do
begin
BringToFront;
Visible := True;
Align := alClient;
end
else FPageIndex := -1;
end;
procedure TNotebook.ShowControl(AControl: TControl);
var
I: Integer;
begin
for I := 0 to FPageList.Count - 1 do
if FPageList[I] = AControl then
begin
SetPageIndex(I);
Exit;
end;
inherited ShowControl(AControl);
end;
procedure TNotebook.SetPages(Value: TStrings);
begin
FAccess.Assign(Value);
end;
procedure TNotebook.SetPageIndex(Value: Integer);
var
ParentForm: TCustomForm;
begin
if csLoading in ComponentState then
begin
FPageIndex := Value;
Exit;
end;
if (Value <> FPageIndex) and (Value >= 0) and (Value < FPageList.Count) then
begin
ParentForm := GetParentForm(Self);
if ParentForm <> nil then
if ContainsControl(ParentForm.ActiveControl) then
ParentForm.ActiveControl := Self;
with TPage(FPageList[Value]) do
begin
BringToFront;
Visible := True;
Align := alClient;
end;
if (FPageIndex >= 0) and (FPageIndex < FPageList.Count) then
TPage(FPageList[FPageIndex]).Visible := False;
FPageIndex := Value;
if ParentForm <> nil then
if ParentForm.ActiveControl = Self then SelectFirst;
if Assigned(FOnPageChanged) then
FOnPageChanged(Self);
end;
end;
procedure TNotebook.SetActivePage(const Value: string);
begin
SetPageIndex(FAccess.IndexOf(Value));
end;
function TNotebook.GetActivePage: string;
begin
Result := FAccess[FPageIndex];
end;
{ THeaderStrings }
const
DefaultSectionWidth = 75;
type
PHeaderSection = ^THeaderSection;
THeaderSection = record
FObject: TObject;
Width: Integer;
Title: string;
end;
type
THeaderStrings = class(TStrings)
private
FHeader: THeader;
FList: TList;
procedure ReadData(Reader: TReader);
procedure WriteData(Writer: TWriter);
protected
procedure DefineProperties(Filer: TFiler); override;
function Get(Index: Integer): string; override;
function GetCount: Integer; override;
function GetObject(Index: Integer): TObject; override;
procedure Put(Index: Integer; const S: string); override;
procedure PutObject(Index: Integer; AObject: TObject); override;
procedure SetUpdateState(Updating: Boolean); override;
public
constructor Create;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
procedure Delete(Index: Integer); override;
procedure Insert(Index: Integer; const S: string); override;
procedure Clear; override;
end;
procedure FreeSection(Section: PHeaderSection);
begin
if Section <> nil then Dispose(Section);
end;
function NewSection(const ATitle: string; AWidth: Integer; AObject: TObject): PHeaderSection;
begin
New(Result);
with Result^ do
begin
Title := ATitle;
Width := AWidth;
FObject := AObject;
end;
end;
constructor THeaderStrings.Create;
begin
inherited Create;
FList := TList.Create;
end;
destructor THeaderStrings.Destroy;
begin
if FList <> nil then
begin
Clear;
FList.Free;
end;
inherited Destroy;
end;
procedure THeaderStrings.Assign(Source: TPersistent);
var
I, J: Integer;
Strings: TStrings;
NewList: TList;
Section: PHeaderSection;
TempStr: string;
Found: Boolean;
begin
if Source is TStrings then
begin
Strings := TStrings(Source);
BeginUpdate;
try
NewList := TList.Create;
try
{ Delete any sections not in the new list }
I := FList.Count - 1;
Found := False;
while I >= 0 do
begin
TempStr := Get(I);
for J := 0 to Strings.Count - 1 do
begin
Found := AnsiCompareStr(Strings[J], TempStr) = 0;
if Found then Break;
end;
if not Found then Delete(I);
Dec(I);
end;
{ Now iterate over the lists and maintain section widths of sections in
the new list }
I := 0;
for J := 0 to Strings.Count - 1 do
begin
if (I < FList.Count) and (AnsiCompareStr(Strings[J], Get(I)) = 0) then
begin
Section := NewSection(Get(I), PHeaderSection(FList[I])^.Width, GetObject(I));
Inc(I);
end else
Section := NewSection(Strings[J],
FHeader.Canvas.TextWidth(Strings[J]) + 8, Strings.Objects[J]);
NewList.Add(Section);
end;
Clear;
FList.Destroy;
FList := NewList;
FHeader.Invalidate;
except
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -