![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Процедура вызывает AV [D7, XP]
pavel_guzhanov © (2010-04-18 19:36:00)Вот такой вот код процедуры:
procedure TMainForm.OnClickImage(sender:TObject);
var Name:String[10];
i, j, k, l,m,c, a, x, y, xa, ya:SmallInt;
BitMap, BitMapR : Graphics.TBitMap;
P, PR : PByteArray;
Image1, Image2: TImage;
SL:TStringList;
S:String;
begin
SL:=TStringList.Create;
Name:=TControl(Sender as TImage).Name;
y:=StrToInt(copy(name, 2, 2));
x:=StrToInt(copy(name, 4, 2));
m:=0;
c:=0;
try
if Pan[y, x]<>nil then
SL.Add(String(Pan[y, x].Name))
else
SL.Add('');
while m<=c do
begin
y:=StrToInt(copy(name, 2, 2));
x:=StrToInt(copy(name, 4, 2));
for k:=1 to 4 do
begin
case k of
1:begin
xa:=x+1;
ya:=y;
end;
2:begin
xa:=x;
ya:=y+1;
end;
3:begin
xa:=x-1;
ya:=y;
end;
4:begin
xa:=x;
ya:=y-1;
end;
end; //case
if (xa<1) or (ya<1) or (xa>18) or (ya>12) or (Pan[yA,xA]=nil) then
continue;
Image1:=Pan[y, x];
Image2:=Pan[ya, xa];
BitMap:=Image1.Picture.Bitmap;
BitMapR:=Image2.Picture.Bitmap;
for i:=0 to Bitmap.Height - 1 do
begin
P := Bitmap.ScanLine[i];
PR:=BitMapR.ScanLine[i];
if not CompareMem(p, pr, BitMap.Width) then
begin
j:=i;
Break;
end;//if not
j:=i;
end;//for i
if j=Bitmap.Height - 1 then
begin
a:=0;
for l:=0 to SL.Count-1 do
begin
if String(Pan[ya, xa].Name)=SL.Strings[l] then
begin
a:=l;
break;
end; //if string
a:=l;
end;// for l
if a=SL.Count-1 then
SL.Add(String(Pan[ya, xa].Name));
c:=SL.Count;
end; //if j
if (SL.Count>1) and (m<c) then
begin
name:=SL.Strings[m];
end;// if sl.count and
S:='';
for l:=0 to SL.Count-1 do
begin
S:=S+SL.Strings[l];
end; //for l
end; //for k
inc(m);
end; //while
for l:=0 to SL.Count-1 do
begin
if sl.Count>1 then
begin
y:=StrToInt(copy(SL.Strings[l], 2, 2));
x:=StrToInt(copy(SL.Strings[l], 4, 2));
pan[y,x].Free;
pan[y,x]:=nil;
end;// if sl.count
end; //for l
for i := 0 to 11 do
begin
for j:=0 to 17 do
begin
if pan[i+1, j+1]<>nil then
pan[i+1,j+1].Parent:=Panel1;
end; //for j
end; //for i
finally
SL.Destroy;
end;
end;
Все отрабатывает правильно. Но... При пошаговой отладке, после секции finally по клавише F7 попадаю на end; который закрывает процедуру. А после него вылетает AV. Подскажите пожалуйста, откуда AV и как с ним бороться?
Игорь Шевченко (2010-04-27 10:36:00) [41]sniknik © (27.04.10 01:32) [52]
> а я высказывал подозрения
Ты следователь ? Или у тебя Delphi тоже полевого, облегченного образца, без исходников ?
Раз у тебя происходит AV в моем примере, ну так покажи, в каком оно месте происходит. Проще ж некуда.
Германн (2010-04-27 02:02:00) [42]
> Игорь Шевченко © (27.04.10 01:23) [51]
>
> sniknik © (27.04.10 01:20) [50]
>
>
> > проверь свой пример на D7.
>
>
> Подари - проверю.
Так зачем тогда на форме ввода вопроса на ДМ создана возможность указания версии Дельфи?
Игорь, это перебор, имхо.
sniknik (2010-04-27 01:32:00) [43]> Я привел код деструкторов
а я высказывал подозрения в различиях во Free
> может в следующих версиях дельфи и сделали удаление через событие (реальное в основном цикле выборки, по типу Release у форм), но в D7 это не так.
вот ответь сам на заданный автору вопрос
> посмотри на TForm.Release; в генофонде. как думаешь зачем так сделали?
еще как вариант цикл выборки сообщений, возможно, каким то боком.
так зачем сравнивать деструкторы?
> где происходит AV ( и почему).
вот чего я точно не хочу делать, так это выяснять почему только для того чтобы что то доказать тебе, то что это не работает в D7. хочешь проверь, хочешь прими как данность, хочешь не верь. мне пофигу.
Игорь Шевченко (2010-04-27 01:23:00) [44]sniknik © (27.04.10 01:20) [50]
> проверь свой пример на D7.
Подари - проверю.
Я привел код деструкторов, сравни со своим, если есть отличия, давай посмотрим.
Кроме всего прочего, ты в D7 можешь узнать (и выложить в форум) именно то место, где происходит AV (и почему).
sniknik (2010-04-27 01:20:00) [45]> А что там уточнять ?
версию дельфи нужно уточнять, когда говоришь "а у меня так работает".
> Где что не так ?
Turbo Delphi 2006, Windows XP SP3
> Процедура вызывает AV [ D7, XP]
проверь свой пример на D7.
Игорь Шевченко (2010-04-27 01:02:00) [46]sniknik © (27.04.10 00:50) [47]
Turbo Delphi 2006, Windows XP SP3
А что там уточнять ?
procedure TForm1.ButtonClick(Sender: TObject);
mov eax,edx
call TObject.Free
ret
end;
destructor TWinControl.Destroy;
var
I: Integer;
Instance: TControl;
begin
Destroying;
if FDockSite then
begin
FDockSite := False;
RegisterDockSite(Self, False);
end;
FDockManager := nil;
FDockClients.Free;
if Parent <> nil then RemoveFocus(True);
if FHandle <> 0 then DestroyWindowHandle;
I := ControlCount;
while I <> 0 do
begin
Instance := Controls[I - 1];
Remove(Instance);
Instance.Destroy;
I := ControlCount;
end;
FBrush.Free;
if FObjectInstance <> nil then Classes.FreeObjectInstance(FObjectInstance);
FPadding.Free;
inherited Destroy;
end;
destructor TControl.Destroy;
begin
Application.ControlDestroyed(Self);
if (FHostDockSite <> nil) and not (csDestroying in FHostDockSite.ComponentState) then
begin
FHostDockSite.RemoveFreeNotification(Self);
FHostDockSite.Perform(CM_UNDOCKCLIENT, 0, Integer(Self));
SetParent(nil);
Dock(NullDockSite, BoundsRect);
FHostDockSite := nil;
end else
SetParent(nil);
FActionLink.Free;
FActionLink := nil;
FConstraints.Free;
FFont.Free;
StrDispose(FText);
FMargins.Free;
inherited Destroy;
end;
destructor TComponent.Destroy;
begin
Destroying;
if FFreeNotifies <> nil then
begin
while Assigned(FFreeNotifies) and (FFreeNotifies.Count > 0) do
TComponent(FFreeNotifies[FFreeNotifies.Count - 1]).Notification(Self, opRemove);
FreeAndNil(FFreeNotifies);
end;
DestroyComponents;
if FOwner <> nil then FOwner.RemoveComponent(Self);
inherited Destroy;
end;
Где что не так ?
sniknik (2010-04-27 00:54:00) [47]может в следующих версиях дельфи и сделали удаление через событие (реальное в основном цикле выборки, по типу Release у форм), но в D7 это не так.
версию нужно уточнять.
sniknik (2010-04-27 00:50:00) [48]Игорь Шевченко © (27.04.10 00:31) [44]
AV
D7, XP
> Стоит положить кнопку не на форму, а на панель, как этот метод перестанет работать.
в таком виде тоже не работает.
Игорь Шевченко (2010-04-27 00:48:00) [49]DVM © (27.04.10 00:36) [45]
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Panel1: TPanel;
procedure FormCreate(Sender: TObject);
private
FButton: TButton;
procedure ButtonClick(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ButtonClick(Sender: TObject);
begin
Sender.Free;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FButton := TButton.Create(Panel1);
FButton.Parent := Panel1;
FButton.Top := 20;
FButton.Left := 20;
FButton.Caption := 'Click me';
FButton.OnClick := ButtonClick;
end;
end.
DVM (2010-04-27 00:36:00) [50]
> Игорь Шевченко © (27.04.10 00:31) [44]
>
Стоит положить кнопку не на форму, а на панель, как этот метод перестанет работать.
Игорь Шевченко (2010-04-27 00:31:00) [51]
> AV исчезнет. нельзя так удалять, из обработчика свой объект.
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
FButton: TButton;
procedure ButtonClick(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ButtonClick(Sender: TObject);
begin
Sender.Free;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FButton := TButton.Create(Self);
FButton.Parent := Self;
FButton.Top := 20;
FButton.Left := 20;
FButton.Caption := 'Click me';
FButton.OnClick := ButtonClick;
end;
end.
sniknik (2010-04-26 23:28:00) [52]> замени это ... на
или на
if Sender <> pan[y,x] then begin
//TImage(pan[y,x]).OnClick:=nil;
pan[y,x].Free;
pan[y,x]:= nil;
end;
чтобы были удаления, но не было AV (сразу очевидно какое к нему приводит)
sniknik (2010-04-26 23:13:00) [53]pavel_guzhanov © (26.04.10 21:41) [40]
>> у тебя ошибка в другом месте
не верь, главная в том про что говорил.
вот, для пробы, замени это
TImage(pan[y,x]).OnClick:=nil;
pan[y,x].Free;
pan[y,x]:=nil;
на
pan[y,x].Visible:= false;
AV исчезнет. нельзя так удалять, из обработчика свой объект.
Игорь Шевченко (2010-04-26 22:42:00) [54]new:=TImage.Create(Panel1);
//Вот здесь надо Parent присвоить
New.Height:=25;
New.Width:=25;
New.Top:=i*25;
New.Left:=j*25;
а не здесь
pan[i+1,j+1].Parent:=Panel1;
> for i := 0 to 11 do
> begin
> for j:=0 to 17 do
> begin
> if pan[i+1, j+1]<>nil then
> pan[i+1,j+1].Parent:=Panel1;
> end; //for j
> end; //for i
А это нафиг ?
> if sl.Count>1 then
> begin
> y:=StrToInt(copy(SL.Strings[l], 2, 2));
> x:=StrToInt(copy(SL.Strings[l], 4, 2));
> TImage(pan[y,x]).OnClick:=nil;
> pan[y,x].Free;
> pan[y,x]:=nil;
> end;// if sl.count
ты здесь с координатами не ошибаешься ? в смысле х с у не путаешь ?
вообще плохой код. Ты его причеши, потом выложи. А может в процессе причесывания сам найдешь путаницу
pavel_guzhanov (2010-04-26 21:41:00) [55]
> у тебя ошибка в другом месте
Вот код MainFormUnit.pas:
unit MainFormUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Math;
type
TMainForm = class(TForm)
Panel1: TPanel;
Button1: TButton;
procedure OnClickImage(sender:TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
Pan:array [1..12, 1..18] of TImage;
end;
var
MainForm: TMainForm;
implementation
{$R *.dfm}
procedure TMainForm.Button1Click(Sender: TObject);
var New:TImage;
i, j: Integer;
x,y:String[2];
begin
for i := 0 to 11 do
begin
for j:=0 to 17 do
begin
pan[i+1,j+1].Free;
pan[i+1,j+1]:=nil;
end; //for j
end; //for i
try
Randomize;
for I := 0 to 11 do
begin
for j:=0 to 17 do
begin
new:=TImage.Create(Panel1);
New.Height:=25;
New.Width:=25;
New.Top:=i*25;
New.Left:=j*25;
if length(intToStr(j+1))
Leonid Troyanovsky (2010-04-26 21:37:00) [56]
> Игорь Шевченко © (26.04.10 21:30) [38]
> А зря.
Каждый волен заблуждаться в меру своих заблуждений.
У нас свободная страна ;)
--
Regards, LVT.
Игорь Шевченко (2010-04-26 21:30:00) [57]Паша, у тебя ошибка в другом месте. Которое ты не привел. А зря.
Leonid Troyanovsky (2010-04-26 21:26:00) [58]
> sniknik © (26.04.10 20:42) [35]
> посмотри на TForm.Release; в генофонде. как думаешь зачем
> так сделали?
[Антидидактическое] От отчаяния? :)
--
Regards, LVT.
sniknik (2010-04-26 20:46:00) [59]> чтобы за компонентом не осталось никаких процедур?
причем здесь "не осталось"? дело не в том чтобы не осталось, а в том чтобы не выполнялся код у "призрака", а код никуда не денется если ты его объект из него же и "грохаешь".
sniknik (2010-04-26 20:42:00) [60]посмотри на TForm.Release; в генофонде. как думаешь зачем так сделали?