по созданным формам(создаю страницу и пихаю туда форму). Вопрос как правильно закрыть эту страницу(с формой)? Если на форме я делаю close то соответственно все удаляется кроме вкладки, а при попытке удаления вкладки получаю access violation((( Код удаления вкладки: procedure TMainFrm.DeletePage(NamePage: string);
var
i: integer;
varPage: TTabSheet;
begin
for i := 0 to pcMain.PageCount - 1 do
begin
if pcMain.Pages[i].Caption = NamePage then
begin
varPage := pcMain.Pages[i];
varPage.Free;
//Если вкладка была последняя и мы её удалили то скрываем вкладки
if pcMain.PageCount = 0 then
pcMain.Visible:=false;
break;
end;
end;
end;
Помещай создаваемые формы в TObjectList<>. Перед удалением вкладки удаляй сначала форму, потом вкладку
Поправка. Если запускаю процедуру удаления из главной формы, на которой pagecontrol, то все отлично. Ошибка возникает при вызове процедуры из созданной формы.
Делай тестовый проект и выкладывай сюда.
Истина рядом. Сделал пустой проект только с pagecontrol и 2 формами и там не возникает access violation.🤯 Но по вашему совету однозначно почитаю и попробую применить tobjectlist.
Попробуй поставить удаление страницы (varPage.Free) в отложенное сообщение. У тебя похоже, что после срабатывания DeletePage идёт обращение к этому же объекту - типичная ситуация, когда кнопка удаления лежит на удаляемом фрейме, а обработчик события OnClick не является "последним" в цепочке инструкций обработки нажатия кнопки - отсюда и AV.
Тебе нужен контейнер, который будет хранить объекты и сам корректно уничтожать при удалении из него. А вкладки используй только для отображения этих объектов, перед удалением вкладки проверяй, удалён ли соответствующий ей объект
Что-то вроде: TThread.ForceQueue(nil, procedure begin varPage.Free; end);
В общем вот вариант с исправлениями: procedure TMainFrm.DeletePage(NamePage: string); var i: integer; varPage: TTabSheet; begin for i := 0 to pcMain.PageCount - 1 do begin if pcMain.Pages[i].Caption = NamePage then begin varPage := pcMain.Pages[i]; TThread.ForceQueue(nil, procedure begin varPage.Free; end); //Если вкладка была последняя и мы её удалили то скрываем вкладки if pcMain.PageCount = 1 then pcMain.Visible:=false; break; end; end; end;
TThread.ForceQueue(nil, varPage.Free);
имхо, достаточно PostMessage. Чего огород городить?
Это разве скомпилируется? Не знаком с Lazarus, но в Delphi по синтаксису будет вызван метод Free объекта varPage и его результат будет передан вторым параметром метода ForceQueue
ForceQueue принимает процедуру, он не может принять "ничего", что является результатом Free
Обсуждают сегодня