(200分)讨论:在Dll中使用Mdi窗体存在的问题(Behard, Friecin,jishiping请进)

redcony 2002-11-05 04:53:30
1. 不使用Build With Runtime Package:
1.1 需要把Application全局变量传人Dll并覆盖原有的Application,在Dll退出时还原(跟踪代码发现还原后DLL的Application变量仍然是NULL) 才能创建MdiChild 窗体
1.2 创建的子窗体在主程序中访问不到,只有在主程序中自己记载各窗体以及当前活动的窗体
1.3 创建的子窗体最大化后和主窗体(含ToolBar)融合的不好看。
1.4 主窗体关闭时不触发子窗体的CloseQuery事件,却触发子窗体的Active事件,需要写代码控制子窗体的CloseQuery和Close事件。
1.5 编译的文件大。
2. 使用Build With Runtime Package(只包含Vcl50.bpl)
2.1 需要发布Vcl50。Bpl到系统目录下
2.2 每一个在动态库中显示的其他窗体(除了子窗体外)在任务栏上会出现图标,如果显示的窗体比较多时,效果太差。
2.3 主程序中自动维护当前所有子窗体
2.4 编译出的文件小
3. 其他
在方案1中如果传人Screen (子窗体上有一个TstatusBar)在创建时会出现一个“Cannot
Assign a font to a font “错误,在退出时好像也有访问非法地址的问题
在方案2中如果把其他窗体设为ToolWindow则可解决任务栏显示的问题,但是窗体的系统按钮没有了,并且用MessageBox也会在任务栏上产生图标。

以上所有的现象是在Dll静态链接到主程序时出现的。

...全文
53 点赞 收藏 18
写回复
18 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
yyl2000 2002-11-28
up

回复
gangAndgang 2002-11-23
如果有几十个人同时开发,如果不使用DLL,那么源代码的控制不是很麻烦???
回复
wj59 2002-11-12
up
回复
bittcn 2002-11-11
1.我所说的注册机制,就是大家在写DLL时都遵循的一种编程约定。
窗体初始化时向主窗体发送一个消息,主窗体在收到消息后,在自己维护的队列中查找是否这个窗体已经有实例,如果是,这将这个窗体置在顶层,不在创建这个窗体的实例;否则,创建这个窗体的实例,并在主窗体的窗体队列中加入这个窗体的指针;窗体在关闭前,也通过消息操作主窗体中的这个队列。
主窗体根据自己的这个队列,维护Window菜单。
2.我认为,尽管VCL打包DLL有很多不好的地方,但用DLL封装一个系统的模块还是一种比较好的方法。我们做了一些项目,一般都是一个主程序DLL外加数十个DLL。主程序只负责对DLL的调用,DLL中具体处理业务逻辑。我们在更新时,只简单地发送一个DLL,一般就是几百K,电子邮件就可以方便地传递,只须用新的DLL覆盖旧的DLL就行,不用作大的改动。所以我们更新都不用重新编译整个应用程序,也不用派技术人员到场,节约时间,节约成本。
3.防止Form有图标在任务栏上显示,也可以用API
HWND SetParent(
HWND hWndChild, // handle to window
HWND hWndNewParent // new parent window
);
回复
redcony 2002-11-11
绝对同意 bittcn的说法,如果不使用Dll,主程序有5-6M,维护起来对公司
来说代价太大,太麻烦,我也是用消息来替代了许多Vcl处理的过程
回复
Behard 2002-11-11
我一般是使用动态调用的
对于那些限制我的调试跟你们的有点区别
(最主要是我还是使用 BCB3.0 )
回复
jishiping 2002-11-10
这儿,我只是不赞成将MDIChild做在DLL中。如果不采用MDI架构,则不存在
这方面的问题。对于BCB的限制(或者说容易出问题的地方),我们应该尽量
避免使用它。如果不使用MDI架构,就没有关系了。对于项目组的开发,适当
使用DLL也是好的。但是如果过多的使用DLL,也不见得就是好事。如果一个项
目有几十个人开发,每个人都写一个DLL,这时你还会觉得使用DLL好吗?
回复
gangAndgang 2002-11-10
to jishiping(JSP 季世平)
1、反正我是不赞成在BCB中,将MDIChild做在DLL中的。我个人认为,VCL对
MDI的打包,做出了很多限制,如果将MDIChild做在DLL中,会有很多问题。

如果不把MDICHILD放在dll中,那么有更好的办法能做到将一个个的form分开编译成一个个独立的东西 ,并能在一起运行呢?而且这样的话对于项目组的开发也比较方便,因为每 个开发的东西可以组织成独立的dll,方便开发,也减少了一次编译的时间和最后集成的时间,不存在最后的系统集中到一起进行编译,而且还能先做好主窗体,然后再一步步的挂上各个子功能,比较符合软件工程中的那种增量开发模型呀
回复
jishiping 2002-11-10
同理,在EXE中的Form中重载虚函数,将Params.WndParent设成NULL,可以达
到让任意一个Form可以显示在任务栏上(正常情况下不会显示在任务栏上)。
回复
jishiping 2002-11-10
1、反正我是不赞成在BCB中,将MDIChild做在DLL中的。我个人认为,VCL对
MDI的打包,做出了很多限制,如果将MDIChild做在DLL中,会有很多问题。
2、对于问题2.2(每一个在动态库中显示的其他窗体在任务栏上会出现图标
),可以通过重载Form的虚函数CreateParams就可以解决了。最主要是改变
TCreateParams的成员变量WndParent。比如,将程序(EXE)的主窗口的句柄
传入DLL中(以下为DLL中的代码):
HWND MainWnd = NULL;

void __declspec(dllexport) __stdcall SetMainHandle(HWND hWnd)
{
MainWnd = hWnd;
}

class TDllForm1 : public TForm
{
__published: // IDE-managed Components
private: // User declarations
protected:
void __fastcall CreateParams(TCreateParams&);
public: // User declarations
__fastcall TDllForm1(TComponent* Owner);
};

void __fastcall TDllForm1::CreateParams(TCreateParams& Params)
{
TForm::CreateParams(Params);
Params.WndParent = MainWnd;
}

只要在EXE中调用上面写的DLL的函数SetMainHandle,将EXE的主窗口的
Handle传到DLL中,同时DLL中的所有Form(MDIChild除外)按照上面那样
重载虚函数CreateParams后,Form就不会出现在任务栏上了。
回复
gangAndgang 2002-11-10
同意 bittcn(Ocean Wave)
只是主窗体调用子窗体时动态调用较好,并且将主窗体的application传进去。至于窗体注册机制,可能是模拟主 窗体管理子窗体的一种方法吧。
回复
myy 2002-11-10
这方面我曾经研究过,总的来说,无论dll、bpl(较好)方式,都不尽如任意。
回复
redcony 2002-11-07
对于2.2
即使你传入Applciation,在Dll中出现的窗体(不是MDIChild)也一样在
任务栏上出现图标
对于2.3
最少VCL维护了当前Screen上所有的窗体,并负责释放,否则如何解释直接
关闭主窗口时,并没有触发当前所有字窗体的Close事件
并且使用Postmessage如何保证消息一定到达指定的窗体?
Windows会丢弃一些消息,使用SendMessage?
回复
Behard 2002-11-07
我使用第二种方案,而且是使用动态调用
我曾经(静态)和使用 Delphi(动态) 的比较过
发觉有些错误只在 BCB(静态) 中出现
我建议使用 动态调用

对于 2.2
只要和 子窗体的一样,把 Application 传进去就可以了
最明显的是使用 ShowMessage 时他的 title 不是你的 Project 名(不传递 Application)

对于 2.3
我觉得并不是这样的,我使用 PostMessage 处理
或者判断 MDIChildren[i]->Caption 然后在 Timer 中处理一些东西

2.4
我觉得这点很重要,特别是有 Dll 和 Exe 时,发布方便很多,而且文件小一点也快
回复
redcony 2002-11-06
bittcn :
如何建立一套窗体注册机制
回复
bittcn 2002-11-06
我们采用第一种方式搭建了一个框架,整个有框架和和子模块组成。
子模块封装成DLL供主程序调用,一个模块的变化不会引起整个框架和其它模块的变化。才开始也遇到过许多的问题。后来在主框架中作了一些处理,建立了一套窗体注册机制。但还是没有达到完善的地步。
回复
Libran 2002-11-06
在创建时会出现一个“Cannot Assign a font to a font “错误
——试试把有关控件的ParentFont属性设为false
回复
Behard 2002-11-05
mark
快下班了
明天再看
回复
发帖
C++ Builder
创建于2007-08-02

1.3w+

社区成员

C++ Builder相关内容讨论区
申请成为版主
帖子事件
创建了帖子
2002-11-05 04:53
社区公告
暂无公告