![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Архитектура в CAD-системе. Изображения. [D7, XP]
Псарь © (2011-08-04 04:16:00)Делаю скромный редактор по перетаскиванию и прочему манип. с объектами-картинками.
Основной класс объекта манипуляций:
type
TDisplayObj = class
constructor Create(X, Y: LongInt);
private
FX, FY : LongInt;
FW, FH : LongWord;
FIsHit : boolean;
FAlpha : byte;
FIsBlend: boolean;
FPtDrag : TPoint;
FIsDrag : boolean;
protected
procedure SetEffect(Bmp: TBitmap);
procedure Draw(AContext: TContext; Bmp: TBitmap);
procedure OnMouseDown(X, Y: LongInt);
procedure OnMouseMove(X, Y: LongInt);
procedure OnMouseUp (X, Y: LongInt);
public
function GetBounce: TRect;
procedure Aligned(Align: LongWord);
function HitTest(X, Y: LongInt): boolean; overload;
function HitTest(const R: TRect): boolean; overload;
property PosX: LongInt read FX write FX;
property PosY: LongInt read FY write FY;
property Alpha: byte read FAlpha write FAlpha;
property IsBlend: boolean read FIsBlend write FIsBlend;
end;
Очевидно, что хранить в каждой таком объекте (коих десятки и сотни) TBitmap - не выгодно по памяти.
Следовательно он должен подаваться снаружи.
Сделал ассоциативный массив, кидается TBitmap и назначается имя.
Зная имя, получаем изображение и рисуем.
Но тут гложат меня сомнения, как правильно сделать:
1) Хранить в каждом TDisplayObj строку - ключ к TBitmap?
или вынести ее в метод Draw?
2) Как задавать высоту и ширину объекта? Т.е.
ГДЕ задавать? В конструкторе по ключу имени? Или
в том же Draw? Но ведь метод GetBounce может понадобиться и без Драв.
3) Все время получать и искать в массиве по ключи при рисовании - медленно может выйти. Лучше хранить уже готовые НАЙДЕННЫЕ ТБитмапы.
Но как правильно все организовать?
зы. Троллей прошу идти в баню.
Псарь (2011-08-07 09:13:00) [1]
> Sapersky (06.08.11 19:08) [9]
Большущее Вам спасибо. =)
Sapersky (2011-08-06 19:08:00) [2]Значит, когда уничтожили Bmp1, то изображение в нем перенеслось
в Bmp2?
Изображения вообще не хранятся в TBitmap, они хранятся во внутреннем контейнере TBitmapImage.
При выполнении Assign двум или более TBitmap'ам назначается один TBitmapImage, при этом TBitmapImage хранит кол-во владельцев (счётчик ссылок). При уничтожении TBitmap счётчик ссылок уменьшается, и TBitmapImage уничтожается только тогда, когда он равен 0, т.е. больше нет владельцев.
И кстати, исходники всего этого открыты (хотя для новичка, возможно, выглядят пугающе).
Jeer (2011-08-05 15:19:00) [3]
> Значит, когда уничтожили Bmp1, то изображение в нем перенеслось
> в Bmp2?
Если сделано по толковому, то никто не гоняет биты и байты туда-сюда.
Валидный указатель остается во втором живом объекте и этого (+ контроль ссылок) достаточно от мемликов.
Псарь (2011-08-05 12:37:00) [4]
> Ega23 © (04.08.11 10:23) [4]
> Зачем конструктор publised?
Он будет вроде как в публик?
> brother © (04.08.11 10:36) [5]
>
> > If Bmp2.Empty then Caption:= 'NULL'
>
> а так:
> If Bmp2 = nil then Caption:= 'NULL'
> ?
При чем тут это?
Мы же не уничтожаем Bmp2. Он всегда будет валидным.
А вот изображение в нем под вопросом.
> DiamondShark © (04.08.11 11:18) [6]
Значит, когда уничтожили Bmp1, то изображение в нем перенеслось
в Bmp2?
Если так, то сделаю каждому TDisplayObject'у по TBitmap.
DiamondShark (2011-08-04 11:18:00) [5]
> Псарь (04.08.11 07:57) [3]
> Почему тогда при уничтожении Bmp1, Bmp2 все равно рисуется?
Потому что
> При этом ведётся подсчёт ссылок и всё корректно уничтожается
> по мере надобности.
brother (2011-08-04 10:36:00) [6]> If Bmp2.Empty then Caption:= 'NULL'
а так:
If Bmp2 = nil then Caption:= 'NULL'
?
Ega23 (2011-08-04 10:23:00) [7]
> TDisplayObj = class
> constructor Create(X, Y: LongInt);
Зачем конструктор publised?
Псарь (2011-08-04 07:57:00) [8]
> Sapersky (04.08.11 06:58) [2]
Вы уверены?
Почему тогда при уничтожении Bmp1, Bmp2 все равно рисуется?
Или я что не понимаю.
var
Bmp1, Bmp2: TBitmap;
procedure TForm1.FormCreate(Sender: TObject);
begin
Bmp1:= TBitmap.Create;
Bmp2:= TBitmap.Create;
Bmp1.LoadFromFile('C:\image\LazerTank.bmp');
Bmp2.Assign(Bmp1);
end;
procedure TForm1.Timer1Timer(Sender: TObject); // Интервал 1.
begin
If Bmp2.Empty then Caption:= 'NULL'
else begin
Caption:= 'True';
Canvas.Draw(10, 10, Bmp2);
end;
end;
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
FreeAndNil(Bmp1);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Bmp1.Free;
Bmp2.Free;
end;
Sapersky (2011-08-04 06:58:00) [9]В TBitmap используется механизм разделения картинок. При копировании через TBitmap.Assign в новом объекте создаётся ссылка на картинку, сама картинка не копируется. При этом ведётся подсчёт ссылок и всё корректно уничтожается по мере надобности.
Можно и просто копировать переменную TBitmap присвоением, при этом она работает как обычный указатель - занимает 4 байта и указывает на "чужие" данные. Но проблемы с уничтожением (уничтожили объект в одном месте, все прочие указатели "испортились") придётся решать вручную.
Псарь (2011-08-04 04:16:00) [10]TContext - расширенный TCanvas, если чо