Здравствуйте, уважаемыепрограммисты!
Столкнулся с такой проблемой:
Необходимо реализовать функцию удаления картинок (TImg) из контекстного меню.
Имеется 2 юнита. Главный и для работы с картинками:
Код:
unit Unit1;
interface
uses
Unit2,
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus;
type
TForm1 = class(TForm)
aBlocksPM: TPopupMenu;
Del: TMenuItem;
procedure PPBtn_DelBlckClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;Shift:TShiftState; X, Y: Integer);
private
public
n: aBlocks;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
n := aBlocks.Create;
n.NewBlock(self, Round(form1.Width/2-5), 50, 0,2); // Создаем 0й
n.aBlock[n.count-1].PopupMenu:=aBlocksPM;
n.NewBlock(self, Round(form1.Width/2-5), form1.Height-70, 1,2); // и 1й блоки
n.aBlock[n.count-1].PopupMenu:=aBlocksPM;
end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
n.NewBlock(self, x, y, n.count ,2); //Создаем новый блок при клике на форме
n.aBlock[n.count-1].PopupMenu:=aBlocksPM; // Присваиваем ему контекстное меню
end;
procedure TForm1.PPBtn_DelBlckClick(Sender: TObject); // процедура выполняется при клике на Del в контекстном меню
var i:integer;
begin
if n.aBlockSelected<n.count-1 then
for i:= n.aBlockSelected to n.count-2 do // Сдвигаем все элементы массива по очереди
begin
n.aBlock[i]:=n.aBlock[i+1];
end;
n.Count:=n.Count-1;
FreeAndNil(n.aBlock[n.Count]); // Обнуляем конечный элементт
SetLength(n.aBlock, n.Count); // Изменяем размер массива
end;
end.
unit Unit2;
interface
uses windows, SysUtils, System.Classes, Vcl.Graphics, Vcl.Controls, ExtCtrls;
type TImg = class(TImage)
private
public
id,nu : integer; //id - тип блока, nu - его номер
end;
aBlocks = class
private
num : integer; // № конечного эл-та массива
public
aBlock: array of TImg;
aBlockSelected:integer; // номер выделенного эл-та
constructor Create;
procedure NewBlock(Sender: TObject; X, Y, number, id1: Integer);
destructor DeleteBlock(Sender: TObject;index: Integer);
procedure Draw(numb:integer);
procedure aBlockContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean);
property Count: integer read num write num;
end;
implementation
constructor aBlocks.Create;
begin
num:=0;
aBlockSelected:=-1; // задаем начальные параметры
end;
procedure aBlocks.NewBlock(Sender: TObject; X, Y, number, id1: Integer);
begin
if number=num then
begin
num := num + 1;
SetLength(aBlock, num);
end;
aBlock[number] := TImg.Create(Sender as Tcomponent);
with aBlock[number] do
begin
onContextPopup:=aBlockContextPopup;
id:=id1;
nu:=number;
Left := X - 25;
Top := Y - 25;
Width := 50;
Height := 50;
Parent := Sender as TWinControl;
Constraints.MinHeight:=40;
Constraints.MinWidth:=40;
end;
if number>2 then aBlock[number].id:=id1 else aBlock[number].id:=2;
Draw(number);
end;
destructor aBlocks.DeleteBlock(Sender: TObject; index: Integer);
var i:integer;
begin
//
end;
procedure aBlocks.Draw(numb:integer);
begin
aBlock[numb].Canvas.Brush.Color:=clWhite;//Цвет Заливки
aBlock[numb].Canvas.Pen.Width:=2;//толщина линии контура
aBlock[numb].Canvas.Pen.Color:=clBlack;//Цвет контура линии
aBlock[numb].Canvas.rectangle(1,1,aBlock[numb].Width,aBlock[numb].Height)
case numb
if numb=0 then aBlock[numb].Canvas.TextOut(aBlock[numb].width-30,aBlock[numb].height-25,'n0')
else if numb=1 then aBlock[numb].Canvas.TextOut(aBlock[numb].width-30,aBlock[numb].height-25,'nф')
else aBlock[numb].Canvas.TextOut(aBlock[numb].width-30,aBlock[numb].height-30,inttostr(numb-1)+'N');
if numb=aBlockSelected then
with aBlock[numb].Canvas do
begin
Brush.Color:=clBlack;
rectangle(10,1,40,7);
end;
end;
procedure aBlocks.aBlockContextPopup(Sender: TObject; MousePos: TPoint;
var Handled: Boolean);
var i:integer; FirstSelect:boolean;
begin
FirstSelect:=false;
if aBlockSelected>-1 then
begin
i:=aBlockSelected;
FirstSelect:=true;
end;
aBlockSelected:=(Sender as Timg).nu;
Draw(aBlockSelected);
if (aBlockSelected>-1) and FirstSelect then Draw(i);
if (aBlock[aBlockSelected].nu=0) or (aBlock[aBlockSelected].nu=1)
then aBlock[aBlockSelected].PopupMenu.Items[0].Enabled:=false
else aBlock[aBlockSelected].PopupMenu.Items[0].Enabled:=true;
end;
end.
Поначалу блоки нормально удаляются, а потом начинает выдавать ошибки доступа. Подскажите в чем может быть проблема. Заранее спасибо!