Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: 2 класса рисующие фигуры из абстрактного  (Прочитано 6210 раз)
0 Пользователей и 1 Гость смотрят эту тему.
eugrita
Помогающий

ru
Offline Offline

« : 02-06-2011 14:05 » 

Задание
Разработать иерархию классов Delphi. Разместить определение классов в отдельном модуле.
Класс, позволяющий рисовать окружность некоторого размера с центром в точке, определен-ной нажатием левой клавиши мыши.
Класс, позволяющий рисовать ветвление из двух линий с окружностями на концах (ветви идут вниз симметрично под углом 300  из точки, определенной нажатием правой клавиши мыши).
Параметры задаются с использованием интерфейсных элементов.
пытаюсь построить иерархию классов. в unit UCls - собираю определения и реализации методов всех необходимых классов
Сначала абстрактный класс TFigure
Код:
unit Ucls;
Interface
  Type TFigure = object
    x0,y0:single; {центр фигуры}
    size:single;{размер квадрата}
    procedure draw(frm:TForm);virtual; {метод рисования}
    constructor Init(x,y,sz:single);
  end;

implementation
  procedure TFigure.draw(frm:TForm);
  begin

  end;
Метод рисования draw должен где-то рисовать - ему надо как параметр передать Canvas
Я -пытаюсь передать frm:TForm но чтоб дельфя поняла этот тип где-то раньше должен стоять
uses Forms; но его влепить некуда если первым послк unit UCls - компилятор ругает что должна бытьсекция interface, если после объявл класса или после implementation - то цепляется к параметру
frm:TForm. Как быть?

Добавлено через 45 минут и 23 секунды:
Извините. Сам вопрос поставил-сам решил - надо было влепить
uses Forms,Graphics; после Interface но до Type
« Последнее редактирование: 02-06-2011 14:54 от eugrita » Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #1 : 02-06-2011 15:44 » 

Некрасивое решение - передавать в класс саму форму. А если надо рисовать не на форме. В общем как минимум не универсальное решение. Я бы в метод Draw передавал хендл контекста устройства в котором будет осуществлено рисование:
Код:
procedure draw(dc: HDC);virtual;
В классе создаешь член типа TCanvas:
Код:
FCanvas: TCanvas;

constructor TFigure.Init(x,y,sz:single);
begin
  FCanvas := TCanvas.Create;


end;

procedure TFigure.draw(dc: HDC);
begin
   FCanvas.Handle := dc;

end;
Ну и не забываем в деструкторе класса освободить память под объект FCanvas.
Записан
eugrita
Помогающий

ru
Offline Offline

« Ответ #2 : 02-06-2011 21:16 » 

понял. со временем разберу. Сейчас -другая проблема
классы созданные так (см ниже) работают
Код:
Type TFigure = object
    x0,y0:Integer;
    size:Integer;
    procedure draw(frm:TForm);virtual; {ïðîòîòèï ôóíêöèè}
    constructor Init(x,y,sz:Integer);
  end;
 Type TCircle = object(TFigure)
   R:Integer;{}
   procedure draw(frm:TForm);virtual;
   constructor Init(x,y,sz:Integer);
   destructor Destroy;
 end;
destructor TCircle.Destroy;
  begin
    
  end ;
но проблема в вызове деструктора. Т.е надо чтобы по кнопке  разрушить созданные объекты.
Как понимаю созданные классы не являются наследниками TObject -соответственно они не понимают методов Create и Free, а также FreeAndNil
Даже при всем желании не могу сделать их наследниками TObject так как изменение
Type TFigure = object(TObject) не проходит
как-тогда быть? писать свой деструктор Destroy? И что там писать?
В коде выше я включил деструктор Destroy, но что писать -не знаю. Срабатывает, но непонятно, уничтожаются ли
Объекты у меня описаны в секции var главной программы var cir:TCircle;
вызов деструктора -через cir.Destroy;
« Последнее редактирование: 02-06-2011 21:19 от eugrita » Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #3 : 03-06-2011 03:22 » 

А зачем ты используешь object?
Делай классы и будет счастье:
TFigure = class
TCircle = class(TFigure)

В этом случае можешь наследовать и от TObject, но не нужно. Если использовать класс, то полученный объект имеет деструктор и метод Free для освобождения памяти объекта. Тебе достаточно только определить свой деструктор, если нужно выполнять какие то действия при удалении объекта, а для освобождения памяти вызывать метод Free.
Записан
eugrita
Помогающий

ru
Offline Offline

« Ответ #4 : 03-06-2011 03:57 » 

вроде получилось, использовал ваше 1-е предложение:
Код:
procedure TFigure.draw(dc: HDC);
  begin
    FCanvas.Handle := dc;
    fCanvas.Brush.Color := clRed;
  end;
...
procedure TCircle.draw(dc: HDC);
  begin
    inherited  draw(dc);
     fCanvas.Ellipse(x0-R,y0-R,x0+R,y0+R);
  end;

вызов:
Код:
var
  Form1: TForm1;   dc : HDC;
....
dc := GetDC (Handle);
...
 cir:=TCircle.Create;
         cir.Init(X,Y,siz);
         cir.draw(DC);
однако единственно при  fCanvas.Ellipse(x0-R,y0-R,x0+R,y0+R);
рисует круги с красным заполнением (не так как раньше)
« Последнее редактирование: 03-06-2011 04:30 от eugrita » Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #5 : 03-06-2011 04:12 » 

1. Конструктор в классе лучше называть Create, а деструктор Destroy.
Открой исходники дельфийских модулей и посмотри как там определяются классы, конструкторы и деструкторы. Также не помешало бы почитать литературу.
2.  Ты вызываешь несуществующий метод self.Create. Ведь у тебя конструктор определен по имени Init
« Последнее редактирование: 03-06-2011 04:16 от zubr » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines