Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.05.27;
Скачать: CL | DM;

Вниз

Динамичное создение контролов   Найти похожие ветки 

 
Strate ©   (2007-05-09 21:17) [0]

Создаю чекбокс на форме:

chkBoxes[0] := TCheckBox.Create(Self);

... дальше выставляю Parent, Visible... в общем контрол создаётся и работает.

Тут же:

chkBoxes[0].Free - и уже выдаёт ошибку Invalid Pointer Operation.

В чём проблема?


 
Strate ©   (2007-05-09 21:22) [1]

Да, ещё забыл уточнить.

chkBoxes : array of TCheckBox;

длину выставляю перед созданием

SetLength(chkBoxes, N);


 
Johnmen ©   (2007-05-09 21:37) [2]

При указанных исходных данных ошибки не будет, если N>0.


 
Rial ©   (2007-05-09 21:45) [3]

> [0] Strate ©   (09.05.07 21:17)
> Тут же:

Замени "тут же" на реальный код.


 
Strate ©   (2007-05-09 22:01) [4]

Вот полностью код:

TfrmQuery = class(TForm)
   cmdOK: TButton;
   cmdClose: TButton;
   Button1: TButton;
   procedure cmdCloseClick(Sender: TObject);
   procedure cmdOKClick(Sender: TObject);
   procedure FormShow(Sender: TObject);
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
   Cancelled : boolean;
   Table : TADOTable;
   procedure DestroyComponents;
 public
   { Public declarations }
   chkFields : array of TCheckBox;
   function ShowDialog (ATable : TADOTable) : integer;
 end;

var
 frmQuery: TfrmQuery;

implementation

{$R *.dfm}

procedure TfrmQuery.DestroyComponents;
var
 i : byte;
begin
 for i := 0 to High(chkFields) do
   chkFields[i].Free;
end;

function TfrmQuery.ShowDialog;
begin
 result := 1;
 Cancelled := True;
 Table := ATable;
 ShowModal;
 If Cancelled then result :=0;
end;

procedure TfrmQuery.cmdCloseClick(Sender: TObject);
begin
 Cancelled := True;
 Close;
end;

procedure TfrmQuery.cmdOKClick(Sender: TObject);
begin
 Cancelled := False;
 Close;
end;

procedure TfrmQuery.FormShow(Sender: TObject);
var
 i : byte;
 Fields : TStringList;
begin
 Fields := TStringList.Create;
 Table.GetFieldNames(Fields);
 SetLength(chkFields, Fields.Count-1);
 for i := 0 to Fields.Count-1 do
 begin
   chkFields[i] := TCheckBox.Create(Self);
   With chkFields[i] do
   begin
     Height := 25;
     Parent := Self;
     Visible := True;
     Caption := Fields[i];
     Left := 10;
     Top := 10+(Height+10)*i;
   end;
 end;
 Fields.Free;
end;

procedure TfrmQuery.Button1Click(Sender: TObject);
begin
 DestroyComponents;
end;


Из другой формы вызывается ShowDialog, создаются контролы и работают. Жмём на Button1 - вываливается ошибка.


 
Strate ©   (2007-05-09 22:05) [5]

т.е. не при нажатии на кнопку. После закрытия формы пытаюсь закрыть главную форму - и выскакивает Invalid Pointer Operation.

Если убрать всё что связано с динамическими чекбоксами всё нормально.


 
Johnmen ©   (2007-05-09 22:14) [6]


> SetLength(chkFields, Fields.Count-1);

Т.е. если поле одно, то размерность массива = 0 ? :)))

for i := 0 to High(chkFields) do
  chkFields[i].Free;

А ты уверен, что в массиве вообще есть элементы???


 
Strate ©   (2007-05-09 22:18) [7]

Johnmen ©   (09.05.07 22:14) [6]

Ну, пока я тестирую полей больше чем 1 и они всегда есть :) Исправил немного:

procedure TfrmQuery.DestroyComponents;
var
 i : byte;
begin
 for i := 0 to Length(chkFields) do
   FreeAndNil(chkFields[i]);
end;

Но ошибка после закрытия главной формы никуда не делась. И возникает она вообще после оператора Application.Run (после его выполнения) :-(


 
Johnmen ©   (2007-05-09 22:19) [8]


>> for i := 0 to High(chkFields) do
>>  chkFields[i].Free;
> А ты уверен, что в массиве вообще есть элементы???

Здесь нормально...


 
Strate ©   (2007-05-09 22:21) [9]

Подправил вот до такого состояния:

procedure TfrmQuery.FormShow(Sender: TObject);
var
 i : byte;
 Fields : TStringList;
begin
 Fields := TStringList.Create;
 Table.GetFieldNames(Fields);
 SetLength(chkFields, Fields.Count);
 for i := 0 to Fields.Count-1 do
 begin
   chkFields[i+1] := TCheckBox.Create(Self);
   With chkFields[i+1] do
   begin
     Height := 25;
     Parent := Self;
     Visible := True;
     Caption := Fields[i];
     Left := 10;
     Top := 10+(Height+10)*i;
   end;
 end;
 Fields.Free;
end;


, теперь ошибка сразу на первом вызове chkFields[i].Free;


 
Johnmen ©   (2007-05-09 22:21) [10]


> Ну, пока я тестирую полей больше чем 1 и они всегда есть :)

Т.е. кол-во элементов массива меньше кол-ва полей, и это нормально???


 
Johnmen ©   (2007-05-09 22:23) [11]


>  теперь ошибка сразу на первом вызове chkFields[i].Free;

Индексация динамических массивов начинается с нуля. О чём и написано в хелпе.


 
Strate ©   (2007-05-09 22:25) [12]

В общем пропала ошибка :) Всё клёво работает. Вот изменённые участки:

procedure TfrmQuery.DestroyComponents;
var
 i : byte;
begin
 for i := 0 to High(chkFields) do
   FreeAndNil(chkFields[i]);
end;


procedure TfrmQuery.FormShow(Sender: TObject);
var
 i : byte;
 Fields : TStringList;
begin
 Fields := TStringList.Create;
 Table.GetFieldNames(Fields);
 SetLength(chkFields, Fields.Count);
 for i := 0 to Fields.Count-1 do
 begin
   chkFields[i] := TCheckBox.Create(Self);
   With chkFields[i] do
   begin
     Height := 25;
     Parent := Self;
     Visible := True;
     Caption := Fields[i];
     Left := 10;
     Top := 10+(Height+10)*i;
   end;
 end;
 Fields.Free;
end;



Страницы: 1 вся ветка

Текущий архив: 2007.05.27;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.035 c
15-1178100684
ыукмшсу
2007-05-02 14:11
2007.05.27
Регистрация службы в MS Vista


6-1161035477
kay
2006-10-17 01:51
2007.05.27
Как задать gateway сетевому интерфейсу?


2-1178637823
likenoother
2007-05-08 19:23
2007.05.27
вывод текста через канвас


1-1174519920
Makhanev Alexander
2007-03-22 02:32
2007.05.27
named pipes...


3-1173785473
kulkse
2007-03-13 14:31
2007.05.27
DBGrid MultiSelect