步骤是这样的:
1、在DLL中触发事件是,向主程序发送消息,并向共享内存中输入需要共享的数据。
2、主程序窗体接收到消息,执行对应的XX过程。
3、XX过程是调用主程序中的业务窗体,关键是用showmodal的方式打开窗体。问题是:步骤1、2都可是实现,但是在XX过程中生成窗体实例,并在关闭时free窗体后,当我关闭整个主程序时,系统会提示内存错误。XX过程如下:
var
  FrmBusiForm :TFrmBusiForm;
  isOk :boolean; 
begin
    if not Assigned(FrmBusiForm) then
    begin
      FrmBusiForm:= TFrmBusiForm.Create(Application);
      //注:Application在调用DLL时作为参数传入,DLL中的窗体为MDI的子窗体
    end;
    FrmBusiForm.ShowModal;
    isOk := FrmBusiForm.mSaveOk;
    FrmBusiForm.free           //这一句不能够解决问题
  //FreeAndNil(FrmBusiForm);   //这一句不能够解决问题我查过比较多的相关问题,怀疑是,在生成窗体时,在堆栈里插入该窗体,然后当dll释放时,将该窗体指向的对象和控件全部释放了,导致当主程序退出时,无法查找到堆中窗体指针的指向内存。附上bittcn(Ocean Wave) 大侠写的一点:
“1.我所说的注册机制,就是大家在写DLL时都遵循的一种编程约定。 
窗体初始化时向主窗体发送一个消息,主窗体在收到消息后,在自己维护的队列中查找是否这个窗体已经有实例,如果是,这将这个窗体置在顶层,不在创建这个窗体的实例;否则,创建这个窗体的实例,并在主窗体的窗体队列中加入这个窗体的指针;窗体在关闭前,也通过消息操作主窗体中的这个队列。 主窗体根据自己的这个队列,维护Window菜单。”不知道我理解的是不是正确,并且如何向“主窗体的窗体队列中加入这个窗体的指针”,请各位大侠帮帮忙!~~谢谢!~~

解决方案 »

  1.   

    可能释放有问题
    try
    ....
    finally
     free
    end;
    试试看
      

  2.   

    我试过,用free和FreeAndNil(FrmBusiForm)都不行,问题似乎不在这里
      

  3.   

    FrmBusiForm:= TFrmBusiForm.Create(nil)   试试!
      

  4.   

    谢谢,FrmBusiForm:= TFrmBusiForm.Create(nil) 也试过了,还是不行
      

  5.   

    1、我想问题可能出在这里,因为在FrmBusiForm.ShowModal之前,实际的ACTIVE窗体是DLL中的窗体,所以showmodal使DLL中的窗体与FrmBusiForm窗体直接形成了逻辑上的父子关系,当DLL释放时,将FrmBusiForm指向的内存空间全部释放了,而主程序中指针队列中可能还有FrmBusiForm的窗体指针,所以在主程序结束时,会去释放该指针对应的内存空间(已经被DLL释放的内存空间),因此出现内存错误的问题。不知道我理解的是不是正确,请大家帮我想想解决的办法。
    2、我当时想在DLL中调用主程序中的窗体,因为这个窗体在DLL中和主程序中都有可能用到,
    我不想在DLL中再维护一遍这个窗体代码,所以希望能够有一部分窗体,能够在DLL中被调用。
    不知道大家是否遇到过类似的问题?
      

  6.   

    看看下面的源代码,可能对你有帮助
    http://www.2ccc.com/article.asp?articleid=3376
      

  7.   

    你可以尝试在主程序结束时或者Dll释放时判断frmBusiForm是否合法
      

  8.   

    wywry(Wyatt) 您提供的源码写得非常好,对我用处很大,谢谢!~但是我目前仍然没有找的解决的办法,请大家再帮帮忙。