Задать вопрос
To4KaXD
@To4KaXD

Как решить проблему с отрисовкой картографии?

Всем привет! Сижу делаю картографию. Уже сколько сижу не могу понять кое-что.
Есть Form create, Поток1, Поток 2:
Тут создается массив объекта TPngobject и закачивается изображение "нет фото",
procedure TForm1.FormCreate(Sender: TObject);
NoImage.LoadFromFile('Data\All\loading.png');
   for pii:=0 to 20 do
   for pj:=0 to 20 do
   BEGIN
   LoTiles[pj, pii]:=TPngobject.Create();
   LoTiles[pj, pii]:=NoImage;
   END;
end;


Здесь происходит Выстраивание изображения из тайлов, и запуск второго потока

procedure TMyThread.Execute;
repeat
    tilesStartX:=deleX;
    tilesEndX:=RaidX[1];
    tilesStartY:=deleY;
    tilesEndY:=RaidY[1];
    for i:=deleY to RaidY[1] do
      begin
        for j:=deleX to RaidX[1] do //RaidX[1]
          begin
            try
            begin
            OneTileRead.Canvas.Draw(bezostX, bezostY, LoTiles[pj, pii]);
            end;
            except
             ShowMessage('Àëÿóëþ!: '+ intTostr(pj) + ':' + intTostr(pii) );
            end;
           bezostX:=bezostX+256;
            LoadRaid[a]:=0;
            LoadRaid[a]:=j;
            LoadRaid1[a]:=0;
            LoadRaid1[a]:=i;
            inc(a);
            inc(pj);
          end;
        inc(b);
        bezostX:=temp;
        bezostY:=bezostY+256;
        pj:=0;
        inc(pii);
      end;
      pii:=0;
      if oneRun=true then
      begin
           MyThread1:=TMyThread1.Create(False);
           MyThread1.Priority:=tpLowest;
      oneRun:=false;
      end;
end;
until false;


Это второй поток, включается из первого потока.

procedure TMyThread1.Execute;
repeat
pii:=0;
for i:=tilesStartY to tilesEndY do begin
pj:=0;
  for j:= tilesStartX to tilesEndX do begin
try
  if FileExists('Data\MAPSIMAGE\' + intToStr(zoom) + '\' + IntToStr(j)  + 'x' +  IntToStr(i) + '.png')
  then
  begin
  LoTiles[pj, pii].LoadFromFile('Data\MAPSIMAGE\' + intToStr(zoom) + '\' + IntToStr(j)  + 'x' +  IntToStr(i) + '.png');
  end
  else
  begin
  LoTiles[pj, pii].canvas.Draw(0,0,NoImage);
  end;
  except
ShowMessage('Òóò åððîð!');
end;
    inc(pj);
  end;
  inc(pii);
end;
 
until false;
end;


Краткое описание: Переменная LoTiles[pj, pii] уже создана и хранит изображения нет фото при загрузке формы, далее через таймер включается первый поток, через него происходит выстраивание рисунка в OneTileRead, т.к второй поток еще не включен, видно изображение нет фото. Как запущен второй поток, в котором и должно происходить обновление изображения, благодаря загрузке новых изображений в LoTiles[pj, pii], выскакивает ошибка, ошибка ничего абсолютно ничего не говорящая, Acess violation. Мои догадки такие, когда используется изображение в первом потоке второй не может загрузить новый файл... Вопрос: как сделать правильно?
  • Вопрос задан
  • 75 просмотров
Подписаться 1 Простой 1 комментарий
Пригласить эксперта
Ответы на вопрос 3
@kalapanga
Для решения таких проблем и существует отладчик. Ошибка возникает не абы где, а в конкретной строке. Выясните место возникновения ошибки, поставьте перед ним точку останова, посмотрите значения переменных когда придёте в эту точку. Так и поймёте, что приводит к ошибке.
Ошибку с нарушением границ массива поймать ещё проще. На время разработки включите в настройках опцию компилятора "Range checking".
Ответ написан
Комментировать
xpert13
@xpert13
Full Stack Developer
Вам бы подучить немного Делфи не помешал. Бегло посмотрел код и увидел большое количество неправильного или ошибочного написания кода. Вот например:
LoTiles[pj, pii]:=TPngobject.Create();
LoTiles[pj, pii]:=NoImage;

В этом куске вы сначала создаёте новый объект, записываете его ссылку в переменную LoTiles[pj, pii], а потом в эту же переменную записываете ссылку на объект NoImage. Во-первых это явно не то, что вы хотите, а во вторых теряется ссылка на созданный ранее объект и вы его уже не освободите (считай утечка памяти).
Ответ написан
Комментировать
@Kot-da-Vinci
Работа с визуальными компонентами должна быть только из основного (главного) потока. Если вам очень нужно "потрогать" визуальные компоненты из других потоков, то делать это нужно через метод Synchronize. Подробнее про него можно прочитать в справке.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы