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

Тема в разделе "Delphi - FAQ", создана пользователем Dock1100, 24 ноя 2009.

  1. Dock1100

    Dock1100 :-]

    Регистрация:
    9 ноя 2009
    Сообщения:
    678
    Симпатии:
    0
    Кагда создан двухмерный масив я кликаю по рисунку и он должен исщезнуть а вместо него на етомзе месте должен появитса другой с другого масива.
    При создании масива вот таким образом
    Код (Text):
    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
    Код (Text):
     state[i_pos,k_pos].Visible:=false;
    status[i_pos,k_pos].Visible:=true;
    (тоесть в cell_mousedown(i2,k2); я определяю какой именно Timage для дальнейшей с ним работыю)
    Выдает что ето не событие а процедура.
    Как ето исправить.
     
  2. Titan

    Titan Well-Known Member

    Регистрация:
    10 июн 2004
    Сообщения:
    105
    Симпатии:
    0
    Дело в том, что OnMouseDown процедура должна быть сторого определенного формата( в смысле объявления).

    Delphi help:
    Код (Text):
     type TMouseEvent = procedure (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer) of object;
    property OnMouseDown: TMouseEvent;
    Добавлено: скажите , а зачем вам лишний код и лишние переменные ?
    вот это
    Код (Text):
    i2:=i-1;
    k2:=k-1;
    нафиг убрать.
    делайте цикл от нуля, небольшие корректировки ниже по коду и будет счастье :rolleyes:
     
  3. Dock1100

    Dock1100 :-]

    Регистрация:
    9 ноя 2009
    Сообщения:
    678
    Симпатии:
    0
    Я понял но мне надо чтоб каждый елемент имел свое действие, тоесть когода я жму на картинку етаже картинка исщезала и появлялась другая.
    для етого я и писал onmousedown:=cell_mousedown(i2,k2); чтобы при создании рисунка действие знало куда обращатса(к какому имено елементу).
    к примеру
    Код (Text):
    procedure onmousedown...
    begin
    state[i2,k2].visible:=false;
    status[i2,k2].visible:=true;
    как ето сделать?

    ____________
    Ету фигню
    Код (Text):
    i2:=i-1;
    k2:=k-1;
    я вчера писал дома в 2 часа ночи а сегодня хочу доделать
     
  4. Dock1100

    Dock1100 :-]

    Регистрация:
    9 ноя 2009
    Сообщения:
    678
    Симпатии:
    0
    Ладно тогда подскажите как сделать чтобы при создании масива каждому елементу присвоилось в onmousedown
    вот такое:
    Код (Text):
    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 ето:
    Код (Text):
    type Tpoint=record
    x,y:integer;
    end;
    (пишитса в начате юнита)
     
  5. Titan

    Titan Well-Known Member

    Регистрация:
    10 июн 2004
    Сообщения:
    105
    Симпатии:
    0
    Вообще , по-хорошему, я бы сделал отдельный класс , который бы унаследовал от TImage и добавил туда сохранение индекса элемента ну и соответственно OnMouseDown.

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

    Метод у вас будет выглядеть как-то так:
    Код (Text):
     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) , вызывать все его методы и т.д
     
  6. Dock1100

    Dock1100 :-]

    Регистрация:
    9 ноя 2009
    Сообщения:
    678
    Симпатии:
    0
    Titan огромное вам спосибо
    в моём случяе
    Код (Text):
    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;
    и есть сам поиск;

    Код (Text):
    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;
    происходит ошибка так как ето процедура а не событие.
     
  7. Dock1100

    Dock1100 :-]

    Регистрация:
    9 ноя 2009
    Сообщения:
    678
    Симпатии:
    0
    Все не надо.
    Оказывается решение очень простое: создаем рисунок;
    делаем событие onMouseDown;
    А при создании обекта пишем onMouseDown:=Image1MouseDown;
     
  8. Titan

    Titan Well-Known Member

    Регистрация:
    10 июн 2004
    Сообщения:
    105
    Симпатии:
    0

    Ну конечно же, только так и надо. Но вы и сразу так делали, в самом первом посте :(
     
  9. Dock1100

    Dock1100 :-]

    Регистрация:
    9 ноя 2009
    Сообщения:
    678
    Симпатии:
    0
    Нет в начале onmousedown я писал как отдельную процедуру, а не как действие для существуещего рисунку.
     
  10. Dock1100

    Dock1100 :-]

    Регистрация:
    9 ноя 2009
    Сообщения:
    678
    Симпатии:
    0
    кстати номер елемента в масиве можна определить еще одним способом для етого при создании пишем name:='название_масива'+inttostr(i)+'_'+inttostr(j);
    а при кликание
    Код (Text):
    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);
     
  11. Titan

    Titan Well-Known Member

    Регистрация:
    10 июн 2004
    Сообщения:
    105
    Симпатии:
    0
    Да можно кучу хороших методов придумать. Один из индексов, который точнее всего характеризует элемент в массиве можно сохранять в поле Tag объекта.
    Имхо делать преобразования из строки не лучший вариант.
     
  12. Dock1100

    Dock1100 :-]

    Регистрация:
    9 ноя 2009
    Сообщения:
    678
    Симпатии:
    0
    Можна поинтересоватся, почему?
    Как по мне код достаточно простой и не должен сильно грузить комп.
     
  13. Titan

    Titan Well-Known Member

    Регистрация:
    10 июн 2004
    Сообщения:
    105
    Симпатии:
    0
    - если есть возможность сохранить без преобразрвания, почему не воспользоваться ?
    - преобразование из строки - источник возможной ошибки. Меньше лишнего кода - меньше вероятность ошибок.
     
Загрузка...

Поделиться этой страницей