Нарушение прав доступа при закрытии формы с плавающим компонентом - PullRequest
0 голосов
/ 16 апреля 2020

У меня есть приложение C ++ Builder VCL, в котором есть несколько динамически создаваемых компонентов. Эти компоненты должны иметь возможность подключаться и отсоединяться от Panel.

Проблема в том, что если пользователь закрывает форму, когда один из этих компонентов отстыкован (плавающий), я получаю сообщение об ошибке:

Исключение первого шанса на $ 50C278EF. Класс исключения $ C0000005 с сообщением «нарушение доступа по адресу 0x50c278ef: чтение адреса 0x00000010». Процесс Project1.exe (8004)

Вот упрощенный пример, демонстрирующий проблему:

ГЭС:

//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
    TPanel *Panel1;
    TPanel *Panel2;
    void __fastcall FormCreate(TObject *Sender);
    void __fastcall FormDestroy(TObject *Sender);
private:    // User declarations
    TPanel *Panel3;
public:     // User declarations
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

CPP

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    Panel3 = new TPanel((TComponent*)nullptr);
    Panel3->Parent = Panel1;
    Panel3->Width = 50;
    Panel3->Height = 50;
    Panel3->DragKind = dkDock;
    Panel3->DragMode = dmAutomatic;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
    delete Panel3;
}
//---------------------------------------------------------------------------

DFM

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 299
  ClientWidth = 635
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  PixelsPerInch = 96
  TextHeight = 13
  object Panel1: TPanel
    Left = 128
    Top = 48
    Width = 409
    Height = 217
    Caption = 'Panel1'
    DockSite = True
    TabOrder = 0
    object Panel2: TPanel
      Left = 216
      Top = 8
      Width = 185
      Height = 97
      Caption = 'Panel2'
      DragKind = dkDock
      DragMode = dmAutomatic
      TabOrder = 0
    end
  end
end

В этом примере, если Panel3 является плавающим и пользователь закрывает эту форму, мы получаем исключение.

...