VCLSkin组件使用、Delphi界面美化图文教程

只要在程序的任何一个窗体里加入SkinData组件,设置好相关属性,则所有这个程序
【菜科解读】
VCLSkin是个方便而且功能强大的界面加强型组件包。
只要在程序的任何一个窗体里加入SkinData组件,设置好相关属性,则所有这个程序里出现的窗体(包括对话框)都具有设置好的界面风格。
SkinStore组件又可以把一些皮肤文件预先存在里面,供SkinData随时调用,表现出程序的多种风格。
下面简单地介绍它的用法。
1. VCLSkin综述VCLSkin 是一个能让Delphi程序变得非常漂亮的控件包. 它允许允许软件开发人员不用修改程序代码便把软件界面变得非常漂亮。
它的美化支持窗体和控件和菜单。
VCLSkin同时也提供了大量高质量的skin(皮肤)让你应用于你的程序。
2. VCLSkin特点VCLSkin 是一个用于让用户的程序界面更加漂亮的扩展控件。
它允许软件开发人员不用修改源代码就能让他们的程序界面更加漂亮。
一个标准的程序界面能在窗体放入VCLSkin控件后变得非常漂亮,而这公公需要几分钟的时间。
VCLSkin 能做些什么 ?不像其它控件那样,你需要修改源代码才能构建一个漂亮的界面, VCLskin 能让Delphi的标准控件在一下子就变得非常漂亮,而这一切都不用修改源代码。
VCLSkin 支持以下的窗体: * Delphi Form * MDIform . (normal,Maximized, MInimized) * Common Windows dialogs (Open/Save,Font,Print,Color). * MsgBox. * Exception MsgBox.VCLSkin 支持的标准控件: * The title bar of TForm * The title bar buttons * The borders of Tform * Tbutton,TBitbtn. * Tradiobutton and Tcheckbox * Tmainmenu and Tpopupmenu * Toolbar buttons * TTabcontrol and TPageControl * T Progressbar * TStatusbar * TCustomCombox,Tcombobox, TDbCombobox * TPanel and TGroupbox * TMemo, TListBox,TListView,TTreeview * TRadioGroup , TDBRadioGroup. * TCustomGrid,TStringgrid,TDrawgrid,Tdbgrid. * Third party component, Enlib, AdvGrid ..同时也支持大量的第三方控件。
3.安装你可以像安装其它控件一样安装这夽控件,其实就这几步: 1. 解压缩 Vclskin2.zip 到任意目录 2. 在 Delphi IDE 环境中选择菜单 "File. Open...", 然后找到连接库 vclskindX.dpk, 按着点击Compile按钮。
3. 在 Environment 添加VCLSkin控件所在的路径。
*****************************************************************************************1. TSkinDataTSkinData 主要用于美化你的程序, 只要把TSkinData控件放下去,它就能自动美化所有窗体。
属性Active: 使用或取消对程序的美化。
DisableTag: 取消对某个特定的组件的美化; 把组件的Tag属性设为99就行了。
(control.tag mod 100=disabletag)SkinControls: 指定哪类组件能被美化.SkinFile: skin(皮肤)文件的包含路径的文件名,在运行时加载。
SkinStore: 在设计模式时储备的skin文件.SkinFormType: 能使用多种美化方式.方法LoadFromStream(Stream: TStream);LoadFromFile(value:string);LoadFromCollection(astore:TSkinStore;aindex:integer);在运行时装载skin文件.UpdateSkinControl(fParent:Tform);UpdateMenu(fParent:Tform);在运行时组件创建时进行美化。
事件OnFormSkin(Sender:TObject;aName:string;Var DoSkin:boolean);OnFormSkin 事件的发生先于美化窗体, 如果 Doskin 为 true, Vclskin 就会美化这个窗体, 如果为false,Vclskin 就会跳过这个窗体. aName 是窗体的类名.OnSkinChangned(Sender:TObject);OnSkinChanged 发生在skin文件改变之后。
2. TSkinStoreTSkinStore 能让你在设计模式时储存多个skin文件。
TSkinData 能在运行时从 TSkinStore 装载skin文件:TSkinData.LoadFromCollection(astore:TSkinStore;aindex:integer),3. 怎么美化程序界面你可以在几分钟内构建一个漂亮的程序.1 把 TSkindata 控件放在主窗体上。
2 设置 Skindata.skinstore 属性 , 把skin文件储存在你的程序中。
3 设置 Skindata.active = true4 编译运行你的程序。
4. VCLSkin FAQ1 如果我的工程中有14个窗体,用不用每个窗体都放一个skin控件?不用,你只需要放置一个Tskindata在你的主窗体,Vclskin就能自动美化每个窗体。
2 怎样美化一个内嵌的窗体 ?Vclskin 不能自动美化内嵌窗体,你要手动控制它。
压缩包中有一个"NestedForm"的例子,讲的是在运行状态美化内嵌窗体、框架的。
3 怎样美化动态控件 ?你需要手动控制它。
代码如下:control:=Tmycontrol.create(form1);skindata1.UpdateSkincontrol(form1); // add this line to skin dynamic control.4 怎样美化依靠窗体 ?Vclskin 支持停靠窗体. 例程代码如下:procedure TDockableForm.FormShow(Sender: TObject);beginif MainForm.skindata1.active then MainForm.skindata1.skinform(handle);end;5 怎么美化动态的右键菜单 ?例程代码如下:popup:=Tpopupmenu.create(form1);..... add menuiteskindata1.UpdateMenu(form1); //add this linepopup.popup(x,y);6 怎样美化动态窗体 ?Vclskin 可以美化动态窗体 , 但不能自动美化内嵌窗体. 点击这儿查看如何美化内嵌窗体.7 找不到文件 'c:\program files\borland\delphi7\SM\winskindata.pas'Delphi7 试用版与Delphi7正式版的Dcu文件格式是不一样的。
如果你使用的是正式版,你可以安装一个演示包。
vclskin2.zip.如果你使用的是试用版,你可以安装一个演示包。
D7trial.zip.8 使用 FastReport 时,出现了“无效操作,控件没有父窗体的的错误提示 ?设置 TSkindata.skincontrols.xcFastReport = true 就可以解决这个问题。
9 使用 ReportBuilder 出现了“无效操作,控件没有父窗体的错误提示?你可以在 TSkindata.OnformSkin 事件中取消美化这个控件。
代码如下 :procedure Tform1.SkinData1FormSkin(Sender: TObject;aName: String; var DoSkin: Boolean);begin//'TppPrintPreview' 就是要取消美化的窗体名称。
if aName='TppPrintPreview' then doskin:=false;end;10 如何存取skin文件的颜色?你可以借助 Tskindata.colors[] 属性来存取颜色。
比如说 , 窗体的背景色是 : skindata.Colors[csButtonFace].TShemeColor=(csText,csTitleTextActive,csTitleTextNoActive,csButtonFace,csButtonText,csButtonHilight,csButtonlight,csButtonShadow,csButtonDkshadow,csSelectText,csSelectBg,csHilightText,csHilight,csMenuBar,csMenuBarText,csMenuText,csMenubg,csScrollbar,csTextDisable);TShemeColors=array[csText..csTextDisable] of Tcolor;Skindata.Colors: TShemeColors;11 用户能自定义那些可视化控件的外观吗?你可以使用 skin builder自定义细节.12 怎样取消美化某个窗体或控件?设置 form.tag=99 取消 美化这个窗体。
13 如何在美化一个工程的窗体标题栏和菜单的风格?设置 TSkindata.skincontrols.xcMainmenu = false
先建立一个新工程,加入一些常见的组件。
运行结果的界面如图9.18所示。
然后加入一个SkinData控件,把Active属性设为True。
再单击SkinStore属性的带省略号的按钮,选择VCLSkin自带的一个皮肤文件macos.skn。
然后,编译,运行,结果如图9.19所示。
图9.18 原始程序 图9.19 加入VCLSkin组件后的效果
此处将程序界面从原来古板的样貌变成Mac Os风格没有用一行代码,只设了SkinData的属性。
下面我们结合SkinStore组件讲讲程序中“换肤”的做法。
在窗体上加入一个SkinStore组件,在Object Inspector中单击Store后面的带省略号的按钮,出现如图9.20所示的窗体。
单击图标,新生成一个SkinStore,可以像上面设置SkinData的SkinStore那样设置好它的属性。
创建多个SkinStore,存入多个皮肤。
然后在窗体的按钮上加入如下代码(代码的作用是当程序运行中按下Button1时,SkinData1会从SkinStore1中读取第1个皮肤,并显示出来):
procedure TForm1.Button1Click(Sender: TObject);
begin
SkinData1.LoadFromCollection(SkinStore1,1);
end;
类似地,加入以下代码:
procedure TForm1.Button3Click(Sender: TObject);
begin
SkinData1.LoadFromCollection(SkinStore1,2);
end;
procedure TForm1.SpeedButton3Click(Sender: TObject);
begin
SkinData1.LoadFromCollection(SkinStore1,3);
end;
“换肤”功能完成了。
在程序中按下那几个按钮,程序界面的风格就会相应改变。
图9.21示出了两个例子。
图9.21 VCLSkin的另两种皮肤效果
VCLSkin的功能远不止如此,我们挑几个说一下:
· DataSkin有个DisableTag属性。
默认值是99。
如果窗体上哪个组件的Tag值是99的话,DataSkin不会对这个组件起作用。
· 支持MDI窗体。
· 支持通用Windows对话框(打开,保存文件等)。
· SkinControls属性可以设置对哪类控件起作用。
· 在一个程序中不同窗体可以有不同皮肤风格。
VCLSkin,组件,使用,、,Delphi,界面,美化,图Ecplise编译Cygwin环境、使用CDT插件开发C/C++
编译环境采用的是Cygwin。
使用Ecplise4.2 + CDT8.1.2 +Cygwin2.774。
建议先阅读第6条的注意事项。
强烈介意:先安装配置cygwin再安装cdt插件一、具体安装步骤为了保证安装顺利,请按以下步骤来进行。
1、安装Cygwin下载地址:http://cygwin.com/setup.exe官网:http://cygwin.com/下载好后,点击setup.exe进行安装,出现如下图所示界面 点击“NEXT”后我们看到如下界面:我们看到有三种安装模式:Install from Internet,这种模式直接从Internet安装,适合网速较快的情况;Download Without Installing,这种模式只从网上下载Cygwin的组件包,但不安装;Install from Local Directory,这种模式与上面第二种模式对应,当你的Cygwin组件包已经下载到本地,则可以使用此模式从本地安装Cygwin。
从上述三种模式中选择适合你的安装模式,这里我们选择第一种安装模式,直接从网上安装,当然在下载的同时,Cygwin组件也保存到了本地,以便以后能够再次安装。
选中后,点击“下一步”。
这一步选择Cygwin的安装目录,以及一些参数的设置。
默认的安装位置是C:\cygwin\,你也可以选择自己的安装目录,然后选择“下一步”,这一步我们可以选择安装过程中从网上下载的Cygwin组件包的保存位置,选择完以后,点击“下一步”,这一步选择连接的方式,选择你的连接方式,然后点击下一步,会出现选择下载站点的对话框,如下图所示,此步选择第一个163提供的镜像网站就可以,国内下载速度挺快,如果有其他镜像,可以输入URL后,点击“Add”进行添加,然后再在列表中选中。
选择完成后,点击“下一步”,进过下载几个文件后显示如下界面下面就在这个界面中下载我们需要编译C/C++代码的Packages,我们只需要下载“Devel”分支下几个包就可以了,gcc,gcc-core,gcc-g++,gcc-mingw-core,gcc-mingw-g++,make ,gdb,binutils。
在上图的search框中输入gcc,程序会自动进行搜索,如下图,通过选择“Devel”分支下的包,找到安装我们需要的包,然后点击Skip来选择最新的安装包这是已经成功安装最新版本包后的图示,大家单击“Skip”来选择最新版本的安装。
同理,输入“make”后,选择“Devel”分支下的包,下载如图所示的包:输入“gdb”后,选择“Devel”分支下的包,下载如图所示的包:输入“binutils”后,选择“Devel”分支下的包,下载如图所示的包:选完以后,我们选择下一步,进入安装过程,如下图所示,安装的时间依据你选择的组件以及网络情况而定。
安装完成后,安装程序会提示是否在桌面上创建Cygwin图标等,点击完成退出安装程序。
2、配置Windows的环境变量熟悉Java开发环境的都应该知道怎么找到环境变量,实在不知道的去百度下吧。
将cygwin\bin目录加入到环境变量PATH中。
然后,打开cmd命令行窗口,分别试一下gcc , g++命令。
如果显示“访问被拒绝” (access denied), 进入cygwin安装目录\bin下检查g++.exe, gcc.exe是否只有1k大小,如果是,那么文件是符号链接,那么把文件重命名一下(备份)。
然后把g++-3.exe(或者g++-4.exe)拷贝一份,重命名为g++.exe。
把gcc-3.exe拷贝一份,重命名为gcc.exe。
3、下载Ecplise CDT插件下载地址:http://www.eclipse.org/cdt/downloads.php参考:Ecplise插件的安装的四种方法。
或者通过Ecplise自动升级功能进行安装,如下图所示:添加地址:http://download.eclipse.org/tools/cdt/releases/juno4、配置Ecplise的C/C++开发环境(1)设置Ecplise与Cygwin的路径映射按以下步骤打开Ecplise:Window -> Preferences->C/C++->Debug-> Common Source Lookup Path -> add -> new "Path Mapping".映射方法,如下图:eclipse中调试时,由于GDB使用的unix格式的路径,而eclipse使用的是windows路径,导致找不到匹配的代码, 把linux的路径映射windows的路径:比如 /cygwin/c 映射成 C:\ 。
(2)配置C/C++的"Makefile Project",选择“PE Windows Parser", 和”Cygwin PE Parser" 两项。
5、在Ecplise中创建工程编写C/C++代码(1)创建C/C++工程点击”Next“,显示如下图:点击”Next“,显示如下图:点击”Finish“完成创建。
当编写好代码后,可以对你的工程进行编译,点击“Project”选项下的"Builder Project"项目即可。
编译后的工程,如下图所示:此时是成功编译后“Consloe”控制台的显示画面。
点击上面选中的,然后点击鼠标右键,选择“Run”,即可运行程序。
此时控制台即可打印出文字了。
到此我们就完成了Ecplise + CDT + Cygwin开发环境的配置,以后你就可以享用其方便的功能了。
6、常见问题1、Eclipse下的CDT创建C++项目时候,不能自动生成includes文件夹有两种解决方法:(1)打开Window -> Preferences->C/C++->Environment,如下图所示,添加两个环境变量将C_INCLUDE_PATH 设为 /usr/include将CPLUS_INCLUDE_PATH 设为 /usr/include/c++如果在Cygwin的/usr/include/目录下没有c++这个目录,可以从\cygwin\lib\gcc\i686-pc-cygwin\3.4.4\include\c++拷贝一个到目录下,或者直接添加这个目录都可以。
此步也可以解决代码中提示的显示信息”Unresolved inclusion:“问题,尽管不影响编译,只是无法定位头文件中的符号。
(2)在Windows里面,加入环境变量CPLUS_INCLUDE_PATH 和C_INCLUDE_PATH,并都设置成,安装的Cygwin的对应lib路径:D:\cygwin\lib然后再新建C/C++项目的时候,就可以自动生产Includes文件夹了。
2、用eclipse 建立编译C++工程出现错误提示 “symbol could not be resolved”问题原因:是debug下的source lookup path没有映射正确。
解决办法:window -> preferences -> C/C++ -> debug -> source lookup path > Path Mapping\cygdirve\c C:\用cygwin下的c盘来替代当前的C盘 来查找需要的库文件,如果你的Cygwin安装在C盘,则映射C盘,如果安装在D盘,则映射为\cygdirve\d D:\,其他盘同理。
3、用eclipse 建立编译C++Debug工程出现错误提示以下错误依然是上面映射的问题,打开Cygwin自带的“Cygwin Terminal”,然后输入以下命令“mount”如图所示:上面就是我们设置的映射,如果没有你的Ecplise的Workspace所在的盘的位置的映射,请按照上面的说明进行添加,即可调试成功。
例如,我的Workspace在D:盘下,则我想调试程序,必须映射到D盘的位置。
4、解决Eclipse的CDT编写的c/c++程序的运行结果不能输出到console的问题(1)设置“Debug Configurations"里的“Environment”选项,添加PATH,指定X:\cygwin\bin的路径。
如图所示(2)如果build不能通过(编译正常通过后会出现类似下面的输出)**** Build of configuration Debug for project Test ****make allmake: Nothing to be done for `all‘.**** Build Finished ****请按照上面步骤重新安装。
Ecplise,编译,Cygwin,环境,、,使用,CDT,
JS正则表达式的RegExp对象和括号的使用等需要注意的
但在要求参数变化的环境下,RegExp()构造函数是更好的选择:var reg1 = /‘\w+‘/g;var reg2 = new RegExp(‘\‘\\w+\‘‘,‘g‘);对比两种创建方式,RegExp中的第一个参数为要创建的正则字符串,一方面注意,因为不是直接量的表示形式,因此不用斜杠“ / ”括起来了;而是字符串中必须要对引号“ ‘ ”和转义符号“ \ ”进行二次转义。
此外,无论是直接量还是RegExp()构造函数,都是生成了新的RegExp对象,并将其赋值给变量。
在《Javascript权威指南》一书中讲到,对于正则表达式的直接量,ECMAscript 3规定在每次它时都会返回同一个RegExp对象,因此用直接量创建的正则表达式的会共享一个实例。
直到ECMAScript 5才规定每次返回不同的实例。
各浏览器中,IE一直遵守ECMAScript 5中的规定,其他浏览器的较老版本则遵循ECMAScript 3的规定。
因此在实际应用中,采取构造函数创建的方法比较安全,或者在使用lastIndex属性时要记得归0。
括号()的使用:1、分组即把单独项组合成子表达式统一处理,一般用于?、+、*、{n,m}等的重复处理。
见例子:var reg = /Java(script)?/;式子里将script进行统一处理。
2、向后引用即在正则表达式中用“\n”(n代表引用的序号)引用式中前面括号中匹配的文本。
见例子:var reg = /(\d+)[a-z]{3}\1/; //20man20//20man23 错//reg = /\1[a-z]{3}(\d+)/; 错注意 “\n”引用的是前面匹配的文本" 20 ",而不是匹配的正则表达式" \d+ "。
另外,JS里只能引用前面的匹配文本,像例子中的将 \1写在括号引用的前面,将不会匹配到任何文本,浏览器中会提示出错。
同样,JS里也不支持类似“ (?exp) ”(exp为正则字符)的引用命名规则,只支持数字的引用。
既然提到了分组和引用,如果只想进行分组,而不想引用,则可用 "(?: exp)"的形式,既不匹配文本,也不给引用编号。
见例子:var reg = /(\w{3})(?:\d+)([a-z]{2})\2/;//man7788abab显然 \2 匹配的是 "ab" 而不是 "7788" 。
这样便于分组处理,也加快了查询的效率。
3、子模式匹配有时我们想直接引用操作括号匹配的本文,那么可以用子模式匹配的功能(权威指南里叫子模式匹配,有点别扭,实际就是用一个变量形式替换匹配的文本)。
基本形式是用 ’$n’的形式替代匹配编号为n的文本,常用在String对象里的replace()方法,见例子,等号两边交换单词:var reg = /(\w+)=(\w+)/;var str = ‘love=hate’;str.replace(reg,‘$2=$1‘);//"hate=love"次序、贪婪、懒惰:一般的重复匹配字符如?、+、*、{n,m}在匹配的过程中,采用贪婪匹配的方法,即尽可能多的匹配到结果字符。
与之对应的是懒惰匹配,即尽可能少的匹配结果,使用形式只需在重复匹配字符后加上问号" ? "即可,如??、+?、*?、{n,m}?。
见例子:var str = ‘goooogle‘;var reg1 = /o+/; //"goooo"var reg2 = /o+?/; //"go" 现在对例子稍加改动:var str = ‘goooogle‘;var reg1 = /o+gle/; //"oooogle"var reg2 = /o+?gle/; //"oooogle"改过后的例子结果变为相同了,为什么 /o+?gle/ 没有匹配到“ogle”呢?原来正则表达式中总是从左往右进行匹配的,不会从右边获取子串进行匹配。
虽然上面的结果相同,但匹配的原理不太一样。
在reg1中,首先o+会匹配所有的"o",然后接着匹配"gle",从而完成整体匹配。
而在reg2中,o+?会先匹配一个"o",然后gle在字符串的第2位到第4位(即原串的"ooo")匹配失败。
进而回溯至o+?去匹配第二个"o",成功后再在第3位到第4位匹配"gle",以此类推……最后匹配到整个字符串。
总体要记住,从优先级来说,从左往右的次序匹配 > 贪婪 / 懒惰匹配。
零宽断言:关于零宽断言的总体解释可参考博文《正则表达式30分钟入门教程》,值得注意的是,JS里只支持零宽先行断言。
即零宽正预测先行断言"(?=exp)"和零宽负预测先行断言“(?!exp)"。
所谓“零宽”,就是它并不在匹配的结果字符中占据空间。
例如“\w","\s"就会占据一个或几个空间,依匹配的字符长度决定。
而像”^","$"这种对应的首末位置,不占据空间,零宽就是属于这一类。
所谓“正 / 负预测”,是指断言中要求满足的情况。
“正”表示要满足exp,“负”表示要不满足exp的。
所谓"先行",是指被匹配的字符串在前面,零宽断言跟在后面。
即串的后一部分是否满足断言。
所谓“断言”,就是判断的条件。
看两种零宽断言的例子:var str = ‘java coffeescript‘;var reg1 = /\b\w+(?=script\b)/; //coffee var reg2 = /\b\w+(?!script\b)/; //javareg1为零宽正预测先行断言,"(?=script\b)"表示某单词需以“script”结尾,它代表着一种条件,不占有任何空间大小。
同样,reg2为零宽负预测先行断言,"(?!script\b)"表示不以“script”结尾的单词。
另外,因为没有零宽后顾断言,不能判断某字符串的前面部分满足什么条件。
但在JS中可以用多次正则表达式来实现:先匹配到要找的串,然后截取开头到index的字符子串,再匹配子串末尾是否符合需要的断言条件。
具体用法可另外尝试一下。
match()与exec()的异同:match和exec是正则表达式匹配字符串的常用方法。
两者实现的功能差不多,有些细微的区别:1、使用方式match是字符串包装对象的方法,用法:String.match(RegExp);exec是正则表达式对象的方法,用法:RegExp.exec(String);2、返回的结果当RegExp没有设置全局标志 "g" 时:两者的返回结果相同。
即无匹配值时返回null,有匹配值时返回一个数组(令array)。
array[0]为匹配的字符串,array[1]、array[2]……则对应为正则表达式中圆括号匹配的子字符串$1、$2……。
同时数组带有两个属性,array.index表示匹配字符串的初始位置,array.input表示正在检索的字符串。
当RegExp有设置全局标志 "g" 时:match在有值时返回一个数组array。
数组的每项依次表示匹配到的所有的字符串,因此不再有圆括号匹配的子字符串了。
此时数组没有index属性和input属性。
exec则与没有全局标示 "g" 的表现无异。
此时返回的是数组array,array[0]为当前匹配的字符串,array[1],array[2]……则为当前匹配下的圆括号匹配的字串。
此时要注意RegExp对象的lastIndex属性,表示原字符串中匹配的字符串末尾的后一个位置。
当没有进一步的匹配结果时,lastIndex属性置0。
因此,可用lastIndex的循环找出所有的匹配字符串。
来看看例子:varstr = ‘I love1 my job22‘;var reg = /\b[a-z]+(\d+)\b/g;array = str.match(reg);//array = ["love1", "job22"] //array.index = undefind//array.input = undefined------------------------------------array = reg.exec(str);//array = ["love1", "1"]//array.index = 2//array.input = "I love1 my job22"//reg.lastIndex = 7//run againreg.exec(str);//array = ["job22", "22"]//array.index = 11//array.input = "I love1 my job22"//reg.lastIndex = 16//run againreg.exec(str);//reg.lastIndex = 0最后,考虑到ECMAScript 3 和ECMAScript 5的版本区别,每次匹配完之后记得要手动将RegExp对象的lastIndex属性置0,以满足老非IE浏览器的要求。
正则,表达式,的,RegExp,对象,和,括,号的,使用,