关于在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就不会出现在任务栏上了。
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就不会出现在任务栏上了。
相关文章推荐
- 关于 ASP 封装DLL 问题!
- 关于Cross-Dll问题(在不同的模块之间申请和释放内存)
- 关于gcc、glibc和binutils模块之间的关系,以及在现有系统上如何升级的总结
- 关于matlab的编译问题--出现找不到指定模块C:MATLAB7\bin\win32\atlas_Athlon.dll
- 关于系统搜索某个DLL的路径
- 关于用c生成的dll在使用其他供应商的工具创建可执行模块时遇到的一些问题
- 大型JavaWeb分布式系统中关于maven多模块构建以及代码依赖管理
- 关于gcc、glibc和binutils模块之间的关系,以及在现有系统上如何升级的总结
- 转一份关于理解yaffs文件系统很好的资料
- 关于系统启动时不能找到dnsapi.dll的问题
- 关于js封装框架类库之DOM操作模块(一)
- 【软件开发】关于Rundll32.exe调试动态库(.dll)时提示“找不到指定的模块”的解决方案
- 关于计算广告和推荐系统的一些资料
- 关于Linux系统启动自动加载模块
- 关于DLL封装
- 关于gcc、glibc和binutils模块之间的关系,以及在现有系统上如何升级的总结
- 分享关于风控反欺诈系统的资料
- 关于IE7/8上运行web网站,一直报错,提示故障模块名为:np_tdieplat.dll的解决办法
- 关于病毒模块插入系统、应用程序进程的问题
- 关于python scrapy执行爬虫出现的 ImportError: DLL load failed:找不到指定的模块