Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Вниз

Процедура вызывает AV   Найти похожие ветки 

 
pavel_guzhanov ©   (2010-04-26 21:41) [40]


> у тебя ошибка в другом месте

Вот код 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))<2 then
       x:="0"+intToStr(j+1)
     else
       x:=intToStr(j+1);
     if length(intToStr(i+1))<2 then
       y:="0"+intToStr(i+1)
     else
       y:=intToStr(i+1);
     New.Name:="B"+ y+x;
     new.Stretch:=true;
     TImage(New).OnClick:=OnClickImage;
     case Random(5) of
       0:New.Picture.LoadFromFile("0.bmp");
       1:New.Picture.LoadFromFile("1.bmp");
       2:New.Picture.LoadFromFile("2.bmp");
       3:New.Picture.LoadFromFile("3.bmp");
       4:New.Picture.LoadFromFile("4.bmp");
       5:New.Picture.LoadFromFile("5.bmp");
     end;
     New.Canvas.Brush.Style:=bsDiagCross;
     pan[i+1,j+1]:=new;
     pan[i+1,j+1].Parent:=Panel1;
   end;
 end;
 except
   ShowMessage(pan[i,j].Name);
 end;

end;

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; // &#237;&#229; &#241;&#238;&#226;&#239;&#224;&#228;&#224;&#254;&#242;
         end;//if not
         j:=i;
       end;//for i
       if j=Bitmap.Height - 1 then  // &#241;&#238;&#226;&#239;&#224;&#228;&#224;&#254;&#242;
       begin
         a:=0;
// &#207;&#240;&#238;&#226;&#229;&#240;&#234;&#224; , &#229;&#241;&#242;&#252; &#235;&#232; &#226; &#241;&#242;&#240;&#232;&#237;&#227;&#235;&#232;&#241;&#242;&#229; &#243;&#230;&#229; &#242;&#224;&#234;&#224;&#255; &#231;&#224;&#239;&#232;&#241;&#252;
         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
// &#197;&#241;&#235;&#232; &#231;&#224;&#239;&#232;&#241;&#232; &#237;&#229;&#242;, &#242;&#238; &#228;&#238;&#225;&#224;&#226;&#235;&#255;&#229;&#236; &#237;&#238;&#226;&#243;&#254; &#231;&#224;&#239;&#232;&#241;&#252; &#226; &#241;&#242;&#240;&#232;&#237;&#227;&#235;&#232;&#241;&#242;
       if a=SL.Count-1 then  // &#229;&#241;&#235;&#232;  &#224; &#240;&#224;&#226;&#237;&#224; &#234;&#238;&#235;&#232;&#247;&#229;&#241;&#242;&#226;&#243; &#231;&#224;&#239;&#232;&#241;&#229;&#233; &#226; &#241;&#242;&#240;&#232;&#237;&#227;&#235;&#232;&#241;&#242;&#229;
                             //&#231;&#237;&#224;&#247;&#232;&#242; &#242;&#224;&#234;&#238;&#227;&#238; &#232;&#236;&#229;&#237;&#232; &#226; &#241;&#242;&#240;&#232;&#237;&#227;&#235;&#232;&#241;&#242;&#229; &#237;&#229;&#242;
         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));
       TImage(pan[y,x]).OnClick:=nil;
       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.Free;
 end;
end;

end.


Вот код Project1.dpr:

program Project1;

uses
 Forms,
 MainFormUnit in "MainFormUnit.pas" {MainForm};

{$R *.res}

begin
 Application.Initialize;
 Application.CreateForm(TMainForm, MainForm);
 Application.Run;
end.


Другого кода нет.


 
Игорь Шевченко ©   (2010-04-26 22:42) [41]

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


ты здесь с координатами не ошибаешься ? в смысле х с у не путаешь ?

вообще плохой код. Ты его причеши, потом выложи. А может в процессе причесывания сам найдешь путаницу


 
sniknik ©   (2010-04-26 23:13) [42]

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 исчезнет. нельзя так удалять, из обработчика свой объект.


 
sniknik ©   (2010-04-26 23:28) [43]

> замени это ... на
или на
if Sender <> pan[y,x] then begin
 //TImage(pan[y,x]).OnClick:=nil;
 pan[y,x].Free;
 pan[y,x]:= nil;
end;

чтобы были удаления, но не было AV (сразу очевидно какое к нему приводит)


 
Игорь Шевченко ©   (2010-04-27 00:31) [44]


> 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.


 
DVM ©   (2010-04-27 00:36) [45]


> Игорь Шевченко ©   (27.04.10 00:31) [44]
>

Стоит положить кнопку не на форму, а на панель, как этот метод перестанет работать.


 
Игорь Шевченко ©   (2010-04-27 00:48) [46]

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.


 
sniknik ©   (2010-04-27 00:50) [47]

Игорь Шевченко ©   (27.04.10 00:31) [44]
AV

D7, XP

> Стоит положить кнопку не на форму, а на панель, как этот метод перестанет работать.
в таком виде тоже не работает.


 
sniknik ©   (2010-04-27 00:54) [48]

может в следующих версиях дельфи и сделали удаление через событие (реальное в основном цикле выборки, по типу Release у форм), но в D7 это не так.
версию нужно уточнять.


 
Игорь Шевченко ©   (2010-04-27 01:02) [49]

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 01:20) [50]

> А что там уточнять ?
версию дельфи нужно уточнять, когда говоришь "а у меня так работает".

> Где что не так ?
Turbo Delphi 2006, Windows XP SP3
> Процедура вызывает AV [D7, XP]

проверь свой пример на D7.


 
Игорь Шевченко ©   (2010-04-27 01:23) [51]

sniknik ©   (27.04.10 01:20) [50]


> проверь свой пример на D7.


Подари - проверю.

Я привел код деструкторов, сравни со своим, если есть отличия, давай посмотрим.
Кроме всего прочего, ты в D7 можешь узнать (и выложить в форум) именно то место, где происходит AV (и почему).


 
sniknik ©   (2010-04-27 01:32) [52]

> Я привел код деструкторов
а я высказывал подозрения в различиях во Free

> может в следующих версиях дельфи и сделали удаление через событие (реальное в основном цикле выборки, по типу Release у форм), но в D7 это не так.
вот ответь сам на заданный автору вопрос
> посмотри на TForm.Release; в генофонде. как думаешь зачем так сделали?

еще как вариант цикл выборки сообщений, возможно, каким то боком.

так зачем сравнивать деструкторы?

> где происходит AV (и почему).
вот чего я точно не хочу делать, так это выяснять почему только для того чтобы что то доказать тебе, то что это не работает в D7. хочешь проверь, хочешь прими как данность, хочешь не верь. мне пофигу.


 
Германн ©   (2010-04-27 02:02) [53]


> Игорь Шевченко ©   (27.04.10 01:23) [51]
>
> sniknik ©   (27.04.10 01:20) [50]
>
>
> > проверь свой пример на D7.
>
>
> Подари - проверю.

Так зачем тогда на форме ввода вопроса на ДМ создана возможность указания версии Дельфи?
Игорь, это перебор, имхо.


 
Игорь Шевченко ©   (2010-04-27 10:36) [54]

sniknik ©   (27.04.10 01:32) [52]


> а я высказывал подозрения


Ты следователь ? Или у тебя Delphi тоже полевого, облегченного образца, без исходников ?

Раз у тебя происходит AV в моем примере, ну так покажи, в каком оно месте происходит. Проще ж некуда.


 
Игорь Шевченко ©   (2010-04-27 10:58) [55]

На Delphi 2010 под Win7 64 мой код тоже не вызывает AV. Других версий Delphi у меня нету. Если у кого будет желание, протрассируйте код на младших версиях и выложите результат.

Проект прост

program KillComponentfromEventHandler;

uses
 Forms,
 main in "main.pas" {Form1};

{$R *.res}

begin
 Application.Initialize;
 Application.CreateForm(TForm1, Form1);
 Application.Run;
end.


object Form1: TForm1
 Left = 0
 Top = 0
 Caption = "Form1"
 ClientHeight = 293
 ClientWidth = 426
 Color = clBtnFace
 Font.Charset = DEFAULT_CHARSET
 Font.Color = clWindowText
 Font.Height = -11
 Font.Name = "Tahoma"
 Font.Style = []
 OldCreateOrder = False
 OnCreate = FormCreate
 PixelsPerInch = 96
 TextHeight = 13
 object Panel1: TPanel
   Left = 60
   Top = 40
   Width = 301
   Height = 185
   Caption = "Panel1"
   TabOrder = 0
 end
end


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.


 
{RASkov} ©   (2010-04-27 11:18) [56]

> [55] Игорь Шевченко ©   (27.04.10 10:58)

[D7] [WinXP Pro]
Результат:
---------------------------
Debugger Exception Notification
---------------------------
Project KillComponentfromEventHandler.exe raised exception class EAccessViolation with message "Access violation at address 004032B8 in module "KillComponentfromEventHandler.exe". Read of address 0014D000". Process stopped. Use Step or Run to continue.
---------------------------
OK   Help  
---------------------------


 
sniknik ©   (2010-04-27 12:10) [57]

> Ты следователь ? Или у тебя Delphi тоже полевого, облегченного образца, без исходников ?
я человек обладающий здравым смыслом, и логикой (возможно немного извращенной...)

смотреть в исходники в "указанную тобой сторону" не вижу смысла, говорил то я про другое, подозрения(/догадки в изменении работы) высказывал тоже про другое. + ведешь себя так будто тебе должны доказывать, причем "доказательства" предлагаешь искать "там где светлее", т.е. там где ты их решил искать, невзирая на мои слова.
имхо, дело безнадежное.

> Раз у тебя происходит AV в моем примере, ну так покажи, в каком оно месте происходит. Проще ж некуда.
раз у тебя не происходит AV от Free в своих обработчиках, покажи его реализацию, ну и реализацию Release у форм, т.е. то где возможны отличия. проще ж некуда.


 
Игорь Шевченко ©   (2010-04-27 12:33) [58]

sniknik ©   (27.04.10 12:10) [57]


> раз у тебя не происходит AV от Free в своих обработчиках,
>  покажи его реализацию


в посте [49] я показал. Чего-то недостаточно ?

{RASkov} ©   (27.04.10 11:18) [56]

Ну и ? Место-то где ? Или ты полагаешь, что во всех версиях Delphi модули располгаются по одинаковым адресам ? Я тебя разочарую - это не так.


 
12 ©   (2010-04-27 14:21) [59]


> Игорь Шевченко ©   (27.04.10 10:58) [55]

D7 XP
AV
ставлю галку CPU, нажимаю ОК, yажимаю F7

TWinControl.MainWndProc
call FreeDeviceContexts


 
Leonid Troyanovsky ©   (2010-04-27 18:53) [60]


> Игорь Шевченко ©   (27.04.10 00:48) [46]

---------------------------
Debugger Exception Notification
---------------------------
Project Project2.exe raised exception class EAccessViolation with message "Access violation at address 0040367D in module "Project2.exe". Read of address 00000018". Process stopped. Use Step or Run to continue.
---------------------------
OK   Help  
---------------------------
XP SP3 & D6
Лень искать в чьем оно модуле, бо подход крив по определению.
И обсуждалось подобное не раз, чудес не было, только "свезло/не свезло".

В любом случае, в любой, IMHO, версии достаточно добавить после Sender.Free;
ShowMessage(""); // это ж никак не обращение к полям фантома?
и AV неизбежен.

Ну не должен нормальный код содержать подобные кунштюки.
Ведь знаешь ;)

--
Regards, LVT.


 
sniknik ©   (2010-04-27 19:31) [61]

> в посте [49] я показал. Чего-то недостаточно ?
сам ищи там где светлее, а я, если буду, только там где "потерял"...  - реализация Free/ Release у форм. хоть весь оставшийся генофонд сюда скопипасть.


 
Leonid Troyanovsky ©   (2010-04-27 19:39) [62]


> sniknik ©   (27.04.10 19:31) [61]

> "потерял"...  - реализация Free/ Release у форм. хоть весь

По-взрослому, Releasе - тоже костыль.
Но, подзащитный лишь пару раз с ним согрешил :)

--
Regards, LVT.


 
Игорь Шевченко ©   (2010-04-27 20:24) [63]

Leonid Troyanovsky ©   (27.04.10 18:53) [60]


> В любом случае, в любой, IMHO, версии достаточно добавить
> после Sender.Free;
> ShowMessage(""); // это ж никак не обращение к полям фантома?
>
> и AV неизбежен.


Подвело тебя твое ИМНО

procedure TForm1.ButtonClick(Sender: TObject);
begin
 Sender.Free;
 ShowMessage("");
end;


работает. Turbo Delphi 2006


> Ну не должен нормальный код содержать подобные кунштюки.
>
> Ведь знаешь ;)


Марксизм не догма, а руководство к действию.
Ведь знаешь ? :)

Я вот в упор не вижу причины, по которой в обработчике события надо обращатся после выполнения собственно обработчика к полям/методам инициатора события.

Сам метод обработчика живет в неудаляемом классе, так что аналогия с Release здесь никаким боком не подходит. И кстати, Release, как ни странно, тоже вызывает Free в обработчике события. Правда, события от сообщения.


 
Игорь Шевченко ©   (2010-04-27 20:30) [64]

sniknik ©   (27.04.10 19:31) [61]


> сам ищи там где светлее, а я, если буду, только там где
> "потерял"...  


А у меня нету AV, мне нечего искать. Понял ?


 
Leonid Troyanovsky ©   (2010-04-27 21:34) [65]


> Игорь Шевченко ©   (27.04.10 20:24) [63]

> работает. Turbo Delphi 2006

Свезло.

--
Regards, LVT.


 
Игорь Шевченко ©   (2010-04-27 21:41) [66]

Leonid Troyanovsky ©   (27.04.10 21:34) [65]

Есть у меня стойкое ощущение, что часть догм перестала ими быть.

Нес па ?

Могу конечно и ошибаться, но факт - вещь упрямая.


 
Leonid Troyanovsky ©   (2010-04-27 21:53) [67]


> Игорь Шевченко ©   (27.04.10 20:24) [63]

С необходимыми и достаточными условиями?
And все версии?

А накуа ж это сомнительное удовольствие?

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2010-04-27 22:04) [68]


> Игорь Шевченко ©   (27.04.10 21:41) [66]

> Могу конечно и ошибаться, но факт - вещь упрямая.

Завтра испытаю на Turbo Delphi 2006, доложусь.
Хотя, это и не снимает ответственности с других.

Будет/не будет - код, один хрен, коряв.
И что ж за нужда в оном? :)

--
Regards, LVT.


 
Игорь Шевченко ©   (2010-04-27 22:25) [69]

Leonid Troyanovsky ©   (27.04.10 22:04) [68]


> Будет/не будет - код, один хрен, коряв.


нужда в корявом коде может быть одна - проверить факт, а не верить на слово.

Я тебе даже полностью версию выпишу, чтобы можно было сравнить - я на свою установку накатываю все апдейты.

"Borland® Delphi® for Microsoft® Windows™ Version 10.0.2558.35231 Update 2 Copyright © 2005 Borland® Software Corporation. All Rights Reserved."


> С необходимыми и достаточными условиями?
> And все версии?


На двух версиях, которыми располагаю, проверил. Результат опубликовал :)


 
Leonid Troyanovsky ©   (2010-04-27 22:38) [70]


> Игорь Шевченко ©   (27.04.10 22:25) [69]

> "Borland® Delphi® for Microsoft® Windows™ Version 10.0.2558.
> 35231 Update 2 Copyright © 2005 Borland® Software Corporation.

Здесь похвастать не чем, бо, не следил, не участвовал,
не ..  привлекался :)

> На двух версиях, которыми располагаю, проверил. Результат
> опубликовал :)

Результат любопытный и заслуживает, IMHO, текущего обсуждения.
Будет над чем поразмышлять :)

--
Regards, LVT.


 
sniknik ©   (2010-04-27 23:15) [71]

> Будет над чем поразмышлять :)
procedure       GetDynaMethod;
{       function        GetDynaMethod(vmt: TClass; selector: Smallint) : Pointer;       }
asm
       { ->    EAX     vmt of class            }
       {       SI      dynamic method index    }
       { <-    ESI pointer to routine  }
       {       ZF = 0 if found         }
       {       trashes: EAX, ECX               }

       PUSH    EDI
       XCHG    EAX,ESI
       JMP     @@haveVMT
@@outerLoop:
       MOV     ESI,[ESI]
@@haveVMT:
       MOV     EDI,[ESI].vmtDynamicTable
       TEST    EDI,EDI
       JE      @@parent
       MOVZX   ECX,word ptr [EDI]
       PUSH    ECX
       ADD     EDI,2
       REPNE   SCASW //ошибка здесь. на событии "обратного отщелкивания"  мыши после клика
       JE      @@found
       POP     ECX
@@parent:
       MOV     ESI,[ESI].vmtParent
       TEST    ESI,ESI
       JNE     @@outerLoop
       JMP     @@exit

@@found:
       POP     EAX
       ADD     EAX,EAX
       SUB     EAX,ECX         { this will always clear the Z-flag ! }
       MOV     ESI,[EDI+EAX*2-4]

@@exit:
       POP     EDI
end;


 
sniknik ©   (2010-04-27 23:18) [72]

в смысле ошибка то конечно не там, она раньше, в попутанных адресах от несуществующего объекта, но валится именно на этой команде (вылезает за "свою" память как понимаю).


 
Игорь Шевченко ©   (2010-04-27 23:45) [73]

Помогло воспроизвести ошибку только включение в проект FastMM с указанием Full Debug mode, при котором при освобождении объекта заведомо портится занимаемая им память.

Так что код действительно "как повезет" и не рекомендуется к использованию.


 
sniknik ©   (2010-04-27 23:52) [74]

догма...


 
Игорь Шевченко ©   (2010-04-28 00:00) [75]

sniknik ©   (27.04.10 23:52) [74]

Для обработчика OnClick - да, догма, потому что он срабатывает на нажатие мыши. За что тебе спасибо :)

Для потенциально любого обрабтчика - отнюдь не догма.


 
Игорь Шевченко ©   (2010-04-28 00:09) [76]

Соответственно, при


> procedure TForm1.ButtonClick(Sender: TObject);
> begin
>   //Sender.Free;
> end;
>
> procedure TForm1.ButtonMouseUpFree(Sender: TObject; Button:
>  TMouseButton;
>   Shift: TShiftState; X, Y: Integer);
> 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;
>   FButton.OnMouseUp := ButtonMouseUpFree;
> end;


Даже использование FastMM не вызывает ошибки


 
sniknik ©   (2010-04-28 00:22) [77]

> Для потенциально любого обрабтчика - отнюдь не догма.
для форм, с их обычным обилием, и в них же выполняющимися действиями, обработчиками Release вместо Free - узаконенная в доке догма.

а вообще, для потенциального большинства, т.к. мало найдется событий ничего не наследующих (и не выполняющих потому неизвестно что, не в данный момент так в перспективе), и вообще независимых, без последствий, типа отработал и все, и никуда не лезет, никого не вызывает, и ни к чему не обращается (не в данный момент так в перспективе).


 
Игорь Шевченко ©   (2010-04-28 00:48) [78]

sniknik ©   (28.04.10 00:22) [77]


> для форм, с их обычным обилием, и в них же выполняющимися
> действиями, обработчиками Release вместо Free - узаконенная
> в доке догма.


Цитата из справки:

"Use Release to destroy the form and free its associated memory.
Any event handlers for the form or its children should use Release instead of Free.Failing to do so can cause a memory access error"

для уничтожения формы внутри ее самой и только для этого.

Какое отношение Release имеет к обработчикам событий компонент, я честно не понимаю.


 
Игорь Шевченко ©   (2010-04-28 00:49) [79]

sniknik ©   (28.04.10 00:22) [77]


> типа отработал и все, и никуда не лезет, никого не вызывает,
>  и ни к чему не обращается (не в данный момент так в перспективе).
>


На перспективу лчуше вообще ничего не писать. Надежнее будет.


 
sniknik ©   (2010-04-28 00:57) [80]

> Какое отношение Release имеет к обработчикам событий компонент, я честно не понимаю.
только одно отношение, это аналог, когда "убивают" себя из своего же обработчика. с формой такая ситуация происходит чаще, вот и позаботились.
и также это путь к обходу сабжа, ничего не мешает сделать тоже самое для имеджа например.



Страницы: 1 2 3 вся ветка

Форум: "Начинающим";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.68 MB
Время: 0.062 c
2-1268466114
Starraider
2010-03-13 10:41
2010.08.27
Программный сброс статистики по дате


3-1239773025
Spot
2009-04-15 09:23
2010.08.27
Interbase через BDE


4-1235053242
Franzy
2009-02-19 17:20
2010.08.27
Нужен пример CreateFileMapping()


15-1275913487
oleg_teacher
2010-06-07 16:24
2010.08.27
Mac os + delphi


2-1268313251
Rail
2010-03-11 16:14
2010.08.27
Поле Edit





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский