用这个方法 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;
To chechy(chechy): 还是不行,问题仍然存在.
Edit1Change也应该在一开始检测listbox1的有效性。加入: if not assigned(listbox1) then exit;
请务必帮忙再分析一下,弹出的错误对话框如下: 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的指针判断都是正确的,不知到底是哪引起的.
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;
我一直不知道怎样用assigned,是不是虽然Free了,但这个ListBox指针还存在,一定要使它为空才能再创?
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;
还是不行,问题仍然存在.
if not assigned(listbox1) then exit;
listbox1.Parent := nil;
listbox1.Free;
应首先断开它与它父对象的关系!
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的指针判断都是正确的,不知到底是哪引起的.
必须先将它的parent:=nil才行
配合上freeandnil();
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;
begin
ListBox1.OnClick := nil; // !!!!! 试一试这个
Edit1.Text := ListBox1.Items.Strings[ListBox1.ItemIndex];
ListBox1.Free;
IsExist := False;
end;
可以确定释放后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.
但最后一关,我想Click事件把值传给TEdit后,马上把ListBox释放掉,在哪里写释放代码呢?
可不可以定义一个消息,释放代码写在这里,然后在Click事件的最后发送消息?
现在的错误是在事件中释放了对象自己,而这种代码在Delphi的体系结构中是不允许的。
我在程序不知做过多少次
类似于: hyhy95(无相) 兄的操作
都是这么干的
从来没出过错
这些知识来自何方?
我想再深入学习一下