Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема с удалением контрола, Появляется ошибка ацесс виолэйшн и т.д. 
:(
    Опции темы
Elfin
Дата 17.12.2005, 19:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 28.10.2004

Репутация: нет
Всего: нет



Возникла проблема с реализацией игры "убери лишнее" .
Условия моей программы такие:
Разработать упрощенную версию игры «Убери лишнее»: на экране появляются объекты –рисунки, среди которых есть лишний. Необходимо указать его. Использовать динамическое создание объектов.

Проблема в том что иногда после выбора нужной картинки вылетает сообщение об ошибке. Не могу найти ее причину. Подскажите в чем она может заключаться?

Привожу код

Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ImgList, ExtCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    ImageList1: TImageList;
    Button1: TButton;
    Edit1: TEdit;
    UpDown1: TUpDown;
    procedure Button1Click(Sender: TObject);
  private
    procedure CtrlClk(sender: tobject);
    procedure freeimages;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure Tform1.CtrlClk(sender: tobject);
begin
if (sender as Timage).Name='Target' then
(SENDER AS TCONTROL).FREE;
end;

procedure Tform1.freeimages;
var i: integer;
begin
  for i:=panel1.ControlCount-1 downto 0  do
  if (panel1.Controls[i] is timage) then
  panel1.Controls[i].FREE;
end;

procedure TForm1.Button1Click(Sender: TObject);
Var
  c,d,I,L: byte; E: TImage;
Begin
  freeimages;
  randomize;
  L:=random(5)+1;
  c:=strtoint(edit1.text);
  d:=random(c)+1;
  E:=nil;
  For I:=0 to c-1 Do
  Begin
    E := TImage.Create(SELF);
    E.OnClick:=CtrlClk;
    E.Parent := panel1;
    E.cursor:=crHandPoint;
    E.Left := (I mod 10) * 64 + 10;
    E.Top := 10+64*(i div 10);
    E.Width:=64;
    E.Height:=64;
    if (I+1)=d then
      begin
        ImageList1.GetBitmap(((L-1+(random(4)+1)) mod 5),E.Picture.bitmap);
        E.Name:='Target'
      end
    else
      begin
        ImageList1.GetBitmap(L-1,E.Picture.bitmap);
        E.Name:='Im'+inttostr(i)
      end;
  End
end;

end.

PM MAIL   Вверх
Zero
Дата 17.12.2005, 21:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2169
Регистрация: 23.10.2004
Где: Россия, г. Рязань

Репутация: 8
Всего: 24



Цитата(Elfin @ 17.12.2005, 20:40)
Проблема в том что иногда после выбора нужной картинки вылетает сообщение об ошибке. Не могу найти ее причину. Подскажите в чем она может заключаться?

При выборе какой картинки, и какая ошибка вылетает?
Лучше вставь всю папку с исходниками (без екзешника), а то не охота разбиратся во всём коде чтобы его откомпилить.(внизу есть кнопка Ответить, после нажатия на которую будет возможность вставлять файлы, Zip-архив)
PM MAIL ICQ   Вверх
Albinos_x
Дата 17.12.2005, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Evil Skynet
****


Профиль
Группа: Комодератор
Сообщений: 3288
Регистрация: 28.5.2004
Где: X-6120400 Y-1 4624650

Репутация: 26
Всего: 108



1. какое сообщение об ошибке?
2. в каком месте?


--------------------
"Кто владеет информацией, тот владеет миром"    
Уинстон Черчилль
PM MAIL ICQ   Вверх
Elfin
Дата 18.12.2005, 10:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 28.10.2004

Репутация: нет
Всего: нет



К сообщению прикрепил файл - архив с исходниками 22 кб.

После нажатия на бутон1 происходит очищение панели1 от всех контролов а затем заполнение ее новыми контролами, среди которых один отличается от остальных картинкой и именем Targetб у остальных же имя 'IM'+порядковый номер картинки. При нажати на эту картинку с именем 'Target' она должна удалиться, иногда все нормально получается, а иногда происходит ошибка Acces Violation и код ошибки.

Это сообщение отредактировал(а) Elfin - 18.12.2005, 10:29

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  _________.zip 27,25 Kb
PM MAIL   Вверх
YurikGL
Дата 18.12.2005, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 5.7.2005
Где: Уфа

Репутация: нет
Всего: 2



Может я что не понимаю, но

E.Name:='Target'
Зачем так????

Создай массив Image-в и все будет хорошо.... А в Tag-e храни свое (i)

Если уж очень нужно свою строку хранить, то создай наследника от TImige у которого есть нужное поле... А переименовывать объекты по ходу выполнения это как-то неправильно ИМХО....

А то в твоем случае реально существует только один объект Е и ты его много раз создаешь, меняешь имена, а ссылки на старые объекты теряешь...
--------------------
 
PM MAIL WWW ICQ   Вверх
Elfin
Дата 18.12.2005, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 28.10.2004

Репутация: нет
Всего: нет



Цитата
А в Tag-e храни свое (i)

Это как? что-то я не совсем понял.

OK попробовал массив имагов, тоже не робит.
Код

var
  Form1: TForm1; d: byte; E: array of TImage;

implementation

{$R *.dfm}

procedure Tform1.CtrlClk(sender: tobject);
begin
if (sender as Timage)=E[d-1] then
(SENDER AS TCONTROL).FREE;
//или E[d-1].free;
end;

procedure Tform1.freeimages;
var i: integer;
begin
  for i:=panel1.ControlCount-1 downto 0  do
  if (panel1.Controls[i] is timage) then
  panel1.Controls[i].FREE;
end;

procedure TForm1.Button1Click(Sender: TObject);
Var
  c,I,L: byte;
Begin
  freeimages;
  L:=random(5)+1;
  d:=random©+1;
  c:=strtoint(edit1.Text);
  setlength(e,c);
  for i:=0 to c-1 do
    begin
      E[i]:=Timage.Create(panel1);
      E[i].OnClick:=CtrlClk;
      E[i].Parent := panel1;
      E[i].cursor:=crHandPoint;
      E[i].Left := (I mod 10) * 64 + 10;
      E[i].Top := 10+64*(i div 10);
      E[i].Width:=64;
      E[i].Height:=64;
      if (I+1)=d then
        ImageList1.GetBitmap(((L-1+(random(4)+1)) mod 5),E[i].Picture.bitmap)
      else
        ImageList1.GetBitmap(L-1,E[i].Picture.bitmap);
      panel1.Refresh
    end;
end;

end.


Это сообщение отредактировал(а) Elfin - 18.12.2005, 13:29
PM MAIL   Вверх
Quadr0
Дата 18.12.2005, 13:44 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











...

Это сообщение отредактировал(а) Quadr0 - 15.7.2011, 02:51
  Вверх
Elfin
Дата 18.12.2005, 17:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 28.10.2004

Репутация: нет
Всего: нет



Зачем из мухи делать слона? к чему такие навороты, если в теории алгоритм должен быть проще.
Можно также по координатам вычислять в какую картинку я ткнул мышью, но стоит ли?
Единственноен чего я не понимаю - это откуда ошибка, если теоретически все верно.
PM MAIL   Вверх
YurikGL
Дата 18.12.2005, 18:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 5.7.2005
Где: Уфа

Репутация: нет
Всего: 2



Честно говоря, я так и не понял в чем прикол...
Если Image создается методом "кидания на форму" то вызов free из OnClick этого компонента работает нормально...
Вызов free из других объектов по отношению к динамически созданным Image тоже проходит нормально....
Из экспериментов выяснил, что ошибка возникает не всегда. Иногда это - abstract error иногда - AV....
Похоже на глюки самих делфей...
С другими компонентами, кстати, та же фигня...
А при использовании события OnExit (для TButton) все работает...
Добавлено @ 18:53
В принципе, прблема решилась так:


Код

type
  TForm1 = class(TForm)
    Button1: TButton;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);

  private
    procedure clickdel(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  mas: array [1..10] of TImage;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
begin
for i:=1 to 5 do begin
  mas[i]:=TImage.Create(Form1);
  mas[i].Parent:=self;
  mas[i].Left:=i*20;
  mas[i].Width:=15;
  mas[i].OnMouseUp:=clickdel;
  mas[i].Picture.LoadFromFile('c:\windows\Zapotec.bmp');
  mas[i].tag:=i;
end;
end;

procedure TForm1.ClickDel(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
a:integer;
Begin
with (sender as TImage) do a:=tag;

mas[a].Free;
mas[a]:=nil;

End;

end.


т.е. вместо OnClick использовать OnMouseUp

Это сообщение отредактировал(а) YurikGL - 18.12.2005, 18:50
--------------------
 
PM MAIL WWW ICQ   Вверх
Zero
Дата 18.12.2005, 18:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2169
Регистрация: 23.10.2004
Где: Россия, г. Рязань

Репутация: 8
Всего: 24



Цитата(Elfin @ 18.12.2005, 18:39)
Единственноен чего я не понимаю - это откуда ошибка, если теоретически все верно.

Очень просто, я раньше на тотже кручёк раза три подряд ловился, а г-н Посол, меня всё время исправлял... smile
Короче тут вся фишка в том, что при нажатии на картинку, она удаляет сама себя, что не разрешает ОС Winows, вот и выскакивает ошибка. smile
Короче я чуть-чуть подправил, можешь посмотреть в прикреплённом файле.

Присоединённый файл ( Кол-во скачиваний: 12 )
Присоединённый файл  ISH.zip 26,50 Kb
PM MAIL ICQ   Вверх
YurikGL
Дата 18.12.2005, 19:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 5.7.2005
Где: Уфа

Репутация: нет
Всего: 2



Цитата
Zero (Online)

Сами себе сообщение посылаете? Это, наверное, более правильное решение, чем мое...
--------------------
 
PM MAIL WWW ICQ   Вверх
p0s0l
Дата 18.12.2005, 22:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 58
Всего: 112



Цитата(Zero @ 18.12.2005, 18:58)
что не разрешает ОС Winows
не совсем... Событие OnClick вызывается из других процедур объекта, и при выходе из OnClick идет дальнейшая работа с этим объектом (например, вызов OnMouseUp), а объекта-то уже нет, уничтожили... Вот и получаются AV...


--------------------
С уважением, г-н Посол.
PM   Вверх
YurikGL
Дата 18.12.2005, 22:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 5.7.2005
Где: Уфа

Репутация: нет
Всего: 2



Цитата
не совсем... Событие OnClick вызывается из других процедур объекта, и при выходе из OnClick идет дальнейшая работа с этим объектом (например, вызов OnMouseUp), а объекта-то уже нет, уничтожили... Вот и получаются AV...

Хм.... а почему тогда иногда срабатывает без ошибок?
--------------------
 
PM MAIL WWW ICQ   Вверх
Elfin
Дата 19.12.2005, 04:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 28.10.2004

Репутация: нет
Всего: нет



Zero
YurikGL
p0s0l Cпасибо огромное за разъяснения, очень благодарен за помощь, все работает.

ZeroВсе работает, но этот код я не понимаю. Если не трудно, объясни как это работает.
PM MAIL   Вверх
Zero
Дата 19.12.2005, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2169
Регистрация: 23.10.2004
Где: Россия, г. Рязань

Репутация: 8
Всего: 24



Цитата(Elfin @ 19.12.2005, 05:00)
Если не трудно, объясни как это работает.

Короче вся фишка в том, что при выполнении этой строки:
Код

(SENDER AS TImage).FREE;
которая раньше была у тебя, то сразу происходило удаление объекта при нажатии на него, а я вставил строку:
Код

PostMessage (Handle, WM_DELIMG, WPARAM(Sender), 0);
которая вызывает другую процедуру после выполнения всех действий с данным объектом (типа такого)
Цитата(p0s0l @ 18.12.2005, 23:30)
при выходе из OnClick идет дальнейшая работа с этим объектом (например, вызов OnMouseUp),

А в вот этой процедуре:
Код

procedure TForm1.delimage;
begin
  TImage(msg.WParam).Free;
end;
происходит удаление объекта после выполнения всех действий, которые произходят после нажатия (onClick)
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0934 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.