ZIK1337
@ZIK1337

Delphi7 — исключение класса EAccessViolation — как исправить?

Здравствуйте, при работе с потоками на Delphi7 столкнулся с ошибкой:
"Проект вызвал исключение класса EAccessViolation с сообщением 'Access violation at address 00450036 in module Read of address 0000000E"
Скрин ошибки:
spoiler
p9nHL9X.jpg

Как исправить?

Код Unit_3:
spoiler
unit Unit3;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, ComCtrls, Unit3_1;

type
  TForm1 = class(TForm)
    PaintBox1: TPaintBox;
    PaintBox2: TPaintBox;
    PaintBox3: TPaintBox;
    TrackBar1: TTrackBar;
    TrackBar2: TTrackBar;
    TrackBar3: TTrackBar;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Button5: TButton;
    Button6: TButton;
    Button7: TButton;
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure TrackBar1Change(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button7Click(Sender: TObject);

  private
    { Private declarations }
  public
    Thread1, Thread2, Thread3:TMoveThread;
  end;

var
  Form1: TForm1;

implementation
{$R *.dfm}

  procedure TForm1.FormCreate(Sender: TObject);
  var taxi00, taxi01: TbitMap;
    begin
      taxi00:=tbitmap.Create;  // Создается объект BitMap
      taxi00.LoadFromFile('taxi00.bmp'); // В него загружается изображение
      taxi01:=tbitmap.Create;
      taxi01.LoadFromFile('taxi01.bmp');
      thread1:=TMoveThread.Create(taxi00,taxi01,PaintBox1); //Создается поток
      Thread1.Priority:=tpLowest;  //Устанавливается небольшой
                         //приоритет у потока, чтобы поток был управляемым и не
                         //забирал все ресурсы.
      thread2:=TMoveThread.Create(taxi00,taxi01,PaintBox2);
      Thread2.Priority:=tpLowest;
      thread3:=TMoveThread.Create(taxi00,taxi01,PaintBox3);
      Thread3.Priority:=tpLowest;
      Thread1.Suspend;Thread2.Suspend; Thread3.Suspend;

    end;

  procedure TForm1.Button4Click(Sender: TObject);
    begin
      if Thread1.Suspended=false then  Thread1.Suspend;
    end;

  procedure TForm1.Button5Click(Sender: TObject);
    begin
      if Thread2.Suspended=false then  Thread2.Suspend;
    end;

  procedure TForm1.Button6Click(Sender: TObject);
    begin
      if Thread3.Suspended=false then  Thread3.Suspend;
    end;

  procedure TForm1.Button1Click(Sender: TObject);
    begin
      if Thread1.Suspended=true then  Thread1.Resume;
    end;

  procedure TForm1.Button2Click(Sender: TObject);
    begin
      if Thread2.Suspended=true then  Thread2.Resume;
    end;

  procedure TForm1.Button3Click(Sender: TObject);
    begin
      if Thread3.Suspended=true then  Thread3.Resume;
    end;

  procedure TForm1.Button7Click(Sender: TObject);
    begin
      close;
    end;

  procedure TForm1.TrackBar1Change(Sender: TObject);
    var I: integer;
      priority:TThreadPriority;
    { Изменение приоритета соответствующего потока }
    begin
      priority:=tpIdle;
      for i:=0 to ((sender as ttrackbar).position -1) do inc(priority);
      if sender=trackbar1 then thread1.priority:=priority  else
      if sender=trackbar3 then thread3.priority:=priority
      else thread2.Priority:=priority;
    end;

end.

Код Unit3_1:
spoiler
unit Unit3_1;

interface

uses
  Classes, Graphics, ExtCtrls;

type
  TMoveThread = class(TThread)
  private
    FBox: TPaintBox;           // Где воспроизводится картинка
    b0,b1: tbitmap;            // Сами картинки
    i:integer;                 // Для определения координат картинки
    procedure DoVisualSwap;    // Одна процедура двигает вправо,
    procedure DoVisual;        // Другая влево
  protected
    procedure Execute; override;
  public
    Thread1, Thread2, Thread3:TMoveThread;
    constructor Create(a,b: TBitmap; c:TPaintBox);
    destructor Destroy; override;
  end;

implementation

  constructor TMoveThread.Create(a,b:tbitmap; c:TPaintBox);
    begin
      b0:=a;b1:=b;Fbox:=c;i:=0;
      inherited Create(False);
    end;

  procedure TMoveThread.DoVisualSwap;{Двигает картинку вправо}
    begin
       with FBox do
        begin
         canvas.Draw(i,0,b0);
         inc(i);
        end;
    end;

   procedure TMoveThread.DoVisual;   { Двигает картинку влево }
    begin
        with FBox do
           begin
                  canvas.Draw(i,0,b1);
                  dec(i);
           end;
    end;

  procedure TMoveThread.Execute; {В зависимости от координат
                                  картинка двигается влево или вправо }
    begin
      while true do
        begin
          while i<=(fbox.Width+b0.Width) do Synchronize(DoVisualSwap);
          while i>=(0-b0.Width) do Synchronize(DoVisual);
        end;
    end;

  destructor TMoveThread.Destroy;
    begin
     b0.free;
     b1.free;
     inherited Destroy;
    end;

end.

Скрин приложения:
spoiler
7mq9gEC.jpg

Картинки "taxi00.bmp" и "taxi01.bmp" лежат в папке с проектом:
spoiler
8UzndOW.jpg
  • Вопрос задан
  • 557 просмотров
Пригласить эксперта
Ответы на вопрос 1
@StockholmSyndrome
у вас все три потока работают с одними и теми же картинками, что порождает конфликт потоков
Ответ написан
Ваш ответ на вопрос

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

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