The task was set to the maximum from standard components and elements, to make it “beautiful”.
I made a box with drop-down panels from the memo, painted the Canvas with it, so that it is uniform, but adding a Label to the panel to write at least something, a Label with text is displayed under the canvas and no labels are visible. How to pull the inscription up? Writing on canvas outside will be oh so awkward ...
unit ToggledPanels; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls; type TstorageMemo = class(TMemo) private { Private declarations } PCount: word; {количество Toggl-ов} procedure PPanelCount(Count:word);{заводим количество панелей} procedure WMPaint(var Msg: TMessage); message WM_Paint;{отрисовка} protected { Protected declarations } public { Public declarations } TGLineHeight: Word; published { Published declarations } property PanelCount: word write PPanelCount; constructor Create(AOwner: TComponent); override; destructor Destroy; override; end; TToggledLabel = class; TToggledPanel = class(TPanel){сами панельки} private Opened: boolean;{статус открыт/закрыт} TGLineHeight: Word;{пока не используется, высота тогла} ToglText:TToggledLabel;{сюда будем снаружи пихать текст в лэйбл} { Private declarations } procedure WMPaint(var Msg: TMessage); message WM_Paint; protected { Protected declarations } public // Width: word; { Public declarations } published { Published declarations } destructor Destroy; override; constructor Create(AOwner: TComponent); override; procedure Click; override; end; TToggledLabel = class(TLabel) private { Private declarations } protected { Protected declarations } public // Width: word; { Public declarations } published { Published declarations } end; implementation var CountBuf : array of TToggledPanel;{храним количество тогглов} { TstorageMemo } constructor TstorageMemo.Create(AOwner: TComponent); begin inherited; Self.Cursor:= crArrow;{начальные конструкции} Self.Top:= 40; Self.Left:= 40; Self.Height:= 200; Self.Width:= 500; Self.ScrollBars:= ssVertical; Self.Ctl3D:=false; Self.ReadOnly:=true; end; procedure TstorageMemo.PPanelCount(Count: word); var i: word; begin inherited; { собственно создадим и забьем панельками} setlength(CountBuf, Count); PCount:=Count; if Count>0 then for i := 1 to Count do begin CountBuf[i]:= TToggledPanel.Create(Self); CountBuf[i].Parent:= Self; CountBuf[i].AutoSize:=false; CountBuf[i].Width:=Self.Width; CountBuf[i].TGLineHeight:=20; CountBuf[i].Name:='TogglePanel'+inttostr(i); if i > 1 then CountBuf[i].Top:=20*(i-1) else CountBuf[i].Top:=0; end; end; procedure TstorageMemo.WMPaint(var Msg: TMessage); var i: word; begin HideCaret(Self.Handle);{прячем каретку в мемо, она не нужна} for i := 1 to length(CountBuf) do begin{и закрашиваем после раскрытия} тогла if i > 1 then begin CountBuf[i].Top:=CountBuf[i-1].Height+CountBuf[i-1].Top+2; CountBuf[i].ToglText.BringToFront;{попытка выдернуть лэйбл наверх/не работает} end else CountBuf[i].Top:=0; end; inherited; end; constructor TToggledPanel.Create(AOwner: TComponent); begin inherited; Self.Height:=20; Self.Opened:= false; Self.Caption:=''; Self.AutoSize:=True; Self.ParentShowHint:=false; Self.ParentColor:=false; Self.ParentCustomHint:=false; {выставили параметры при создании, теперь создадим внутри лейбл} ToglText:= TToggledLabel.Create(Self); ToglText.Parent:= Self; ToglText.BringToFront; with ToglText do begin Top:=20+5; AutoSize:=true; Width:=Self.Width-20; Height:=40; Left:=10; {текст для примера} Text:='11111111111111111'+#13#10+'2222222222222'+#13#10+'333333333333'; ParentFont:=true; ParentColor:=False; end; end; destructor TToggledPanel.Destroy; begin inherited; end; procedure TToggledPanel.WMPaint(var Msg: TMessage); begin inherited; {заливка после раскрытия} with Self.Canvas do begin Brush.Color:= $00f4a142; end; ExtFloodFill(Self.Canvas.Handle, 0, 0, $00f4a142, FLOODFILLBORDER); end; destructor TstorageMemo.Destroy; var i: word; begin for i := 1 to PCount do CountBuf[i].Destroy; inherited; end; procedure TToggledPanel.Click; var i: word; t:byte; begin {тут собственно раскрытие} if self.Opened then begin self.Height:= self.Height div 7; self.Opened:=false; end else begin i:=self.Height*7; t:=0; while self.Height<i do begin Self.Height:=Self.Height+(t div 2); inc(t); sleep(10); Self.ToglText.BringToFront; Application.ProcessMessages; end; Self.ToglText.BringToFront; self.Opened:=true; end; inherited; end; end. Add to the form
procedure TForm3.FormCreate(Sender: TObject); begin ToggledPanel:= TstorageMemo.Create(Form3); ToggledPanel.Parent:= Form3; ToggledPanel.PanelCount:=2; ToggledPanel.TGLineHeight:=20; end; Variant draft, therefore sizes, sv-va, par-ry, etc. in large numbers while exhibited from the inside ... Do not pay attention.