powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / удалить элемент TList<>
25 сообщений из 26, страница 1 из 2
удалить элемент TList<>
    #39993798
GrigoriyFomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
3-й день кодинга - дает мозг сбои. Задача для меня нетипичная, поэтому прошу совета гуру.
Есть запись типа
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
type
	TcfOrdElem=record
		f: TcfAddSaleForm; //Дочерняя форма редактирования заказа
		p:TPanel; //Панель на TFlowPanel для имитации плиток с заказами
  	l:TDzHTMLText; //Label с простой HTML раскраской, на предыдущей панели, где выводим краткое содержание заказа
  end;


	ords:Tlist<TcfOrdElem>; //Член класса главной формы - массив с заказами



Вот выводятся панели-плитки с одновременно обрабатываемыми заказами (типа официант обслуживает 3 столика и у каждого столика свои заказы. Кликаем на панель - активирует соотв. окно с редактированием заказа TcfAddSaleForm
Но вот незадача. В TcfAddSaleForm официант жмет ОТМЕНИТЬ заказ - как из этой формы грохнуть саму форму редактирования, лейбл и панель из главной формы, а затем и сам элемент дженерика (тоже на главной форме)? какое проперть нужно создать в TcfAddSaleForm, чтоб это можно было использовать для моей задачи?
Чет, туплю.
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993799
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
GrigoriyFomin
как из этой формы грохнуть саму форму редактирования

Пошли окну сообщение "умри".
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993800
GrigoriyFomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ъъъъъ
GrigoriyFomin
как из этой формы грохнуть саму форму редактирования

Пошли окну сообщение "умри".

Это понятно, форму я по Free прикончу - как в основной форме грохнуть связанные с ней элементы интерфейса? они в массиве?
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993802
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
GrigoriyFomin
ъъъъъ
пропущено...

Пошли окну сообщение "умри".

...как в основной форме грохнуть связанные с ней элементы интерфейса?

Пошли сообщение "основной" форме.

GrigoriyFomin
они в массиве?

Никто, кроме тебя, не знает.
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993803
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GrigoriyFomin,

Сделать у формы поле типа ^TcfOrdElem и при создании формы назначать его. При закрытии заказа отправлять родительской форме сообщение, например WM_CANCELORDER, с этим значением в LPARAM. А она при получении этого сообщения уже пусть сама прибивает всё что надо.
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993805
GrigoriyFomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alekcvp
GrigoriyFomin,

Сделать у формы поле типа ^TcfOrdElem и при создании формы назначать его. При закрытии заказа отправлять родительской форме сообщение, например WM_CANCELORDER, с этим значением в LPARAM. А она при получении этого сообщения уже пусть сама прибивает всё что надо.

а в 64битной винде будет работать? Там же вроде приколы с адресами и int32 и int64
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993806
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
GrigoriyFomin,

будет работать.
Нет там таких приколов.
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993808
GrigoriyFomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alekcvp,

вот тут засада.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
procedure TcfMAinForm.btnAddOrderClick(Sender: TObject);
var r:TcfOrdElem;
begin
  r.f:=TcfAddSaleForm.Create(fp1);
	r.p:=TPanel.Create(fp1);
	r.p.Parent:=fp1;
  r.p.Width:=200;
  r.p.Height:=200;

	r.l:=TDzHTMLText.Create(fp1);
	(r.l as TDzHTMLText).Align:=alClient;
  (r.l as TDzHTMLText).Parent:=r.p;

  (r.l as TDzHTMLText).OnClick:=ClickItem;
  (r.f as TcfAddSaleForm).MainFormLAbel:=(r.l as TDzHTMLText);
  (r.f as TcfAddSaleForm).MainFormPanel:=r.p;

//Вот тут я в форму передаю ссыль на элемент
  (r.f as TcfAddSaleForm).OrdElem:=@r;

	ords.Add(r); ////Вот тут засада. Элемент я помещаю в TList. Как к нему обратиться после того, как он попал в тлист? 



так тоже не помогает
Код: pascal
1.
2.
	ords.Add(r);
  (ords.Items[ords.IndexOf(r)].f as TcfAddSaleForm).OrdElem:=@r;
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993810
GrigoriyFomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
вообщем, передал на форму основные элементы, их при закрытии грохаю, но элемент в ТЛист остается, да и бог с ним, зато нужный эффект достигнут - панель на главной форме исчезает. не знаю, может потом и будут проблемы или утечки памяти - пока работает, победить по-другому не шмог :)
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993855
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GrigoriyFomin
Код: pascal
1.
2.
3.
//Вот тут я в форму передаю ссыль на элемент
  (r.f as TcfAddSaleForm).OrdElem:=@r;
  ords.Add(r); ////Вот тут засада. Элемент я помещаю в TList. Как к нему обратиться после того, как он попал в тлист? 




Зачем к нему обращаться?.. В TcfAddSaleForm.OnDestroy отправляете сообщение основной форме:
Код: pascal
1.
PostMessage(<MainFormHandle>, WM_КАКОЕТО, 0, LPARAM(OrdElem));


После этого в обработчике этого сообщения пишете:
Код: pascal
1.
2.
3.
PcfOrdElem = ^TcfOrdElem;
....
ords.Remove(PcfOrdElem(Msg.LParam)^);
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993856
GrigoriyFomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alekcvp,

как получить адрес элемента, который был добавлен в ТЛист? Я ж работаю с локальной переменной - она в стеке, посте метода Адд она наверняка помещается по другому адресу - как узнать потом тот адрес?
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993858
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GrigoriyFominЯ ж работаю с локальной переменной - она в стеке

Эта переменная, внезапно, указатель. От перемены указателя адрес объекта не меняется.

И тупишь ты не с задачей, а с азами. Из задачи же можно просто выкинуть дженерик и она
станет тривиальной: просто в главной форме проверяй ModalResult и по mrCancel удаляй лейбл
и панель для которой вызывал свой TcfAddSaleForm.ShowModal.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993861
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GrigoriyFomin
alekcvp,
как получить адрес элемента, который был добавлен в ТЛист? Я ж работаю с локальной переменной - она в стеке, посте метода Адд она наверняка помещается по другому адресу - как узнать потом тот адрес?

Не уверен на 100%, но метод Add вроде возвращает индекс добавленного элемента, т.е. можно сделать
Код: pascal
1.
(r.f as TcfAddSaleForm).OrdElem := @ords.List[ords.Add(r)];


Тогда в OrdElem точно окажется указатель на нужный элемент в списке.
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993875
GrigoriyFomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alekcvp,

элементы могут перетасовываться в результате добавления/удаления - индекс будет меняться все время и по этому адресу может находиться другой жэлемент. Я так понимаю, в этом случае сохраняется адрес на n-й элемент ТЛиста
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993886
Читая такой топик, хочется плакать... Это задача тривиальная, решается она ровно за 5 минут.

Раз

Код: 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.
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Generics.Collections,
  {Наша форма, которую будем создавать по КД}
  Unit2;

type
  TListForms = TObjectList<TForm>;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure CloseOrderFunc(Form: TForm);
  private
    ListForms: TListForms;
  public

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.CloseOrderFunc(Form: TForm);
var
  i: Integer;
begin
  i := ListForms.IndexOf(Form);
  if i <> -1 then
    ListForms.Delete(i);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  addForm: TForm2;
  Idx: Integer;
begin
  Idx := ListForms.Add(TForm2.Create(self)); // Добавим элемент в список
  with ListForms.Items[Idx] as TForm2 do // Редактируем сам элемент в списоке
  begin
    AddInfo(Idx, CloseOrderFunc);

    Caption := 'Заказ номер №' + (Idx + 1).ToString;

    show(); // Показать форму
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ListForms := TListForms.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ListForms.Free; // Список больше не нужен
end;

end.




Два
Код: 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.
unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TCloseOrderFunc = procedure(Form: TForm) of object;

  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  private
    IndexListForm: integer;

    CloseOrder: TCloseOrderFunc;
  public
    procedure AddInfo(IndexListForm: integer; CloseOrder: TCloseOrderFunc);
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.AddInfo(IndexListForm: integer; CloseOrder: TCloseOrderFunc);
begin
  self.IndexListForm := IndexListForm;
  self.CloseOrder := CloseOrder;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
  ShowMessage('Заказ в списке номер №' + (IndexListForm + 1).ToString);
end;

procedure TForm2.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose := MessageDlg('Закрыть заказ? №' + (IndexListForm + 1).ToString, mtInformation, mbOKCancel, 0) = mrOK;
  if CanClose then
    CloseOrder(self); // Удаляем наш заказ из списка
end;

end.




Что сложного?
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993890
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный,

Он хочет в списке хранить не формы, а свои записи в которых так же хранится ссылка на дополнительные компоненты.
Хотя, ИМХО, действительно проще будет эти ссылки сделать свойствами этой формы, а саму форму хранить в обычном TList, тогда и дженерики тут нафиг не нужны. И при закрытии формы, сначала убивать доп. компоненты по ссылкам из свойств этой формы, а потом саму форму.
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993896
alekcvp,

Вообще ПОФИГ это задача на столько простая, что её можно как угодно модифицировать

Код: 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.
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Generics.Collections,
  {Наша форма, которую будем создавать по КД}
  Unit2;

type
  TInfoRec = record
    self: TForm;
    str: string;
  end;

  TListForms = tdictionary<TForm, TInfoRec>;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure CloseOrderFunc(Form: TForm);
  private
    ListForms: TListForms;
  public

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.CloseOrderFunc(Form: TForm);
begin
  if ListForms.ContainsKey(Form) then
    ListForms.Remove(Form);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  v: TInfoRec;
  Idx: Integer;
begin
  Idx := ListForms.Count;
  v.self := TForm2.Create(self);
  v.str := 'Информация о заказе: №' + (Idx + 1).ToString;
  with v.self as TForm2 do
  begin
    AddInfo(Idx, CloseOrderFunc);

    Caption := 'Заказ номер №' + (Idx + 1).ToString;

    show(); // Показать форму
  end;
  ListForms.Add(v.self, v);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ListForms := TListForms.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ListForms.Free; // Список больше не нужен
end;

end.



Второй модуль трогать не надо, хотя в первом модуле уже структура появилась для формы.
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993897
Хотя зачем для формы создавать ещё одну структуру, для меня загадка. Но и форма может быть не формой в тоже время, но задачу это не меняет.

Вместо формы объектом Формы, может быть тот же TPanel и задача будет как в первом коде. А информационным полям является класс TPanel как в данном случае TForm
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993898
В любом случае в базу данных нужно будет добавлять информацию о заказах, от этого просто не уйти.

К примеру выключили свет, все формы закрылись. Включаем компьютер, и по информации из базы мы создаём все формы как это было изначально.


По этому хранения структуры какой - то там в TList которая свой грою несёт на себе... Это ещё за затея...
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993901
GrigoriyFomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВсеРазумный,

хранить открытые заказы в базе - тоже наверное верно, мало ли что произойдет. А можно как-то в блоб сеарелизовать форму? Ну чтоб не хранить все введенные данные в нее вручную? (там сами позиции, скидки, дисконты, сотрудники и проч.
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993902
GrigoriyFomin,

Ты всё это должен хранить в базе, создав простую структуру, по которой будешь автосоздавать формы, компоненты и прочее. И записывать данные в эти компоненты.

И потом удалять из базы, когда это уже стало неактуально.
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993903
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GrigoriyFomin
ВсеРазумный,

хранить открытые заказы в базе - тоже наверное верно, мало ли что произойдет. А можно как-то в блоб сеарелизовать форму? Ну чтоб не хранить все введенные данные в нее вручную? (там сами позиции, скидки, дисконты, сотрудники и проч.


TStream.WriteComponent()
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993904
GrigoriyFomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВсеРазумный,

блин, хотел как попроще, придется теперь монстра воротить я думал можно как-то слепок текущей формы в поток засунуть, типа дампа памяти или еще как-то. Чтоб не перебирать все нужные поля
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993905
GrigoriyFomin,

Свойства самого класса ты никак не сохранишь, по этому вариант только с помощью базы.
...
Рейтинг: 0 / 0
удалить элемент TList<>
    #39993959
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный
GrigoriyFomin,
Свойства самого класса ты никак не сохранишь, по этому вариант только с помощью базы.

Что это не сохранишь? TBlobStream.WriteComponent() не прокатит что-ли?
...
Рейтинг: 0 / 0
25 сообщений из 26, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / удалить элемент TList<>
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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