从DLL中导出的对象嵌入在窗体中,有一点问题,向高手请教! ( 积分: 200 )

  • 主题发起人 主题发起人 谢方
  • 开始时间 开始时间

谢方

Unregistered / Unconfirmed
GUEST, unregistred user!
[blue]
我在编写一个程序中,使用了
1、主程序与DLL使用接口,主程序调用DLL时传入主程序的接口,DLL导出对象也为接口方式;
2、DLL中的导出对象是Frame,在主程序进行调用时,嵌入到主程序窗体中;

在从DLL中导出Frame并嵌入到主程序中,发现了几个问题,并且也解决了一个,但我想,治本没有治根,最终的原因还是没有找到。

问题一:
Frame中的所有控件不能使用SetFocus方法,如果调用,则失败,提示没有父窗口;
经过多方查找,确认是Forms单元中的GetParentForm方法中不承认主程序窗体为TCustomForm,所以一直返回nil造成,为此,我还特地把Forms单元复制到DLL文件工程中,对该函数进行了修改。

问题二:
在里面的控件不会实时更新;比如说,改变Frame中的一个控件的Visible值,它不会发生变化,但实际是已经执行过了,但界面上根本就不更新。最明显的方式是看TPageControl控件,它切换页面,却总是只显示第一个页面的东西。
我在主程序中放置了一个Notebook,用于切换不同的页面。Frame就在第二个页中。当我切换主程序NoteBook页的时候,它才会更新。

现在能够确定的是:
1、DLL与主程序在一个Application下
2、Dll中的导出对象的Parent正确。
3、在导出时,已经在Frame所有的父中的Components中加入了Frame中的所有组件。

请问:
这应该是什么样的问题?而使它的界面不更新?应该如何解决?


[/blue]
 
[blue]
我在编写一个程序中,使用了
1、主程序与DLL使用接口,主程序调用DLL时传入主程序的接口,DLL导出对象也为接口方式;
2、DLL中的导出对象是Frame,在主程序进行调用时,嵌入到主程序窗体中;

在从DLL中导出Frame并嵌入到主程序中,发现了几个问题,并且也解决了一个,但我想,治本没有治根,最终的原因还是没有找到。

问题一:
Frame中的所有控件不能使用SetFocus方法,如果调用,则失败,提示没有父窗口;
经过多方查找,确认是Forms单元中的GetParentForm方法中不承认主程序窗体为TCustomForm,所以一直返回nil造成,为此,我还特地把Forms单元复制到DLL文件工程中,对该函数进行了修改。

问题二:
在里面的控件不会实时更新;比如说,改变Frame中的一个控件的Visible值,它不会发生变化,但实际是已经执行过了,但界面上根本就不更新。最明显的方式是看TPageControl控件,它切换页面,却总是只显示第一个页面的东西。
我在主程序中放置了一个Notebook,用于切换不同的页面。Frame就在第二个页中。当我切换主程序NoteBook页的时候,它才会更新。

现在能够确定的是:
1、DLL与主程序在一个Application下
2、Dll中的导出对象的Parent正确。
3、在导出时,已经在Frame所有的父中的Components中加入了Frame中的所有组件。

请问:
这应该是什么样的问题?而使它的界面不更新?应该如何解决?


[/blue]
 
父窗口和PARENT 是不一样的,PARENT 是窗体的基础,它的位子在PARANT 之上,父窗口是是消息的发送地。
想办法让主程序窗体为TCustomForm。
 
传入 Screen对象
 
songjungz:

主窗体就是TCustomForm类型。我用最后返回的类型显示出来了,但只是函数它不承认而已。

delphifaq:
没有用。试过了。
 
还是用BPL包吧,否则的话,DLL的类和EXE的类都各自为政,当需要相互“协商”、“交流”时就不能正常工作的。
 
lichengbin:
现在大部分问题都解决了,而且DLL的类可以通过接口调用各种主程序类中的方法、函数和其它的窗体调用。但是,它就是在做了一些操作之后,不更新自己。只有当主窗体的画面切换后,才会更新到最新的状态。
 
引用:lichengbin: DLL的类和EXE的类都各自为政,当需要相互“协商”、“交流”时就不能正常工作的。
DLL和EXE有各自独立的RTTI(运行时类型信息), 所以任何相互间的IS操作都返回FALSE!
 
to: jshyhzj
谢谢帮助,也许你是对的。我是这样解决此问题

Forms.pas

function GetParentForm(Control: TControl): TCustomForm;
begin
while Control.Parent <> nil do Control := Control.Parent;
if (Control is TCustomForm) then
Result := TCustomForm(Control) else
Result := nil;
end;

我把它修改为:
function GetParentForm(Control: TControl): TCustomForm;
begin
while Control.Parent <> nil do Control := Control.Parent;
if (Control is TCustomForm) or (Control = Application.MainForm) then
Result := TCustomForm(Control) else
Result := nil;
end;

就OK了。
 
将DLL中的 Application.Handle := 程序里的 Application.Hand
COM中都是用这个方式解决的,Dll没有用过
 
后退
顶部