Как опредилить динамический обект двухмерного масива

09.11.2009
665
1
#1
Кагда создан двухмерный масив я кликаю по рисунку и он должен исщезнуть а вместо него на етомзе месте должен появитса другой с другого масива.
При создании масива вот таким образом
Код:
for i := 1 to 12 do
for k := 1 to 12 do
begin
i2:=i-1;
k2:=k-1;
State[i2,k2]:=TImage.Create(Form1);
with state[i2,k2] do begin
Width:=20;
Height:=20;
Picture.LoadFromFile(path+'not_open.bmp');
SetBounds(20*i2, 20*k2, 20, 20);
parent:=form1;
onmousedown:=cell_mousedown(i2,k2);
end;
где cell_mousedown
Код:
 state[i_pos,k_pos].Visible:=false;
status[i_pos,k_pos].Visible:=true;
(тоесть в cell_mousedown(i2,k2); я определяю какой именно Timage для дальнейшей с ним работыю)
Выдает что ето не событие а процедура.
Как ето исправить.
 

Titan

Well-Known Member
10.06.2004
105
0
#2
Дело в том, что OnMouseDown процедура должна быть сторого определенного формата( в смысле объявления).

Delphi help:
Код:
 type TMouseEvent = procedure (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer) of object;
property OnMouseDown: TMouseEvent;
Добавлено: скажите , а зачем вам лишний код и лишние переменные ?
вот это
Код:
i2:=i-1;
k2:=k-1;
нафиг убрать.
делайте цикл от нуля, небольшие корректировки ниже по коду и будет счастье :rolleyes:
 
09.11.2009
665
1
#3
Я понял но мне надо чтоб каждый елемент имел свое действие, тоесть когода я жму на картинку етаже картинка исщезала и появлялась другая.
для етого я и писал onmousedown:=cell_mousedown(i2,k2); чтобы при создании рисунка действие знало куда обращатса(к какому имено елементу).
к примеру
Код:
procedure onmousedown...
begin
state[i2,k2].visible:=false;
status[i2,k2].visible:=true;
как ето сделать?

____________
Ету фигню
Код:
i2:=i-1;
k2:=k-1;
я вчера писал дома в 2 часа ночи а сегодня хочу доделать
 
09.11.2009
665
1
#4
Ладно тогда подскажите как сделать чтобы при создании масива каждому елементу присвоилось в onmousedown
вот такое:
Код:
var xpos,ypos,xcell,ycell:integer; point:Tpoint;
begin
getcursorpos(point)
xpos:=point.x-form1.left;
ypos:=point.y-form1.top;
xcell:=(xpos-20) mod 20;
ycell:=(ypos-41) mod 20;
end;
где Tpoint ето:
Код:
type Tpoint=record
x,y:integer;
end;
(пишитса в начате юнита)
 

Titan

Well-Known Member
10.06.2004
105
0
#5
Вообще , по-хорошему, я бы сделал отдельный класс , который бы унаследовал от TImage и добавил туда сохранение индекса элемента ну и соответственно OnMouseDown.

Если же хотите все делать в существующем коде, то не забывайте, что вам в метод OnMouseDown передается объект в Sender.
Я так понимаю, что массив State у вас глобальный.

Метод у вас будет выглядеть как-то так:
Код:
 procedure TForm1.OnMyMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
i:integer;
begin
i := Length (State);
while i > 0 do // для вашего случая, когда индекс начинается с 1..
begin
if State[i] = TImage(Sender) then
begin
//нашли индекс элемента в массиве по которому кликнули, это - i
...
//делаете все, что вам надо		
..
Exit; //больше итераций не надо - выходим из обработчика
end;
dec(i);
end;
end;
Поиск я показал по одномерному массиву, думаю для 2-х мерного не составит труда дописать, у меня нет на это времени.
Помните, что в Sender ваш объект Image, по которому кликнули. Можете делать его невидимым (TImage(Sender).Visible := false) , вызывать все его методы и т.д
 
09.11.2009
665
1
#6
Titan огромное вам спосибо
в моём случяе
Код:
procedure mymousedown(sender:Tobject);
var xpos,ypos,xcell,ycell:integer; point:Tpoint;
begin
getcursorpos(point)
xpos:=point.x-form1.left;
ypos:=point.y-form1.top;
xcell:=(xpos-20) mod 20;
ycell:=(ypos-41) mod 20;
end;
и есть сам поиск;

Код:
State[i2,k2]:=TImage.Create(Form1);
with state[i2,k2] do begin
Width:=20;
Height:=20;
Picture.LoadFromFile(path+'not_open.bmp');
SetBounds(20*i2, 20*k2, 20, 20);
parent:=form1;
onmousedown:=mymousedown;//созданому обекту присвоить процедуру mymousedown
Меня сейчас интересует как при создании обекта ему припоять определенный код(тот что я написал);
Потомучто при создании обекта onmousedown:=mymousedown;
происходит ошибка так как ето процедура а не событие.
 
09.11.2009
665
1
#7
Все не надо.
Оказывается решение очень простое: создаем рисунок;
делаем событие onMouseDown;
А при создании обекта пишем onMouseDown:=Image1MouseDown;
 

Titan

Well-Known Member
10.06.2004
105
0
#8
Все не надо.
Оказывается решение очень простое: создаем рисунок;
делаем событие onMouseDown;
А при создании обекта пишем onMouseDown:=Image1MouseDown;

Ну конечно же, только так и надо. Но вы и сразу так делали, в самом первом посте :(
 
09.11.2009
665
1
#9
Нет в начале onmousedown я писал как отдельную процедуру, а не как действие для существуещего рисунку.
 
09.11.2009
665
1
#10
кстати номер елемента в масиве можна определить еще одним способом для етого при создании пишем name:='название_масива'+inttostr(i)+'_'+inttostr(j);
а при кликание
Код:
si:=copy(TImage(Sender).Name,длина_именимасива+1,pos('_',TImage(Sender).Name)-(длина_именимасива+1));
sj:=copy(TImage(Sender).Name,pos('_',TImage(Sender).Name)+1,length(TImage(Sender).Name)- pos('_',TImage(Sender).Name)+1);
 

Titan

Well-Known Member
10.06.2004
105
0
#11
Да можно кучу хороших методов придумать. Один из индексов, который точнее всего характеризует элемент в массиве можно сохранять в поле Tag объекта.
Имхо делать преобразования из строки не лучший вариант.
 

Titan

Well-Known Member
10.06.2004
105
0
#13
Можна поинтересоватся, почему?
Как по мне код достаточно простой и не должен сильно грузить комп.
- если есть возможность сохранить без преобразрвания, почему не воспользоваться ?
- преобразование из строки - источник возможной ошибки. Меньше лишнего кода - меньше вероятность ошибок.