您的位置:首页 > 其它

关于在dll中封装系统模块的资料

2006-03-30 13:19 471 查看
在Dll中使用Mdi窗体存在的问题
redcony ()
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静态链接到主程序时出现的。

bittcn(Ocean Wave)
我们采用第一种方式搭建了一个框架,整个有框架和和子模块组成。
子模块封装成DLL供主程序调用,一个模块的变化不会引起整个框架和其它模块的变化。才开始也遇到过许多的问题。后来在主框架中作了一些处理,建立了一套窗体注册机制。但还是没有达到完善的地步。
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
);

jishiping(JSP 季世平)
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就不会出现在任务栏上了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: