Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 13.02.2018, 21:49   #1
exyl
Пользователь
 
Регистрация: 15.11.2014
Сообщений: 75
По умолчанию Закрытие динамически созданной вкладки

Доброго вечера.
Есть динамически создаваемые вкладки типа TTabSheet на пэйджконтроле. На вкладках есть панелька, на ней несколько кнопок, все это тоже создается динамически. Одна из кнопок закрывает вкладку, на которой находится:

Код:
(((Sender as TButton).Owner as TPanel).Owner as TTabSheet).Free;
Все это работает вроде бы правильно, но уже после закрытия вылетает акцесс виолейшн.
Конкретно в Vcl.Controls на строке:
Код:
with FTouchManager do
          if (GestureEngine <> nil) and (efMouseEvents in GestureEngine.Flags) then
            GestureEngine.Notification(Message);
Это Делфи 10.2.

Т.е. теоретически можно код обработчика кнопки обернуть в try ... except ... end, и при эксепте просто пропускать этот эррор мимо ушей, но это тот еще костыль. Поэтому закономерный вопрос: а как правильно закрывать вкладку, чтоб ошибки такие не ловить?

Последний раз редактировалось exyl; 13.02.2018 в 21:52.
exyl вне форума Ответить с цитированием
Старый 13.02.2018, 22:13   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Parent сделай вместо Owner. А ваще не хорошо в том числе и себя убивать из своего же метода, я бы пользовательское сообщение послал и уже в нем уничтожил
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 13.02.2018 в 22:18.
Аватар вне форума Ответить с цитированием
Старый 13.02.2018, 22:50   #3
exyl
Пользователь
 
Регистрация: 15.11.2014
Сообщений: 75
По умолчанию

Попробовал Parent. Та же самая история. А что там по сообщениям? Пример под рукой есть?
exyl вне форума Ответить с цитированием
Старый 13.02.2018, 22:57   #4
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Вместо
Код:
(((Sender as TButton).Owner as TPanel).Owner as TTabSheet).Free;
пиши
Код:
PageControl.ActivePage.Free();
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 13.02.2018, 23:09   #5
exyl
Пользователь
 
Регистрация: 15.11.2014
Сообщений: 75
По умолчанию

Цитата:
Сообщение от min@y™ Посмотреть сообщение
Вместо
Код:
(((Sender as TButton).Owner as TPanel).Owner as TTabSheet).Free;
пиши
Код:
PageControl.ActivePage.Free();
Не выйдет. Процедура клика по кнопке находится в модуле, который понятия не имеет что там за пейдж контрол и на какой он форме.
exyl вне форума Ответить с цитированием
Старый 13.02.2018, 23:24   #6
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
Сообщение от exyl Посмотреть сообщение
Не выйдет. Процедура клика по кнопке находится в модуле, который понятия не имеет что там за пейдж контрол и на какой он форме.
Это чо, проблема? Сделай обаботчик клика кнопки методом формы, на которой PageControl находится. Или передавай указатель на PageControl в свойстве Tag кнопки.
Код:
procedure AnyClass.ButtonClick(Sender: TObject);
var
  cmp: TComponent absolute Sender;
  pc: TPageControl;
begin
  // может не работать в 64-битной версии проги, но это неточно.
  pc:= TPageControl(cmp.tag);
  pc.ActivePage.Free();
end;
Если кнопка 1хрен создаётся динамически, то можно вообще добавить в неё пару полей или методов.

Или ещё 100500 способов...
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 13.02.2018, 23:45   #7
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Код:
const SX_MYMESSAGE = WM_USER + 100;
type
  TForm1 = class(TForm)
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    Panel1: TPanel;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure SXMyMessage(var Msg: TMessage); message SX_MYMESSAGE;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.SXMyMessage(var Msg: TMessage);
begin
  TTabSheet(Pointer(Msg.WParam)).Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  PostMessage(Handle,SX_MYMESSAGE,DWORD((Sender as TButton).Parent.Parent),0);
end;
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 13.02.2018, 23:56   #8
exyl
Пользователь
 
Регистрация: 15.11.2014
Сообщений: 75
По умолчанию

Цитата:
Сообщение от min@y™ Посмотреть сообщение
Это чо, проблема? Сделай обаботчик клика кнопки методом формы, на которой PageControl находится. Или передавай указатель на PageControl в свойстве Tag кнопки.
Код:
procedure AnyClass.ButtonClick(Sender: TObject);
var
  cmp: TComponent absolute Sender;
  pc: TPageControl;
begin
  // может не работать в 64-битной версии проги, но это неточно.
  pc:= TPageControl(cmp.tag);
  pc.ActivePage.Free();
end;
Опять акцесс виолейшн. Добавить-то не проблема, проблема, видимо, в том, что в любом случае клик будет по кнопке, которая будет уничтожать своего родителя.
Вообще говоря, когда я работал в 2007 версии, подобного не было, код функционировал без ошибок.

Аватар, спасибо, буду разбираться.
exyl вне форума Ответить с цитированием
Старый 14.02.2018, 00:02   #9
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Цитата:
код функционировал без ошибок
Повезло, случайно
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 14.02.2018, 00:30   #10
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
Сообщение от exyl Посмотреть сообщение
Опять акцесс виолейшн. Добавить-то не проблема, проблема, видимо, в том, что в любом случае клик будет по кнопке, которая будет уничтожать своего родителя.
Не вижу связи.
Почему у меня-то работает? Что я делаю не так?
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Изменение размера динамически созданного StringGrid на динамически созданной форме loom12 Общие вопросы Delphi 2 08.09.2014 15:35
Работа с динамически созданной формой Airou C++ Builder 1 12.07.2011 10:58
Прозрачность динамически созданной формы Lime Общие вопросы .NET 1 03.04.2010 16:25
Передать Title загружаемой страницы в Caption созданной вкладки PageControl-a Verst Общие вопросы Delphi 6 24.11.2009 01:43
Событие для динамически созданной Button Dogmat Помощь студентам 8 24.07.2008 12:44