用AlphaControls皮肤控件来美化用Dll制作的MDI子窗体程序
2014-01-03 15:58
656 查看
AlphaControls控件是目前效果比较好的皮肤控件,专业和细致。
有朋友咨询用Dll制作的MDI子窗体程序被调用后,没有被美化,如何处理?
其实即使正常的窗体被放在dll中,再用主程序来调用,按正常的程序也无法美化dll中的窗体。要想美化,就用包的形式即可。
我们制作非常简单的程序,主窗体为一MDI主窗体,在主窗体上放AlphaControls的TsSkinManager控件并设置其相关属性。
另建立一个dll工程,内建MDIChild子窗体,放TsSkinProvider于上。
如下图:
主程序:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/7ceb5169b4c80cb7a6ea7b415a2ebabe)
DLL中的子窗体:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/b93e471a4e707c60d282c1ed490c8139)
上面其它的控件没什么用,只是看下其它的美化如何而已。
我们以静态调用的方式来做例。以下为制作过程:
一、制作dll
dll和exe在运行时它们都有自己的application。因此在调用dll时要把主程序的Application传给dll中,即这个application属于dll的Owner,在dll卸载时要把原来dll的Application还原给dll,让dll继续它原来的处理,否则你在调用 时会出问题。
另把MDI子窗体封装在dll中,dll中的application并没有MDI主窗体,这样在调用时因为没有主窗体就不可以产生子窗体,这样就会出现找不到子窗体的错误提示信息了。因此就需要把应用程序的Application传到dll中才行。
我们用delphi建立dll时,有一个dll入口,即C++中的DLLMain()函数入口。 在delphi中dll的初始化工作是在工程文件最后的begin end中间。
我们先在工程文件中建立全局变量用于保存dll的application,,等dll退出时再还原dll的application即可。 dll的入口函数自己写,主要有四个参数,表示dll在加载或卸载时要进行的处理动作:
DLL_PROCESS_ATTACH: <进程中加载DLL时>
DLL_THREAD_ATTACH: <线程中加载DLL时>
DLL_THREAD_DETACH: <在线程中卸载Dll时>
DLL_PROCESS_DETACH: <在进程中卸载Dll时>
我们在程序调用dll时把dll的application保存到全局变量中,在退出时再还原,因此我们要把这些功能代码放到dll工程的begin..end之间。
另DllProc是全局变量用来指向dll的入口函数地址,即dll的调用和卸载都是从这个地址开始的,因为我们把这些处理过程全放在一个函数中,在dll的入口处把DllProc指向这个处理函数即可。
工程文件的源代码:
我们在子窗体中做一个公共函数用于导出调用:
记得传入的application是传址哦。
二、建立主应用程序
以下为窗体运行界面:
主窗体:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/36ace76bae8dd76524a46e76a60eece9)
调用后显示照片:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/7b37ecd4cb19d4ec43fa3710afa0640f)
记着:dll和主程序一定要用打包的方式才能美化子窗体,否则不能美化。如果不放置TsSkinProvider,则只能美化AlphaControls的控件,其它的不能美化。
不当之处请指正。
有朋友咨询用Dll制作的MDI子窗体程序被调用后,没有被美化,如何处理?
其实即使正常的窗体被放在dll中,再用主程序来调用,按正常的程序也无法美化dll中的窗体。要想美化,就用包的形式即可。
我们制作非常简单的程序,主窗体为一MDI主窗体,在主窗体上放AlphaControls的TsSkinManager控件并设置其相关属性。
另建立一个dll工程,内建MDIChild子窗体,放TsSkinProvider于上。
如下图:
主程序:
DLL中的子窗体:
上面其它的控件没什么用,只是看下其它的美化如何而已。
我们以静态调用的方式来做例。以下为制作过程:
一、制作dll
dll和exe在运行时它们都有自己的application。因此在调用dll时要把主程序的Application传给dll中,即这个application属于dll的Owner,在dll卸载时要把原来dll的Application还原给dll,让dll继续它原来的处理,否则你在调用 时会出问题。
另把MDI子窗体封装在dll中,dll中的application并没有MDI主窗体,这样在调用时因为没有主窗体就不可以产生子窗体,这样就会出现找不到子窗体的错误提示信息了。因此就需要把应用程序的Application传到dll中才行。
我们用delphi建立dll时,有一个dll入口,即C++中的DLLMain()函数入口。 在delphi中dll的初始化工作是在工程文件最后的begin end中间。
我们先在工程文件中建立全局变量用于保存dll的application,,等dll退出时再还原dll的application即可。 dll的入口函数自己写,主要有四个参数,表示dll在加载或卸载时要进行的处理动作:
DLL_PROCESS_ATTACH: <进程中加载DLL时>
DLL_THREAD_ATTACH: <线程中加载DLL时>
DLL_THREAD_DETACH: <在线程中卸载Dll时>
DLL_PROCESS_DETACH: <在进程中卸载Dll时>
我们在程序调用dll时把dll的application保存到全局变量中,在退出时再还原,因此我们要把这些功能代码放到dll工程的begin..end之间。
另DllProc是全局变量用来指向dll的入口函数地址,即dll的调用和卸载都是从这个地址开始的,因为我们把这些处理过程全放在一个函数中,在dll的入口处把DllProc指向这个处理函数即可。
工程文件的源代码:
library Prodll; { Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. } uses System.SysUtils, System.Classes, Vcl.Forms, Winapi.Windows, Vcl.Dialogs, USecond in 'USecond.pas' {UFrmSecond}; {$R *.res} var DllApp:TApplication; //保存原dll的Application //Dll的入口函数 procedure DLLEntry(Reason:DWORD); begin case Reason of DLL_PROCESS_ATTACH:Application.MessageBox('DLL_PROCESS_ATTACH','ok') ; DLL_THREAD_ATTACH: begin DllApp:=Application; Application.MessageBox('DLL_THREAD_ATTACH','ok'); end; DLL_THREAD_DETACH: Application.MessageBox('DLL_THREAD_DETACH','ok'); DLL_PROCESS_DETACH: begin Application:=DllApp; Application.MessageBox('DLL_PROCESS_DETACH','ok'); end; end; end; exports showme; begin //Dll被调用时初始化 //DLLApp:=Application; //也可以用前面这句话,此时可以把DLL_THREAD_ATTACH去掉即可。 DllProc:=@DLLEntry; end.
我们在子窗体中做一个公共函数用于导出调用:
unit USecond; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, sBevel, Vcl.StdCtrls, Vcl.Buttons, sBitBtn, sPanel, sSkinProvider, cxGraphics, cxControls, cxLookAndFeels, cxLookAndFeelPainters, cxStyles, dxSkinsCore, dxSkinXmas2008Blue, dxSkinscxPCPainter, cxCustomData, cxFilter, cxData, cxDataStorage, cxEdit, DB, cxDBData, cxContainer, cxDropDownEdit, cxTextEdit, cxMaskEdit, cxCalendar, cxProgressBar, cxGridLevel, cxClasses, cxGridCustomView, cxGridCustomTableView, cxGridTableView, cxGridDBTableView, cxGrid; type TUFrmSecond = class(TForm) sPanel1: TsPanel; sBitBtn1: TsBitBtn; sBevel1: TsBevel; sSkinProvider1: TsSkinProvider; Edit1: TEdit; Button1: TButton; cxGrid1DBTableView1: TcxGridDBTableView; cxGrid1Level1: TcxGridLevel; cxGrid1: TcxGrid; cxProgressBar1: TcxProgressBar; cxDateEdit1: TcxDateEdit; cxComboBox1: TcxComboBox; procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } public { Public declarations } end; procedure showme(var App: TApplication; ptitle: PChar; ParentForm: TForm); stdcall; var UFrmSecond: TUFrmSecond; implementation {$R *.dfm} procedure TUFrmSecond.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end; //传入应用程序的application及主窗体 procedure showme(var App: TApplication; ptitle: PChar; ParentForm: TForm); var i: integer; frm: TCustomForm; begin Application:=App; frm := nil; for i := 0 to ParentForm.MDIChildCount - 1 do begin if (Application.MainForm.MDIChildren[i] is TUFrmSecond) then frm := TUFrmSecond(Application.MainForm.MDIChildren[i]); end; if not Assigned(frm) then begin frm := TUFrmSecond.Create(ParentForm); end; //TForm(frm).FormStyle := fsMDIChild;//因在设计时设置了窗体样式,所以注销了。 frm.Caption:=StrPas(ptitle); frm.Show; end; end.
记得传入的application是传址哦。
二、建立主应用程序
unit UMain; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, sSkinProvider, sSkinManager; type TFrmMain = class(TForm) MainMenu1: TMainMenu; N1: TMenuItem; sSkinManager1: TsSkinManager; procedure N1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; procedureshowme(var App:TApplication; ptitle:PChar;ParentForm:TForm);stdcall; external 'Prodll.dll'; var FrmMain: TFrmMain; implementation {$R *.dfm} procedure TFrmMain.N1Click(Sender: TObject); begin showme(Application,'子窗体',FrmMain); end; end.
以下为窗体运行界面:
主窗体:
调用后显示照片:
记着:dll和主程序一定要用打包的方式才能美化子窗体,否则不能美化。如果不放置TsSkinProvider,则只能美化AlphaControls的控件,其它的不能美化。
不当之处请指正。
相关文章推荐
- 利用IrisSkin2.dll皮肤控件美化WINFORM窗体!
- Delphi 皮肤控件AlphaControls的使用
- 教程:简单几步教你在Win版Delphi7中安装AlphaControls皮肤控件包.
- Winform窗体半透明,控件不透明,及皮肤美化效果
- C#Windows窗体程序:用trackBar控件制作调色板
- 在应用了皮肤的程序中制作透明的文本编辑控件(如:TcxMemo)
- windows窗体程序中使用WPF控件 Host WPF Controls in Windows Forms Application
- Delphi封装Mdi窗体到Dll并使用插件管理,tabControl制作多页面
- Delphi 皮肤控件AlphaControls的使用
- Delphi 皮肤控件AlphaControls的使用
- 续《从DLL中获取VCLSkin皮肤的演示程序》谈DLL制作方法
- MDI窗体程序与DLL(有兴趣的请进入讨论)
- 一步一步玩控件:TabControl——从制作山寨Safari窗体开始
- Delphi中如何控制其他程序窗体上的窗口控件
- C#WinForm制作异形窗体/控件
- 一个问题——在MDI窗体中添加控件后显示子窗体
- c#皮肤美化:窗体换肤方案
- Qt Qt Quick QML 打包发布程序出现缺少dll,窗体空白,点击后无反应等发布不成功的终极解决方法
- delphi下实现控制其它窗体中的控件代码模板(delphi 7安装程序)
- 使用iexpress制作控件本地安装程序