关于带窗体的DLL的使用

evonxiang 2017-01-18 10:43:33
最近在测试把项目DLL化,带窗体的DLL写了一个对外的showDllForm的方法来被主程序调用,参数是主程序的handle,主程序中一个panel的handle,主程序的title。我的关闭按钮是在DLL的FORM上的,关闭用的代码是: Application.Terminate,点击关闭会弹出如下错误:



showDllForm方法的代码大致如下:

Application.Handle := ExeHandle;
Application.Title := Title;
Application.CreateForm(TLoginForm, LoginForm);
Application.CreateForm(TMain2012Form, Main2012Form);
LoginForm.ParentWindow := PanelHandle;
LoginForm.Show;


请问是什么原因,是不是必须要在主程序中去释放DLL。

顺便问一下,DLL中有个登陆form LoginForm大小比较小,如何处理可以让主程序的背景不显示出来。只显示出DLL的form。。。


谢谢各位大神。帮忙解个惑。。
...全文
416 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
santiaodahan 2017-03-08
  • 打赏
  • 举报
回复
引用 5 楼 santiaodahan 的回复:
[quote=引用 4 楼 evonxiang 的回复:] [quote=引用 2 楼 santiaodahan 的回复:] 主程序中的Panel作为容器,显示一个dll中的窗体,应该不会成功。两个不同程序中的对象像VCL组件那样交互不会有效,除非dll包装成控件,那就复杂了。窗体显示在panel中也不常见,可以考虑MDI窗体。dll中使用Application.CreateForm,IDE会报错,无法编辑,这可能不是规范用法,但编译能通过。dll中用Create方法动态创建窗体就可以。 另外,LoginForm做成模态窗体放到dll中,在主程序FormCreate中调用就可以先于主窗体显示了。
主程序作为容器调用DLL窗体是可以的,我DLL中一共2个界面 一个是登录界面TLoginForm,另外一个程序登录后的主界面,2个界面设置成主程序的子界面后都可以显示,现在我把TLoginForm模态显示,主界面设为主程序的子界面显示,DLL点关闭按钮后调试还是会报“无效窗口句柄”的错误,但是编译出来后不影响运行,就是DLL中有个最小化程序(Application.Minimize;)不起作用了,就是不知道有没有一个正确的处理DLL如何关闭程序的方式。[/quote] 调用关系不是容器,这两个程序的窗体是独立的,分属不同的Application。容器是指Parent或ParentWindow属性,你的dll中的窗体会显示在主程序Panel矩形范围内?最小化可以试试ShowWindow(Handle, SW_MINIMIZE); CreateForm和Minimize跟可执行程序有很大的关系,在dll中不一定好用,读其中的代码,不行就直接用Windows API。[/quote] 更正一下:dll中的窗体可以嵌入到主程序的Panel中,包括两个独立程序的情况。指定LoginForm.ParentWindow := PanelHandle;可以,其中ParentWindow属性是调用的API函数:SetParent。报“无效窗口句柄”的错误是因为被嵌入Panel所在窗体尚未创建或提前退出,所以应该先处理dll中的窗体。调用Terminate不会执行窗口的Close和CloseQuery事件,需要注意。
santiaodahan 2017-01-23
  • 打赏
  • 举报
回复
补充一点:Application.CreateForm报错的原因。当在dpr文件中出现变量(而不是字符串)对Application.Title或Application.HelpFile赋值时就会报CreateForm错误,dpr无法打开编辑。有不少讨论这个问题的,原因应该是Title和HelpFile对应着项目Options中的Application settings的Title和HelpFile输入值。它们只能接受字符串,当是变量时导致IDE无法识别。这是IDE的特性,但编译器没有此限制,可以正常编译。 另外,dll中begin。。。end.之间的代码一定会被执行一次,所以不需要自动创建的窗体最好不要放在此处,应该动态创建,随时释放。
santiaodahan 2017-01-22
  • 打赏
  • 举报
回复
引用 4 楼 evonxiang 的回复:
[quote=引用 2 楼 santiaodahan 的回复:] 主程序中的Panel作为容器,显示一个dll中的窗体,应该不会成功。两个不同程序中的对象像VCL组件那样交互不会有效,除非dll包装成控件,那就复杂了。窗体显示在panel中也不常见,可以考虑MDI窗体。dll中使用Application.CreateForm,IDE会报错,无法编辑,这可能不是规范用法,但编译能通过。dll中用Create方法动态创建窗体就可以。 另外,LoginForm做成模态窗体放到dll中,在主程序FormCreate中调用就可以先于主窗体显示了。
主程序作为容器调用DLL窗体是可以的,我DLL中一共2个界面 一个是登录界面TLoginForm,另外一个程序登录后的主界面,2个界面设置成主程序的子界面后都可以显示,现在我把TLoginForm模态显示,主界面设为主程序的子界面显示,DLL点关闭按钮后调试还是会报“无效窗口句柄”的错误,但是编译出来后不影响运行,就是DLL中有个最小化程序(Application.Minimize;)不起作用了,就是不知道有没有一个正确的处理DLL如何关闭程序的方式。[/quote] 调用关系不是容器,这两个程序的窗体是独立的,分属不同的Application。容器是指Parent或ParentWindow属性,你的dll中的窗体会显示在主程序Panel矩形范围内?最小化可以试试ShowWindow(Handle, SW_MINIMIZE); CreateForm和Minimize跟可执行程序有很大的关系,在dll中不一定好用,读其中的代码,不行就直接用Windows API。
evonxiang 2017-01-22
  • 打赏
  • 举报
回复
引用 2 楼 santiaodahan 的回复:
主程序中的Panel作为容器,显示一个dll中的窗体,应该不会成功。两个不同程序中的对象像VCL组件那样交互不会有效,除非dll包装成控件,那就复杂了。窗体显示在panel中也不常见,可以考虑MDI窗体。dll中使用Application.CreateForm,IDE会报错,无法编辑,这可能不是规范用法,但编译能通过。dll中用Create方法动态创建窗体就可以。 另外,LoginForm做成模态窗体放到dll中,在主程序FormCreate中调用就可以先于主窗体显示了。
主程序作为容器调用DLL窗体是可以的,我DLL中一共2个界面 一个是登录界面TLoginForm,另外一个程序登录后的主界面,2个界面设置成主程序的子界面后都可以显示,现在我把TLoginForm模态显示,主界面设为主程序的子界面显示,DLL点关闭按钮后调试还是会报“无效窗口句柄”的错误,但是编译出来后不影响运行,就是DLL中有个最小化程序(Application.Minimize;)不起作用了,就是不知道有没有一个正确的处理DLL如何关闭程序的方式。
lcmlhs_2005 2017-01-19
  • 打赏
  • 举报
回复
可以通过调用一个接口函数来做,我也是提醒一下。
santiaodahan 2017-01-18
  • 打赏
  • 举报
回复
主程序中的Panel作为容器,显示一个dll中的窗体,应该不会成功。两个不同程序中的对象像VCL组件那样交互不会有效,除非dll包装成控件,那就复杂了。窗体显示在panel中也不常见,可以考虑MDI窗体。dll中使用Application.CreateForm,IDE会报错,无法编辑,这可能不是规范用法,但编译能通过。dll中用Create方法动态创建窗体就可以。 另外,LoginForm做成模态窗体放到dll中,在主程序FormCreate中调用就可以先于主窗体显示了。
  • 打赏
  • 举报
回复
在DLL_PROCESS_DETACH处理部分释放资源。

5,386

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧