|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Ошибка EAcessViolation при перемещении переменных из вара в класс
Необходимо написать программу с применением класса. Написал сначала без класса - все ок. Перенес процедуры в класс - все ок. Перенес переменные из вара в класс - начало выбивать ошибку EAcessViolation при обращении к любой из этих переменных, а их значение = inaccessible value. Пробовал обращаться и напрямую и через Property - без разницы.
Unit1: Код HTML:
Unit2: Код HTML:
сам проект project1.zip |
#2
|
||||
|
||||
За такой код, в угол ставить нужно - на горох. Переменная B : TPaint, кто её создавать будет, Пушкин?
Код:
B := TPaint.Create; Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
#3
|
||||
|
||||
У тебя B=nil, для его инициализации нужно вызвать конструктор класса
Код:
b:=TPaint.Create; Конструктор вызывай перед первым обращением к обьекту или его свойствам. Желательно в конструкторе формы. И еще, событие OnResize само должно срабатывать при запуске, в OnCreate формы запихивать его нет нужды. О, сорь, запоздал немножко... |
Этот пользователь сказал Спасибо YVitaliy за это полезное сообщение: | ||
7nik (28.02.2012)
|
#4
|
|||
|
|||
был конструктор:
Код:
constructor TBabina.Create; begin inhereted; AlphaP:=0; SpeedP:=10; DriftP:=0; scaleP:=1; end; Последний раз редактировалось lmikle, 28.02.2012 в 02:50. |
#5
|
||||
|
||||
Да ладно, че тут сказать. Пример:
Код:
Procedure TForm1.Button1Click(Sender:TObject); begin b:=TPaint.Create; end; |
#6
|
|||
|
|||
Огромное спасибо, заработало)))
Просто я использовал B.Create; вместо B:=TPaint.Create; поэтому и не пахало. |
#7
|
||||
|
||||
Нужно ещё исправлять, но для начала пойдёт:
Код:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, jpeg, StdCtrls; type TForm1 = class(TForm) PaintBox1: TPaintBox; Start: TButton; exit: TButton; Timer1: TTimer; EditSpeed: TLabeledEdit; EditAlpha: TLabeledEdit; procedure StartClick(Sender: TObject); procedure exitClick(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure EditKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); procedure FormResize(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1 : TForm1; implementation uses unit2; var B : TBabina; {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin B := TBabina.Create(PaintBox1.Canvas); end; procedure TForm1.FormDestroy(Sender: TObject); begin B.Free; end; procedure TForm1.FormResize(Sender: TObject); //ñìåíà ìàñøòàáà ïðè ñìåíå ðàçìåðà ôîðìû begin if (PaintBox1.Width / 400 > PaintBox1.Height / 300) then B.Scale := PaintBox1.Height / 300 else B.Scale := PaintBox1.Width / 400 - 0.03; if (B.Speed = 0) then B.Draw; end; procedure TForm1.StartClick(Sender: TObject); //óñòàíîâêà íîâûõ çíà÷åíèé var n : Integer; Buff : Single; begin PaintBox1.Canvas.FillRect(PaintBox1.ClientRect); val(EditSpeed.Text, Buff, n); B.Speed := Buff; val(EditAlpha.Text, Buff, n); B.Alpha := Buff; B.Drift := 0; if (B.Speed = 0) then Timer1.Enabled := False else Timer1.Enabled := True; Timer1Timer(self); end; procedure TForm1.exitClick(Sender: TObject); //âûõîä begin Application.Terminate; end; procedure TForm1.Timer1Timer(Sender: TObject); //"îáíîâëåíèå ðèñóíêà" begin B.Draw; end; procedure TForm1.EditKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); //îáðàáîòêà íàæàòèÿ enter begin if Key = 13 then StartClick(self); end; end. Код:
unit Unit2; interface uses Windows, Messages, SysUtils, Graphics; type TBabina = class private fCanvas : TCanvas; fAlpha, fSpeed, fDrift, fScale : Single; protected procedure Babina(a : Single; wid, x, y, r : Integer); procedure Line(x1, y1, x2, y2, wid : Integer); public constructor Create(Canvas : TCanvas); procedure Draw; property Alpha : Single read fAlpha write fAlpha; property Speed : Single read fSpeed write fSpeed; property Drift : Single read fDrift write fDrift; property Scale : Single read fScale write fScale; end; implementation constructor TBabina.Create(Canvas : TCanvas); begin fCanvas := Canvas; end; procedure TBabina.Draw; //ðàñ÷åò íîâûõ çíà÷åíèé var l1, l2 : Single; begin l1 := 7 - Round(fDrift / 1.5) mod 25; Line(75 + Round(l1), 206, 300 + Round(l1), 206, 7); l1 := Frac(fDrift / 200 / Pi) * Pi; Babina(fAlpha / 180 * Pi + l1, 10, 300, 100, 100); l2 := Frac(fDrift / 150 / Pi) * Pi; Babina(fAlpha / 180 * Pi + l2, 10, 75, 125, 75); if (Round(l1 * 1000) = 0) and (Round(l2 * 1000) = 0) then fDrift := 0; fDrift := fDrift + fSpeed; end; procedure TBabina.Line(x1, y1, x2, y2, wid : Integer); //ðèñîâàíèå òîëñòîé ïóíêòèðíîé ëèíèè var I : Integer; begin with fCanvas do begin Pen.Width := 1; Pen.Style := psDash; Pen.Color := clBlack; for I := 0 to wid - 1 do begin MoveTo(Round(x1 * fScale), Round(y1 * fScale) - I); LineTo(Round(x2 * fScale), Round(y2 * fScale) - I); end; end; end; procedure TBabina.Babina(a : Single; wid, x, y, r : Integer); //ðèñîâàíèå áàáèíû(êîëåñî ñ 4 ñïèöàìè) begin with fCanvas do begin Pen.Color := clMaroon; Pen.Width := wid; wid := wid div 2; Brush.Color := clBtnFace; Ellipse(Round((x + wid - r) * fScale), Round((y + wid - r) * fScale), Round((x + wid + r) * fScale), Round((y + wid + r) * fScale)); Dec(r); MoveTo(Round((x + wid + Round(r * Sin(a))) * fScale), Round((y + wid - Round(r * Cos(a))) * fScale)); LineTo(Round((x + wid - Round(r * Sin(a))) * fScale), Round((y + wid + Round(r * Cos(a))) * fScale)); MoveTo(Round((x + wid - Round(r * Cos(a))) * fScale), Round((y + wid - Round(r * Sin(a))) * fScale)); LineTo(Round((x + wid + Round(r * Cos(a))) * fScale), Round((y + wid + Round(r * Sin(a))) * fScale)); end; end; end. Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
Этот пользователь сказал Спасибо angvelem за это полезное сообщение: | ||
7nik (28.02.2012)
|
#8
|
|||
|
|||
angvelem у меня задание было про дочерний класс, за отступы мой прерод ничего не говорит, да и посравнением с некоторыми однокурсниками я меня большие отступы.
За fCanvas:TCanvas; и т. д. еще раз спасибо, а то не знал как по нормальному сделать)) З.Ы. Почему uses unit2; в implementation лучше чем в interface? Последний раз редактировалось 7nik, 28.02.2012 в 02:55. |
#9
|
||||
|
||||
Про класс наследник заранее сказано не было, а смысла в нём было мало вот я и убрал. Добавишь как было. За отступы я ничего не говорил, у меня такие, как я всегда привык писать. Когда я говорил, что код кака, имелось в виду обращение из класса к TPaintBox-у. Класс вообще ничего не должен знать ни о каких контролах с которыми работает, в данном случае достаточно было передать Canvas, соответственно и ссылка на unit1 была убрана. Опять же про подключение unit2, можно прописать и в интерфейсной части, но опять же привычка лишнее прятать в исполняемую часть, чтобы потом не нарваться на циркулярные ссылки.
Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
Этот пользователь сказал Спасибо angvelem за это полезное сообщение: | ||
7nik (28.02.2012)
|
#10
|
||||
|
||||
При использовании класса-наследника, меняется немного:
Код:
unit Unit2; interface uses Windows, Messages, SysUtils, Graphics; type TCustomBabina = class private fCanvas : TCanvas; fAlpha, fSpeed, fDrift, fScale : Single; protected procedure Babina(a : Single; wid, x, y, r : Integer); procedure Line(x1, y1, x2, y2, wid : Integer); public procedure Draw; property Alpha : Single read fAlpha write fAlpha; property Speed : Single read fSpeed write fSpeed; property Drift : Single read fDrift write fDrift; property Scale : Single read fScale write fScale; end; TBabina = class(TCustomBabina) public constructor Create(Canvas : TCanvas); property Alpha; property Speed; property Drift; property Scale; end; implementation procedure TCustomBabina.Draw; // расчет новых значений var l1, l2 : Single; begin l1 := 7 - Round(fDrift / 1.5) mod 25; Line(75 + Round(l1), 206, 300 + Round(l1), 206, 7); l1 := Frac(fDrift / 200 / Pi) * Pi; Babina(fAlpha / 180 * Pi + l1, 10, 300, 100, 100); l2 := Frac(fDrift / 150 / Pi) * Pi; Babina(fAlpha / 180 * Pi + l2, 10, 75, 125, 75); if (Round(l1 * 1000) = 0) and (Round(l2 * 1000) = 0) then fDrift := 0; fDrift := fDrift + fSpeed; end; procedure TCustomBabina.Line(x1, y1, x2, y2, wid : Integer); // рисование толстой пунктирной линии var I : Integer; begin with fCanvas do begin Pen.Width := 1; Pen.Style := psDash; Pen.Color := clBlack; for I := 0 to wid - 1 do begin MoveTo(Round(x1 * fScale), Round(y1 * fScale) - I); LineTo(Round(x2 * fScale), Round(y2 * fScale) - I); end; end; end; procedure TCustomBabina.Babina(a : Single; wid, x, y, r : Integer); // рисование бабины(колесо с 4 спицами) begin with fCanvas do begin Pen.Color := clMaroon; Pen.Width := wid; wid := wid div 2; Brush.Color := clBtnFace; Ellipse(Round((x + wid - r) * fScale), Round((y + wid - r) * fScale), Round((x + wid + r) * fScale), Round((y + wid + r) * fScale)); Dec(r); MoveTo(Round((x + wid + Round(r * Sin(a))) * fScale), Round((y + wid - Round(r * Cos(a))) * fScale)); LineTo(Round((x + wid - Round(r * Sin(a))) * fScale), Round((y + wid + Round(r * Cos(a))) * fScale)); MoveTo(Round((x + wid - Round(r * Cos(a))) * fScale), Round((y + wid - Round(r * Sin(a))) * fScale)); LineTo(Round((x + wid + Round(r * Cos(a))) * fScale), Round((y + wid + Round(r * Sin(a))) * fScale)); end; end; constructor TBabina.Create(Canvas : TCanvas); begin inherited Create; fCanvas := Canvas; end; end. Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
#11
|
||||
|
||||
Думаю, достаточно уже того, что класс TBobina есть потомком класса TObject. Зачем делать класс-родитель, если потомок только один?
|
#12
|
||||
|
||||
Как пишет ТС:
Цитата:
Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |