Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 10.03.2021, 18:02
APTEMKA APTEMKA вне форума
Прохожий
 
Регистрация: 28.09.2019
Сообщения: 13
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Ошибки при работе с динамическими объектами

Всех приветствую. Только учусь работать с динамическими объектами, объясню суть вкратце: необходимо реализовать отрисовку на ScrollBox компонентов Panel,на которых будет помещён компонент WebBrowser. Создал процедуру,которая это делает,однако она зависит от количества,которое нужно создать. Если количество маленькое,например, 7 он может создать,но при закрытии приложения выводится ошибка: "Прекращена работа приложения" и ошибки. Но,например,с 20 работает и закрывается всё идеально.Прошу помощи доработать или указать на недостатки.
Код:
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
..
 { Private declarations }
  public
//массив компонентов webbrowser
  web: array of TWebBrowser;
//массив компонентов Panel
    panel:array of Tpanel;
//общее количество,которое нужно создать
   const allcount=14;
//количество объектов,которое поместится в строке в зависимости от размеров экрана
    var count:integer;
//отступ сверху
    toppos:integer;
//параметры объектов
    const widthweb=200;
    const heightweb=100;
    const interval=30;
..
 
procedure TForm1.WebCreate();
  var i,j,a,z,count:integer;
begin
 
showmessage(inttostr(allcount));
Form1.ScrollBox1.Width:=screen.Width;
Form1.ScrollBox1.Height:=screen.Height-Scrollbox1.Top;
 
Form1.toppos:=20;
showmessage(inttostr(Screen.Width));
 
//расчет штук в строке
count:=Floor(Screen.Width/(Form1.widthweb+Form1.interval));
showmessage(inttostr(count));
//расчёт сколько строк нужно нарисовать
a:=floor(allcount/count);
//задание размеров массивов
SetLength(Form1.web,Form1.allcount-1);
SetLength(Form1.panel,Form1.allcount-1);
 
 
for j := 0 to a do     begin
 
 
    for i :=j*count to ((j*count)+count-1) do
       begin
            Form1.panel[i]:=TPanel.Create(self);
            Form1.panel[i].Parent:=Form1.scrollbox1;
            Form1.web[i]:=TWebBrowser.Create(Form1.panel[i]);
            TWinControl(Form1.web[i]).Parent := Form1.panel[i];
 
            if i=j*count then  begin
                    Form1.panel[i].Left:=74 ;
            end
                   else begin
                          Form1.panel[i].Left:=Form1.panel[i-1].Left+Form1.widthweb+Form1.interval;
                     end;
 
           Form1.panel[i].Top:=Form1.toppos;
            Form1.web[i].Left:=0;
            Form1.web[i].Top:=0;
 
            //Form1.web[i].Navigate('google.com');
            Form1.web[i].Silent:=true;
 
            Form1.panel[i].Width:=Form1.widthweb;
            Form1.web[i].Width:=Form1.widthweb;
            Form1.panel[i].Height:=Form1.heightweb;
             Form1.web[i].Height:=Form1.heightweb;
       
//уборка лишних компонентов
            if i>Form1.allcount-1 then begin
              Form1.web[i].Free;
              Form1.panel[i].free;
            end;
 
 
 
 end;
 
 
 
 
 
Form1.toppos:=Form1.toppos+Form1.heightweb+Form1.interval;
end;
 
 
 
end;
Ответить с цитированием
  #2  
Старый 10.03.2021, 18:14
Аватар для dr. F.I.N.
dr. F.I.N. dr. F.I.N. вне форума
I Like it!
 
Регистрация: 12.12.2009
Адрес: Россия, г. Новосибирск
Сообщения: 663
Версия Delphi: D6/D7
Репутация: 26643
По умолчанию

Вы устанавливаете размер массива в точное значение, а создаете компоненты "до усеру" в цикле, а потом пытаетесь удалить лишние. А куда эти лишние создались?
Переделайте цикл так, чтоб лишние компоненты не создавались.
Например, сделайте проверку на количество до создания и при необходимости прерывайте цикл командой break.
__________________
Грамотно поставленный вопрос содержит не менее 50% ответа.
Грамотно поставленная речь вызывает уважение, а у некоторых даже зависть.
Ответить с цитированием
  #3  
Старый 11.03.2021, 00:31
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Я бы сказал по друому.
Там промашка с размерами массива и циклом создания точно есть. А вообще, ссылки на созданные компоненты кроме как для уничтожения таковых нужны? Может им просто Owner'а указать и пусть уничтожением занимается форма когда сама будет уничтожена?
Это во первых. А во вторых, даже если ссылки нужны. Ты создаешь таблицу компонентов NxM, так почему бы и массив не объявить двухмерный и не заниматься ерундой?

Ну и так, как вишенка на торте. В процедуре setLength указваается КОЛ-ВО элементов, а не индекс последнего. Индексация динамических массивов всегда начинается с 0. Т.е. если тебе надо создать массив из 20 элементов, то и в SetLength надо передавать 20, а индексы у них будут от 0 до 19.
Ответить с цитированием
Ответ


Delphi Sources

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

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 21:09.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025