Автор: Neil

 

...у меня происходит утечка памяти при изменениях страниц в закладках NoteBook.

 

Вы не "теряете" ресурсы, вы их используете. Вы ИСПОЛЬЗУЕТЕ ресурсы на каждой страницы начиная с первой, которая доступна для вашего созерцания. Я упомянаю это потому, потому что проблема ПОТЕРИ ресурсов относится к другому типу проблемы.

 

Недавно я работал над проблемой показа других *ФОРМ* в главной форме, как если бы они были страницами NoteBook. Форма создается при перелистывании на эту "страницу", и разрушается при ее покидании. Это требует хранения неизменяемой информации, естественно, в главной форме, но это чрезвычайно нетребовательно к ресурсам. Главное, что вы храните поля индивидуальных данных в главной форме с именем "Child", а инициализируете в обработчике события экземпляра TForm2 (или имеющего другое имя, в зависимости от имени вашей первой дочерней формы) OnCreate. Поместите закладки в нижней части формы, и при изменении закладки освобождайте текущего "ребенка", а затем создавайте и делайте ребенком другой соответствующий экземпляр формы.

 

Использование:

 

Code:

procedure TForm1.GSPageControl1Changing(Sender: TObject;

var AllowChange: Boolean);

begin

AllowChange:=GSPageControl1.Pages[GSPageControl1.NewPageIndex].Enabled

end;

 

При добавлении компонентов во время выполнения программы, вам необходимо присвоить для каждого компонента свойству parent (контейнер) _страницу_ компонента notebook, а не сам notebook.

 Вы можете сделать это следующим образом (пример дан для кнопки):

 

Code:

MyButton := TButton.Create( Form1 );  {как обычно...}

...

...

MyButton.Parent := TTabPage( TabbedNotebook1.Pages.Objects[n] );

{ <== где 'n' - индекс желаемой страницы ==> }

Вот хороший трюк от Xavier Pacheco:

Code:

unit TabDis;

 

interface

 

uses

SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics,

Controls, Forms, Dialogs, StdCtrls, TabNotBk;

 

type

TFrmTabDis = class(TForm)

   TabbedNotebook1: TTabbedNotebook;

   Button1: TButton;

   procedure FormCreate(Sender: TObject);

   procedure Button1Click(Sender: TObject);

private

   { Private-Deklarationen }

public

   { Public-Deklarationen }

end;

 

var

FrmTabDis: TFrmTabDis;

 

implementation

 

{$R *.DFM}

 

procedure TFrmTabDis.FormCreate(Sender: TObject);

var

i: integer;

j: integer;

begin

{ Создаем имена для всех Notebook TTabButton }

 

j := 0;

 

with TabbedNotebook1 do

   for i := 0 to ControlCount - 1 do

     if Controls[i].ClassName = 'TTabButton' then

     begin

       Controls[i].Name := Controls[i].ClassName + IntToStr(j);

       Inc(j);

     end;

end;

 

procedure TFrmTabDis.Button1Click(Sender: TObject);

begin

{ Делаем недоступной определенную страницу notebook }

with TControl(TabbedNotebook1.FindComponent('TTabButton2')) do

   Enabled := not Enabled;

end;

 

end.

 

 

 

Code:

type

TTabSheet = class(ComCtrls.TTabSheet)

private

   FColor: TColor;

   procedure SetColor(Value: TColor);

   procedure WMEraseBkGnd(var Msg: TWMEraseBkGnd);

     message WM_ERASEBKGND;

public

   constructor Create(aOwner: TComponent); override;

   property Color: TColor read FColor write SetColor;

end;

 

{...}

implementation

{...}

 

constructor TTabSheet.Create(aOwner: TComponent);

begin

inherited;

FColor := clBtnFace;

end;

 

procedure TTabSheet.SetColor(Value: TColor);

begin

if FColor  Value then

begin

   FColor := Value;

   Invalidate;

end;

end;

 

procedure TTabSheet.WMEraseBkGnd(var Msg: TWMEraseBkGnd);

begin

if FColor = clBtnFace then

   inherited

else

begin

   Brush.Color := FColor;

   Windows.FillRect(Msg.dc, ClientRect, Brush.Handle);

   Msg.Result := 1;

end;

end;

 

procedure TForm1.FormCreate(Sender: TObject);

begin

Tabsheet1.Color := clWhite;

TabSheet2.Color := clLime;

end;

 

// PageControl1.OwnerDraw := true !

 

procedure TForm1.PageControl1DrawTab(Control: TCustomTabControl;

TabIndex: Integer; const Rect: TRect; Active: Boolean);

var

AText: string;

APoint: TPoint;

begin

with (Control as TPageControl).Canvas do

begin

   Brush.Color := clred;

   FillRect(Rect);

   AText := TPageControl(Control).Pages[TabIndex].Caption;

   with Control.Canvas do

   begin

     APoint.x := (Rect.Right - Rect.Left) div 2 - TextWidth(AText) div 2;

     APoint.y := (Rect.Bottom - Rect.Top) div 2 - TextHeight(AText) div 2;

     TextRect(Rect, Rect.Left + APoint.x, Rect.Top + APoint.y, AText);

   end;

end;

end;

 

 

В данном документе показана технология динамического добавления страниц компонента PageControl (объектов TTabSheet) к элементу управления Windows 95/NT PageControl (объект TPageControl). Оба этих объекта объявлены в модуле ComCtrls. Поэтому убедитесь в том, что ComCtrls указан в списке используемых модулей.

 

Можно перехватить сообщение CM_DIALOGCHAR

Code:

type

TForm1 = class(TForm)

   PageControl1: TPageControl;

   TabSheet1: TTabSheet;

   TabSheet2: TTabSheet;

   TabSheet3: TTabSheet;

private

   {Private declarations}

   procedure CMDialogChar(var Msg:TCMDialogChar);

   message CM_DIALOGCHAR;

public

   {Public declarations}

end;

 

var

Form1: TForm1;

 

implementation

{$R *.DFM}

 

procedure TForm1.CMDialogChar(var Msg:TCMDialogChar);

var

i: integer;

begin

with PageControl1 do

begin

   if Enabled then

     for i := 0 to PageControl1.PageCount - 1 do

       if ((IsAccel(Msg.CharCode, Pages[i].Caption)) and

       (Pages[i].TabVisible)) then

       begin

         Msg.Result:=1;

         ActivePage := Pages[i];

         exit;

       end;

end;

inherited;

end;

 

 

 

 

Code:

procedure TForm1.TabbedNotebook1Click(Sender: TObject);

var

myE: TEdit;

begin

with TabbedNotebook1 do

begin

   if PageIndex = 1 then

   begin

     myE := TEdit.Create(Self);

     myE.Left := 12;

     myE.Top := 12;

     myE.Parent := Pages.Objects[PageIndex] as TWinControl;

     myE.Show;

   end;

end;

end;

 

 

procedure TForm1.Button1Click(Sender: TObject);

var

Button2:Tbutton;

begin

button2:=tbutton.create(self);

button2.parent:=TabbedNotebook1.Pages.Object[0] as TTabPage;

button2.setbounds(30,30,60,30);

end;

 

 

Как использовать клавишу-акселератор в TTabsheets? Я добавляю клавишу-акселератор в заголовок каждого Tabsheet моего PageControl, но при попытке переключать страницы этой клавишей программа пикает и ничего не происходит.

 

Можно перехватить сообщение CM_DIALOGCHAR.

Автор: Mark Johnson

 

Как во время выполнения программы динамически добавлять и удалять страницы динамически созданного NoteBook?

 

Code:

procedure TForm1.Button1Click(Sender: TObject);

var

NewPage: TWinControl;

begin

TabbedNotebook1.Pages.Add(Edit1.Text);

NewPage := TabbedNotebook1.Pages.Objects[TabbedNotebook1.Pages.Count - 1]

   as TWinControl;

with TLabel.Create(Self) do

begin

   Left := 20;

   Top := 20;

   Caption := '&Телефон: ';

   Parent := NewPage;

end;

with TEdit.Create(Self) do

begin

   Left := 100;

   Top := 20;

   Text := '1-800-555-1212';

   Parent := NewPage;

end;

end;

 

 

 

 

Code:

procedure TForm1.Button1Click(Sender: TObject);

var

n: integer;

p: integer;

begin

ListBox1.Clear;

with Notebook1 do

   begin

     for n := 0 to ControlCount - 1 do

       begin

         with TPage(Controls[n]) do

           begin

             ListBox1.Items.Add('Notebook Page: ' +

               TPage(Notebook1.Controls[n]).Caption);

             for p := 0 to ControlCount - 1 do

               ListBox1.Items.Add(Controls[p].Name);

             ListBox1.Items.Add(EmptyStr);

           end;

       end;

   end;

end;