Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / IDE Catastrophic failure при удалении с формы своего компонента / 19 сообщений из 19, страница 1 из 1
04.04.2019, 09:12
    #39796126
Kast2K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDE Catastrophic failure при удалении с формы своего компонента
Добрый день!
Студия 10.2 Tokyo
Для эксперимента сделал тестовый компонент на базе TFrame.
Создал внутри него DataModule и закинул несколько TAdoquery.
Прописал property Connection для дальнейшей связи с базой.


Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
unit frameSelectUser;

interface

uses
  Winapi.Windows, Data.DB, Data.Win.ADODB, Vcl.DBCtrls, Vcl.StdCtrls, Vcl.Controls,
  Vcl.Buttons, System.Classes, System.SysUtils, Vcl.Forms, Variants, Comobj;

type
  TTestSelectUser = class(TFrame)
    GroupBox4: TGroupBox;
    Label3: TLabel;
    Label4: TLabel;
    edtsearch: TEdit;
    cbShop: TDBLookupComboBox;
    cbUser: TDBLookupComboBox;
  private
    FCommand: TADOCommand;

    function  GetConnection: TADOConnection;
    procedure RefreshDBLookup(ADBL: TDBLookupControl);
    procedure SetConnection(const Value: TADOConnection);
  protected
    property Command: TADOCommand read FCommand;
  public
    constructor Create(AOwner:TComponent);override;
    destructor Destroy; override;

  published
    { Published declarations }
    property Connection:TADOConnection read GetConnection write SetConnection;
  end;

type
  TDBlk = class(TDBLookupControl)
  published
    property KeyValue;
    property ListSource;
  end;
  TCRADOConnection = class(TADOConnection)

  end;
  TCRADOCommand = class(TADOCommand)

  end;

procedure Register;

implementation

{$R *.dfm}

uses formSearchForUser, dmDB;

procedure Register;
begin
  RegisterComponents('Test', [TTestSelectUser]);
end;

{ TTestSelectUser }

constructor TTestSelectUser.Create(AOwner:TComponent);
begin
  inherited Create(AOwner);

  FCommand := TADOCommand.Create(Self);
  TCRADOCommand(FCommand).ComponentRef := Self;

  DataModule2:=TDataModule2.Create(Self);
end;

procedure TTestSelectUser.CreateSearchForm(const AText: string='');
var
  f:TfrmSearchForUsers;
begin
  f:=TfrmSearchForUsers.Create(Self);
  try
    f.ShowModal;
  finally
    FreeAndNil(f);
  end;
end;

destructor TTestSelectUser.Destroy;
begin
  SetConnection(nil);
  FreeAndNil(FCommand);
  inherited Destroy;
end;

function TTestSelectUser.GetConnection: TADOConnection;
begin
  if Assigned(Command) then
    Result := Command.Connection 
  else
    Result := nil;
end;

procedure TTestSelectUser.RefreshDBLookup(ADBL: TDBLookupControl);
begin
  TDBlk(ADBL).ListSource.DataSet.DisableControls;
  try
    try
      TDBlk(ADBL).ListSource.DataSet.Close;
      TDBlk(ADBL).ListSource.DataSet.Open;

      TDBlk(ADBL).KeyValue:=Null;
    except
      on E: Exception do
        begin
          raise Exception.Create('RefreshDBLookup Error='+e.Message);
        end;
      on E: EOleException do
        begin
          raise Exception.Create('RefreshDBLookup OLE Error='+e.Message);
        end;
      on E: EDatabaseError do
        begin
          raise Exception.Create('RefreshDBLookup DB Error='+e.Message);
        end;
    end;
  finally
    TDBlk(ADBL).ListSource.DataSet.EnableControls;
  end;
end;

procedure TTestSelectUser.SetConnection(const Value: TADOConnection);
begin
  if Connection <> Value then
  begin
    if Assigned(Connection) then TCRADOConnection(Connection).UnregisterClient(Self);
    if Assigned(Command) then Command.Connection := Value;
  end;
  if Assigned(Value) then
  begin
    TCRADOConnection(Value).RegisterClient(Self);
  end;
end;

end.





Компонент кидаю на форму - проблем нет, добавляю связь с Adoconnection - OK, проверяю работу с БД - ОК.
Удаляю компонент с формы в Design-Time - студия валится с ошибкой.

Ранее я не создавал VCL компоненты и ,возможно по незнанию, что-то делаю не так.

Не могли бы вы указать на мои ошибки или направить на примеры как необходимо делать правильно.

Спасибо.
...
Рейтинг: 0 / 0
04.04.2019, 09:21
    #39796134
goldmi45
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDE Catastrophic failure при удалении с формы своего компонента
Kast2K,

Что это?
Код: pascal
1.
 DataModule2:=TDataModule2.Create(Self);


DataModule2 - это глобальный экземпляр? При создании его вы указываете, что owner у DataModule2 будет ваш компонент. Т.е. при уничтожении вашего фрейма должен будет удалиться и DataModule2.

И ещё, будет утечка памяти, если будет 2 фрейма, или фрейм пересоздастся.
...
Рейтинг: 0 / 0
04.04.2019, 09:35
    #39796142
Kast2K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDE Catastrophic failure при удалении с формы своего компонента
goldmi45Kast2K,

Что это?
Код: pascal
1.
 DataModule2:=TDataModule2.Create(Self);


DataModule2 - это глобальный экземпляр
Да, глобальный.
Написал эту стркоу уже для теста, не в этом ли причина ошибки.
Как оказалось - нет.

Утечка будет из-за этой строки, так ведь?
...
Рейтинг: 0 / 0
04.04.2019, 09:42
    #39796151
goldmi45
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDE Catastrophic failure при удалении с формы своего компонента
goldmi45Т.е. при уничтожении вашего фрейма должен будет удалиться и DataModule2.
...
Рейтинг: 0 / 0
04.04.2019, 09:43
    #39796153
Kast2K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDE Catastrophic failure при удалении с формы своего компонента
goldmi45,

Извините, пропустил :).
Но ошибку все равно не исправляет :(
...
Рейтинг: 0 / 0
04.04.2019, 09:49
    #39796160
goldmi45
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDE Catastrophic failure при удалении с формы своего компонента
Kast2Kgoldmi45,

Извините, пропустил :).
Но ошибку все равно не исправляет :(
Перегистрировали компонент, после того, как поправили?
...
Рейтинг: 0 / 0
04.04.2019, 09:53
    #39796167
Kast2K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDE Catastrophic failure при удалении с формы своего компонента
goldmi45,

Да, конечно.
uninstall - Clean - Build - install - перезапустил IDe - далее все по прежнему
...
Рейтинг: 0 / 0
04.04.2019, 10:05
    #39796182
krapotkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDE Catastrophic failure при удалении с формы своего компонента
я с момента первого использования фреймов уяснил себе, что они работать будут, только если создавать их в RunTime и с тех пор никогда не имел с ними проблем
...
Рейтинг: 0 / 0
04.04.2019, 14:12
    #39796476
roschinspb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDE Catastrophic failure при удалении с формы своего компонента
Kast2K, зачем вообще создавать свой контрол на основе TFrame?
Возьмите в качестве базового предка TCustomPanel, или TWinControl.
...
Рейтинг: 0 / 0
04.04.2019, 14:30
    #39796495
DarkMaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDE Catastrophic failure при удалении с формы своего компонента
Kast2K,

1) Зачем внутри фрейма еще создавать DataModule? Для ADOQuery и прочего родителем может служить сам фрейм.
2) Где процедура Notification()?
...
Рейтинг: 0 / 0
04.04.2019, 14:32
    #39796499
DarkMaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDE Catastrophic failure при удалении с формы своего компонента
roschinspb,

Да будут ровно те же проблемы, только в профиль.
...
Рейтинг: 0 / 0
04.04.2019, 15:37
    #39796576
roschinspb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDE Catastrophic failure при удалении с формы своего компонента
Kast2K,

Кстати не наблюдаю SetSubcomponent. Для всех созданных вручную компонентов внутри Вашего компонента должно вызываться SetSubcomponent(True)!
...
Рейтинг: 0 / 0
04.04.2019, 16:22
    #39796649
Kast2K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDE Catastrophic failure при удалении с формы своего компонента
Коллеги,
Видимо мне попадалась неправильная литература по созданию собственных компонентов. :(
авторЗачем внутри фрейма еще создавать DataModule? Для ADOQuery и прочего родителем может служить сам фрейм.
Я и не спорю, но в моем случае необходимо ещё отображать дополнительное окно по событию, которое также лезет в БД и отображает в DBLookupListbox данные. Поэтому предварительно было принято решение добавить DataModule
автор Где процедура Notification()?
Notification добавил, SetSubComponent(true) и IDesignerHook тоже.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
procedure TTestSelectUser.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (AComponent = FCommand) and (Operation = opRemove) then
    begin
      FCommand := nil;
      DataModule2:=nil;
    end;

  if FDesigner <> nil then
    FDesigner.Notification(AComponent, Operation);
end;



Удалил динамическую форму.

Ошибка пока такая же.

Коллеги, посоветуйте, пожалуйста, хорошую книгу или мануал по созданию компонентов, т.к. как показывает практика, не стоит ориентироваться на сырцы студии и иных доступных компонентов без нормального понимания базы и подхода.
...
Рейтинг: 0 / 0
04.04.2019, 17:32
    #39796718
roschinspb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDE Catastrophic failure при удалении с формы своего компонента
Kast2K, вообще правильный подход такой, делаете минимум (пустой компонент), компилируете, устанавливаете, проверяете как работает в простейшем приложении (вариант когда кинули компонент на пустую форму и вариант когда сохранили и загрузили форму с компонентом). Если всё Ok, добавляете что-то минимальное, проверяете, если всё Ok тогда опять и т. д. пока не сломается. Когда сломалось буде по-крайней мере ясно на чем сломалось.
...
Рейтинг: 0 / 0
05.04.2019, 07:32
    #39796918
Kast2K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDE Catastrophic failure при удалении с формы своего компонента
roschinspbKast2K, вообще правильный подход такой, делаете минимум (пустой компонент), компилируете, устанавливаете, проверяете как работает в простейшем приложении (вариант когда кинули компонент на пустую форму и вариант когда сохранили и загрузили форму с компонентом). Если всё Ok, добавляете что-то минимальное, проверяете, если всё Ok тогда опять и т. д. пока не сломается. Когда сломалось буде по-крайней мере ясно на чем сломалось.

Вы совершенно правы.
Двигаясь только маленькими шагами можно получить работающий продукт. А метод "с шашкой на танки" хорош только там где точно уверен как надо делать и что может произойти.

Спасибо всем откликнувшимся.
Я разобрался в своем примере и получил работающий компонент (добавит\удалить\создать в дизайнере\ в рантайме и т.д.).
Но в продакшен это пока не пущу.

P.S. "О сколько нам открытий чудных готовят Просвещенья дух, и опыт, сын ошибок трудных..."
...
Рейтинг: 0 / 0
05.04.2019, 13:13
    #39797225
DarkMaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDE Catastrophic failure при удалении с формы своего компонента
Kast2K,

Так поделись с общественностью, в чем была причина?
...
Рейтинг: 0 / 0
05.04.2019, 15:59
    #39797393
Kast2K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDE Catastrophic failure при удалении с формы своего компонента
DarkMaster,

Изначально проблема была в моём желании назначать компоненту ADOConnection выбирая из списка.
Далее методом постепенного добавления элементов было выявлено, что для адекватной работы необходимо все компоненты доступа к БД создавать в динамике. Причём, студия не валится в ошибкой если компоненты создаются с owner=nil. При указании Self студия валится.

Код результата (не идеален)


Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
unit uCMPCreate;

interface

uses
  Winapi.Windows, System.SysUtils, System.Classes, Vcl.Controls, Vcl.Forms,
  Data.DB, Data.Win.ADODB,
  Vcl.DBCtrls, Vcl.StdCtrls, Vcl.Buttons, Comobj, Variants;

const
  SQLShops=' select id_shop, shop_name '+
           ' from AllShops '+
           ' order by shop_name';

  TTestCMPCreate = class(TFrame)
    GroupBox4: TGroupBox;
    Label3: TLabel;
    Label4: TLabel;
  private
    { Private declarations }
    FADOQuery,
    aqShops:TADOQuery;

    function  GetConnection: TADOConnection;
    procedure SetConnection(const Value: TADOConnection);
  protected
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  public
    constructor Create(AOwner:TComponent);override;
    destructor Destroy; override;
  published
    { Published declarations }
    property Connection:TADOConnection read GetConnection write SetConnection;
  end;

procedure Register;

implementation

{$R *.dfm}

procedure Register;
begin
  RegisterComponents('Samples', [TTestCMPCreate]);
end;

{ TTestCMPCreate }

constructor TTestCMPCreate.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  FADOQuery:=TADOQuery.Create(nil);
  FADOQuery.SetSubComponent(True);

  aqShops:=TADOQuery.Create(nil);
  aqShops.SetSubComponent(True);
  aqShops.SQL.Text:=SQLShops;
end;

destructor TTestCMPCreate.Destroy;
begin
  FreeAndNil(aqShops);
  FreeAndNil(FADOQuery);
  inherited Destroy;
end;

function TTestCMPCreate.GetConnection: TADOConnection;
begin
  if Assigned(FADOQuery.Connection) then
    Result := FADOQuery.Connection
  else
    Result:=nil;
end;

procedure TTestCMPCreate.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited Notification(AComponent,Operation);
  if (AComponent = FADOQuery) and (Operation = opRemove) then
    begin
      aqShops.Connection:=nil;
      FADOQuery.Connection := nil;
    end;
end;

procedure TTestCMPCreate.SetConnection(const Value: TADOConnection);
var
  ac:TADOConnection;
begin
  ac:=Connection;
  if ac <> Value then
    begin
      if ac<>nil then
        ac.RemoveFreeNotification(Self);

      FADOQuery.Connection := Value;
      aqShops.Connection:=FADOQuery.Connection;

      if Assigned(Value) then
        begin
          Value.FreeNotification(Self);
        end;
    end;
end;

end.


...
Рейтинг: 0 / 0
08.04.2019, 12:22
    #39798019
roschinspb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDE Catastrophic failure при удалении с формы своего компонента
Kast2KDarkMaster,
...все компоненты доступа к БД создавать в динамике... Вообще это как бы намек, что не стоит в одну кучу валить графические контролы и объекты доступа к БД. Хорошей практикой является какраз наоборот разделение "бизнес логики" и "графического представления". Т. е. контрол заранее ни чего не знает о наборе данных, а набор данных ни чего не знает о контролах к которым он подключен.
В приведенном примере надо было разобраться с тем, как прикрутить не AdoQuery, a TDataSource и к нему уже любой TDataSet, который может быть вовсе не ADO, и лежать в другом модуле, который еще не создали.
...
Рейтинг: 0 / 0
09.04.2019, 03:57
    #39798471
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
IDE Catastrophic failure при удалении с формы своего компонента
krapotkinя с момента первого использования фреймов уяснил себе, что они работать будут, только если создавать их в RunTime
Зависит от радиуса кривизны рук.
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / IDE Catastrophic failure при удалении с формы своего компонента / 19 сообщений из 19, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]