unit formSystemPartNo
use ...
TfmSystemPartNo = class(TForm)
...
  private
    FFrame:TFrame;
    sel1,sel2:integer;
    procedure NextStep(sender:TObject);
    procedure LoadMainTypeFrame;
    procedure LoadSubTypeFrame;
  public...
  end;var
  fmSystemPartNo: TfmSystemPartNo;implementation
uses frameSelectType,frameSelectSubType;
...
procedure TfmSystemPartNo.LoadMainTypeFrame;
begin
  if FFrame<>nil then FFrame.free;
  FFrame:=TfrSelectType.Create(self,NextStep);(NextStep是一个过程)
end;
{NextStep是一个过程,响应 frame页面的事件}
procedure TfmSystemPartNo.LoadSubTypeFrame;
begin
  if FFrame<>nil then FFrame.free;
  FFrame:=TfrSelectSubType.Create(self,NextStep);
end;procedure TfmSystemPartNo.NextStep(sender: TOBject);
var
  sel:Integer;
begin  if sender.ClassName ='TfrSelectType' then
  begin
    sel1:=TfrSelectType(FFrame).ListBox1.ItemIndex;
    TfrSelectType(FFrame).free;
    LoadSubTypeFrame;
  end;  if sender.ClassName ='TfrSelectType' then
  begin
    sel2:=TfrSelectSubType(FFrame).ListBox1.ItemIndex;
    TfrSelectSubType(FFrame).free;
  end;
end;
end.在frame中没有free等类似的操作,
在调用LoadMainTypeFrame/LoadSubTypeFrame任一个之后再调用第二个就出错,Debugger Exception Notification
Project MIS.exe raised exception class EAccessViolation with message 'Access Violation at address 004A1917 in module 'vcl70.bpl'.Read of address 0000004B'.Proicess stoped.Use Step or Run to continue.在之前不调用NextStep时不会出错

解决方案 »

  1.   

    NextStep两个判断条件都是sender.ClassName ='TfrSelectType',什么意思?可以写成sender is TfrSelectType.
    再有,Free之后,将Frame置为nil。
      

  2.   

    帅哥说得对,你的问题在这procedure TfmSystemPartNo.NextStep(sender: TOBject);
    var
    sel:Integer;
    beginif sender.ClassName ='TfrSelectType' then
    begin
    sel1:=TfrSelectType(FFrame).ListBox1.ItemIndex;
    TfrSelectType(FFrame).free; //<<<<<<<<
    LoadSubTypeFrame;
    end;if sender.ClassName ='TfrSelectType' then
    begin
    sel2:=TfrSelectSubType(FFrame).ListBox1.ItemIndex;
    TfrSelectSubType(FFrame).free; //<<<<<<
    end;
    end;Free了以后没有设成nil,导致下次判断procedure TfmSystemPartNo.LoadMainTypeFrame / LoadSubTypeFrame;
    begin
      if FFrame<>nil then <<<
        FFrame.free();
     ...
    end;错误.若改成
    procedure TfmSystemPartNo.NextStep(sender: TOBject);
    var
      sel1, sel2:Integer;
    begin
      if sender.ClassName() = TfrSelectType.ClassName() then
      begin
        sel1:=TfrSelectType(FFrame).ListBox1.ItemIndex;
        FFrame.Free();
        FFrame := nil;
        LoadSubTypeFrame();
      end;  if Sender.ClassName() = TfrSelectSubType.ClassName() then
      begin
        sel2:=TfrSelectSubType(FFrame).ListBox1.ItemIndex;
        FFrame.Free(); 
        fFrame := nil;
      end;  ...
    end;应该ok另外,下面两个函数也有一点问题,procedure TfmSystemPartNo.LoadMainTypeFrame;
    begin
       if FFrame<>nil then 
       begin
         FFrame.free;
         FFrame := nil; //谨慎一点,也要补充这一句,因为下面的Create可能会发生异常,
                         //如果在Create返回以前发生异常,那么FFrame就指向一个无效的指针
       end;   FFrame:=TfrSelectType.Create(self,NextStep);(NextStep是一个过程)
    end;procedure TfmSystemPartNo.LoadSubTypeFrame;
    begin
      if FFrame<>nil then 
      begin
        FFrame.free;
        FFrame := nil; //类似的
      end;  FFrame:=TfrSelectSubType.Create(self,NextStep);
    end;SysUtils单元里面有个FreeAndNil,喜欢的也可以用
      

  3.   

    x:TParentTson1(x).xxx
    Tson2(x).xxx
      

  4.   

    我已经改了,本来想用一个名称来操作控件的,也想过可能是内存的释放问题,不过现在放弃了用个名称来操作的想法,只是现在又出现了新的问题。<a href=http://community.csdn.net/Expert/topic/4370/4370867.xml?temp=.2479212>
    http://community.csdn.net/Expert/topic/4370/4370867.xml?temp=.2479212
    </a>