if assigned(listbox1) then
beign
listbox1.free;
listbox1:=nil;
end;

解决方案 »

  1.   

    ListBox已经被Free了,再执行一次,当然要出错。
      

  2.   

    我不是动态创建吗? Free掉,再重新Create,怎么就错了?
    我一直不知道怎样用assigned,是不是虽然Free了,但这个ListBox指针还存在,一定要使它为空才能再创?
      

  3.   

    用这个方法
    FreeAndNil(listbox1);
    改写一下:
    procedure TForm5.ListBox1Click(Sender: TObject);
    begin
      if not assigned(listbox1) then exit;
      Edit1.Text := ListBox1.Items.Strings[ListBox1.ItemIndex];
      FreeAndNil(listbox1);
      IsExist := False;
    end;
      

  4.   

    To chechy(chechy):
        还是不行,问题仍然存在.
      

  5.   

    Edit1Change也应该在一开始检测listbox1的有效性。加入:
      if not assigned(listbox1) then exit;
      

  6.   

    我觉得,将listbox.visible设为false和true的切换,比释放更好,更有效率。
      

  7.   

    我倒觉得用hide属性也可以,只是我想试一下动态创建与释放,可是总不能如愿.
      

  8.   

    我调了半天了,把那条地free语句不要,一切正常,一定是释放后再重建时出错,好,我再仔细看看,回头再给你加分.
      

  9.   

    应这样:
    listbox1.Parent := nil;
    listbox1.Free;
    应首先断开它与它父对象的关系!
      

  10.   

    断不断开无所谓,在Free的时候,Delphi会自动断开的。
      

  11.   

    请务必帮忙再分析一下,弹出的错误对话框如下:
    Project KelySales.exe raised exception class EAccessViolation with message 'Access violation at address 0040394C in module 'KelySales.exe'.Read of address BAADF00D'.Process stopped.Use Step or Run to continue.
    我跟踪了一下,并不是Click事件没有执行,而是第二次执行Click事件后(是执行完所有语句,包括最后的End后)才发生如下的异常.assigned对ListBox1的指针判断都是正确的,不知到底是哪引起的.
      

  12.   

    这种错误一般都是访问了非法内存造成的。光光这些,我无法判断?能否确认,listbox1在释放后,是否是nil?
      

  13.   

    你的问题必须在于
    必须先将它的parent:=nil才行
    配合上freeandnil();
      

  14.   

    To Focus(老鱼):Delphi的控件在释放时,会自动断开与Parent的关系。下面是TControl的Destroy的代码:(注意SetParent(nil)就是断开与Parent的联系)
    destructor TControl.Destroy;
    begin
      Application.ControlDestroyed(Self);
      if (FHostDockSite <> nil) and not (csDestroying in FHostDockSite.ComponentState) then
      begin
        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);
      inherited Destroy;
    end;
      

  15.   

    procedure TForm5.ListBox1Click(Sender: TObject);
    begin
      ListBox1.OnClick := nil; // !!!!! 试一试这个
      Edit1.Text := ListBox1.Items.Strings[ListBox1.ItemIndex];
      ListBox1.Free; 
      IsExist := False;
    end;
      

  16.   

    我也知道是非法访问内存引起的,可是不知道怎么就非法访问内存了.
    可以确定释放后ListBox1为nil,全部代码为:
    unit ImportList;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Menus, ToolWin, ComCtrls, ImgList, ExtCtrls, Grids, ValEdit,
      StdCtrls, DB, ADODB;type
      TForm5 = class(TForm)
        MainMenu1: TMainMenu;
        A1: TMenuItem;
        N1: TMenuItem;
        H1: TMenuItem;
        CoolBar1: TCoolBar;
        ToolBar1: TToolBar;
        ToolButton1: TToolButton;
        ToolButton2: TToolButton;
        ToolBar2: TToolBar;
        ToolButton3: TToolButton;
        ToolButton4: TToolButton;
        ImageList1: TImageList;
        N2: TMenuItem;
        E1: TMenuItem;
        ToolBar3: TToolBar;
        DateTimePicker1: TDateTimePicker;
        ADOConnection1: TADOConnection;
        ImageList2: TImageList;
        StatusBar1: TStatusBar;
        PageControl1: TPageControl;
        TabSheet1: TTabSheet;
        TreeView1: TTreeView;
        Splitter1: TSplitter;
        GroupBox1: TGroupBox;
        StaticText1: TStaticText;
        StaticText2: TStaticText;
        StaticText3: TStaticText;
        StaticText4: TStaticText;
        ADOQuery1: TADOQuery;
        Edit1: TEdit;
        procedure E1Click(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure FormCreate(Sender: TObject);
        procedure Edit1Change(Sender: TObject);
        procedure ListBox1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form5: TForm5;
      ListBox1: TListBox;
      IsExist: Boolean;
      
    implementation{$R *.dfm}procedure TForm5.E1Click(Sender: TObject);
    begin
      Close;
    end;procedure TForm5.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      Action := caFree;
    end;procedure TForm5.FormCreate(Sender: TObject);
    var
      node: TTreeNode;
    begin
      IsExist := False;
      DateTimePicker1.Date := Date;
      node := TreeView1.Items.Add(TreeView1.Selected, '进货单信息');    
    end;procedure TForm5.Edit1Change(Sender: TObject);
    begin
      ADOQuery1.Close;
      ADOQuery1.SQL.Clear;
      ADOQuery1.SQL.Add('Select distinct 器材名称 from 器材库 where 器材名称 like ''%' + Edit1.Text + '%''');
      ADOQuery1.Open;  if not assigned(ListBox1) then       //not IsExist
      begin
        ListBox1 := TListBox.Create(nil);
        ListBox1.Parent := GroupBox1;
        ListBox1.SetBounds(Edit1.Left, Edit1.Top+Edit1.Height+1, Edit1.Width, 13*ADOQuery1.RecordCount+13);
        ListBox1.OnClick := ListBox1Click;
        //IsExist := True;
      end
      else
      begin
        ListBox1.Clear;
        ListBox1.Height := 13*ADOQuery1.RecordCount+13;
      end;  while not ADOQuery1.Eof do
      begin
        ListBox1.Items.Add(ADOQuery1.FieldValues['器材名称']);
        ADOQuery1.Next;
      end;
      if ListBox1.Count>0 then
        ListBox1.Selected[0] := True;  
    end;procedure TForm5.ListBox1Click(Sender: TObject);
    begin
        Edit1.Text := ListBox1.Items.Strings[ListBox1.ItemIndex];
        //FreeAndNil(ListBox1);
        ListBox1.
        ListBox1.Free;
        ListBox1 := nil;end;end.
      

  17.   

    呵呵,agui的代码终于给我启发了,我明白了,我们都犯了一个忌讳,不能在事件中释放对象自己。因为事件是个函数指针,对象从自己的代码中调用这个函数,调用完毕后,还要回到自己的代码中,如果这个时候对象被释放掉,当然要出AV错误了。这也是为什么hyhy95(无相)在执行完毕end后才出错的原因。
      

  18.   

    脱离关系也没有用。Borland好像早就说过,不能在事件中释放自己。
      

  19.   

    确实,脱离关系也没有用,大家劳苦功高了,其实我早就怀疑是不是在自己的事件中释放自己是不是妥当?我想应该是这个问题了.呆会一试就知道.
    但最后一关,我想Click事件把值传给TEdit后,马上把ListBox释放掉,在哪里写释放代码呢?
    可不可以定义一个消息,释放代码写在这里,然后在Click事件的最后发送消息?
      

  20.   

    To Focus(老鱼):我不是把TControl的代码贴出来了吗?setParent(nil)和.Parent := nil是等价的。也就是说,即使你在Free的时候不设置.Parent := nil,Delphi也会替你设置的。
    现在的错误是在事件中释放了对象自己,而这种代码在Delphi的体系结构中是不允许的。
      

  21.   

    真是奇异
    我在程序不知做过多少次
    类似于: hyhy95(无相) 兄的操作
    都是这么干的
    从来没出过错
      

  22.   

    可以发送一个消息给Form,通过这种方法释放对象。我好像就是这么处理的。
      

  23.   

    To Focus:你明白C程序出错的地方,往往不是代码错误的地方。道理就在这里。尽管你释放了对象,但是这个对象的内存还没有完全被破坏,所以你依旧可以用的。而且这种非法操作恰恰不会报错。
      

  24.   

    很感谢两位,chechy劳苦功高,给40分,同时也感谢老鱼,10分.
      

  25.   

    to : chechy(chechy) 
    这些知识来自何方?
    我想再深入学习一下