![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Необходимо написать программу с применением класса. Написал сначала без класса - все ок. Перенес процедуры в класс - все ок. Перенес переменные из вара в класс - начало выбивать ошибку EAcessViolation при обращении к любой из этих переменных, а их значение = inaccessible value. Пробовал обращаться и напрямую и через Property - без разницы.
Unit1: Код HTML:
Unit2: Код HTML:
сам проект project1.zip |
|
#2
|
||||
|
||||
|
За такой код, в угол ставить нужно - на горох. Переменная B : TPaint, кто её создавать будет, Пушкин?
Код:
B := TPaint.Create; |
|
#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. |
| Этот пользователь сказал Спасибо angvelem за это полезное сообщение: | ||
7nik (28.02.2012)
| ||
|
#8
|
|||
|
|||
|
angvelem у меня задание было про дочерний класс, за отступы мой прерод ничего не говорит, да и посравнением с некоторыми однокурсниками я меня большие отступы.
За fCanvas:TCanvas; и т. д. еще раз спасибо, а то не знал как по нормальному сделать)) З.Ы. Почему uses unit2; в implementation лучше чем в interface? Последний раз редактировалось 7nik, 28.02.2012 в 02:55. |
|
#9
|
||||
|
||||
|
Про класс наследник заранее сказано не было, а смысла в нём было мало вот я и убрал. Добавишь как было. За отступы я ничего не говорил, у меня такие, как я всегда привык писать. Когда я говорил, что код кака, имелось в виду обращение из класса к TPaintBox-у. Класс вообще ничего не должен знать ни о каких контролах с которыми работает, в данном случае достаточно было передать Canvas, соответственно и ссылка на unit1 была убрана. Опять же про подключение unit2, можно прописать и в интерфейсной части, но опять же привычка лишнее прятать в исполняемую часть, чтобы потом не нарваться на циркулярные ссылки.
|
| Этот пользователь сказал Спасибо 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. |
|
#11
|
||||
|
||||
|
Думаю, достаточно уже того, что класс TBobina есть потомком класса TObject
. Зачем делать класс-родитель, если потомок только один? |
|
#12
|
||||
|
||||
|
Как пишет ТС:
Цитата:
|