走近vb.net(十一) 随心所欲窗体外观(skin精彩源码)
前几天因为应付约稿,答应的这个源码推迟了几天,今天熬夜把他写出来,请见谅。另外我想说一些题外话,前时我曾在文章中说过,说vb.net的面向对象抄袭java,delphi没有实际根据(你总不能把面象对象理解成linux核心一样的源码技术,他主要还是一种指导思想),这句话本身就有了逻辑性的错误,请问java与delphi是谁抄谁呢?答案只能是smalltalk的面向对象更早(见王国荣的文章)。 vc的面向对象大家闭口不提,然而我个人认为在windows编程上(不包括网络应用)vc仍是最强大的语言,而vc的程序员几乎没有人出来说这些无聊的话。那么是谁在说呢......
这个说法最早源于国外的文章(指在网络应用上有涉嫌模仿java,如果是编写windows程序则毫无根据),而作者在后来的撰文中很清楚的告诉大家纠正此说法。我也一再提到过。可有 人视若无睹。大家现在就说vb.net如何如何太早了一点,我们都是在实践摸索,用都不会用,就毫无根据的揣测有些不智。很多学java的告诉你先学java再学vb.net.这有些不可思议,起码到目前,没有看到java程序员写出我们可以拿来学的vb.net程序。因为有了面象对象的思想不等于有了一切。
现在面向对象真有些神化了,这不可思议,程序员不是哲人,是要通宵达旦的工作学习创造,好象一点也不浪漫!而现在竟被一部分人浪漫了。
不论微软如何的称颂他的网络功能,我相信在不久的将来,vb.net必将成为最快速,最重要,也最适用windows平台的应用程序编程语言(我没有涉及网络应用)。当然决不可能是最强大的,这世界好象没有谁最强大!而且我对他的网络应用不感兴趣。每个人都有自已的路。正如大家都说vb如何的适宜于开发数据库。但是你相不相信一个人从不接触数据库可以写出让人很看好的程 序,每个人有权利选择自已的路! 如果你对网络应用毫无兴趣,java还会是一个好的选择吗?
我个人认为无论是java,delphi,还是vb.net甚至c++,各有各的长处。各有各的用途。无优劣之分,编程最重要的是灵感,是广博的视野,是宽大的襟怀。任何想贬低别人的人,正暴露自已的浅见与无知。我虽然是学vb的,但我在进入delphi的论坛以后,我亦为之感动,这里也有很多兢兢业业,无私奉献的值得尊敬与学习的人。工具永远不能征服人性!外国人没有因这纸是中国人造的而不用,亦没有因火药是中国人发明的而羞愧,也没有因这二进制的起源于中国而牢骚,科学是跨越国界的,不应被蒙上政治色彩。
我曾在一个专门介绍比尔盖茨的网站看了一下他的生平,想来看过的人不少。看了他一生的奋斗历程,我们还能说什么呢?
以上是个人的浅见(鉴于本人对delphi,java的无知,对vb.net的初识以及对面象对象技术的部分误解),只是谈谈感受,请勿借题发挥,大作文章。我写这些是防止一些错得离谱的歪论误导初学者。另外我一再鼓励大家研究一下,弄出一些实际的心得来。我因为自身的限制与没有相互的研讨,所以每一篇文章写出来所付出的努力不亚于写一个工程。所以请转载文章的在跟我联系以后 在文中明确按本文结尾处样式注明我的网站名,网址 。这里先向您致谢了!
另外鉴于一些初学者的要求,以及前辈的指点,我在源码中对入门级的知识进行了注解,如果您认为这些对您是多余的,请谅解还有很多人看不懂。
' 本源码出自vb.net中文站 http://vbnetcn.126.com hejianzhong 请尊重作者劳动不要修改此信息(ai.....................)
' ___________________________________________________________________________________________________________________
' -------------------------------------------------------------------------------------------------------------------
' 请首先清添加lable(lbexit,lbpre,lbshow)控件
' 请在属性栏设置这三个lable控件的backcolr(背景色)为system.desktop 即在出现的取色对话框中选择system标签下的desktop颜色
' 下一步,添加axagent控件这个请参考拙作《走近vb.net(九) axagent动画窗体的实现》
' 设置窗体背景图片为sk1.gif 请在 backgroundimage 属性栏设置
' 所有需要的图片用photoshop做出来,如果你不会做可到《vb.net中文论坛》去找我帮你做。
' 设置lbexit的text属性(指在标签上显示的文本)为“退出”
' 设置lbpre的text属性(指在标签上显示的文本)为“窗体”
' 设置lbshow的text属性(指在标签上显示的文本)为“动画”
' 设置所有label的 textalign(文本的排列方式)为center(居中)
option strict off '关闭option strict
imports system.componentmodel '引用族名
imports system.drawing '引用族名
imports system.winforms '引用族名
public class form1
inherits system.winforms.form '继承一个窗体的类
dim genie as agentobjects.iagentctlcharacterex '声明一个agent的对象
const datapath as string = "merlin.acs" '加载动画数据
public frmpre as form1 '声明一个新的窗体,请不要在这里使用初始化的方法或使用new方法
public imindex as short '声明一个整数
public overloads sub new() '每一个类一般都有一个new过程,在新建一个对象(使用new方法)时调用
mybase.new() '直接调用父类的new过程
form1 = me '设定me关键字
initializecomponent() '下面是初始化组件,你也可以在下面使用call方法呼叫一个子过程(见前面的文章)
axagent1.characters.load("merlin", datapath) '装载动画数据
genie = axagent1.characters("merlin") '把agent对象赋于声明的对象,简化书写的过程
genie.languageid = &h409s '设定语音id
call skinregion(form1) '为窗体改变skin(外观)
end sub
overloads sub new(byval strimage as string)
mybase.new() '直接调用父类的new过程
form1 = me '设定me关键字
initializecomponent() '下面是初始化组件,你也可以在下面使用call方法呼叫一个子过程(见前面的文章)
lbexit.visible = false : lbshow.visible = false : lbpre.visible = false : label3.visible = false '新窗体不显示控制
me.top = me.top + 150 '新窗体的位置,top是距离屏幕顶部的高度
call skinregion(form1, strimage) '为窗体改变skin(外观)
end sub
'上面使用overloads定义了两个不同的new过程,在new过程中使用重载可以间接地使一个类产生很好的可重用性,如果你不明白为什么不写一个新的过程,而一定要使用重载
'那么你看看这里的用法,一定会有所启发的。
public overrides sub dispose() '释放资源,终止程序
mybase.dispose() '调用父类的方法
region1.dispose() '释放gdi资源
genie = nothing '释放动画占用的资源
components.dispose() '释放组件占用的资源
end sub
'下面的是非编辑模块,就不用看了
#region " windows form designer generated code "
'required by the windows form designer
private components as system.componentmodel.container
private withevents lbshow as system.winforms.label
private withevents label3 as system.winforms.label
private withevents linklabel3 as system.winforms.linklabel
private withevents lbexit as system.winforms.label
private withevents lbpre as system.winforms.label
private withevents axagent1 as axagentobjects.axagent
dim withevents form1 as system.winforms.form
'note: the following procedure is required by the windows form designer
'it can be modified using the windows form designer.
'do not modify it using the code editor.
private sub initializecomponent()
dim resources as system.resources.resourcemanager = new system.resources.resourcemanager(gettype(form1))
me.components = new system.componentmodel.container()
me.lbpre = new system.winforms.label()
me.lbshow = new system.winforms.label()
me.label3 = new system.winforms.label()
me.axagent1 = new axagentobjects.axagent()
me.linklabel3 = new system.winforms.linklabel()
me.lbexit = new system.winforms.label()
axagent1.begininit()
'@design me.trayheight = 90
'@design me.traylargeicon = false
'@design me.trayautoarrange = true
lbpre.location = new system.drawing.point(32, 72)
lbpre.text = "窗体"
lbpre.size = new system.drawing.size(64, 24)
lbpre.tabindex = 10
lbpre.backcolor = system.drawing.systemcolors.desktop
lbpre.textalign = system.winforms.horizontalalignment.center
lbshow.location = new system.drawing.point(32, 24)
lbshow.text = "动画"
lbshow.size = new system.drawing.size(64, 24)
lbshow.tabindex = 17
lbshow.backcolor = system.drawing.systemcolors.desktop
lbshow.textalign = system.winforms.horizontalalignment.center
label3.location = new system.drawing.point(176, 16)
label3.text = " "
label3.size = new system.drawing.size(176, 88)
label3.borderstyle = system.winforms.borderstyle.fixed3d
label3.tabindex = 16
axagent1.size = new system.drawing.size(56, 40)
axagent1.ocxstate = ctype(resources.getobject("axagent1.ocxstate"), system.winforms.axhost.state)
axagent1.tabindex = 1
axagent1.location = new system.drawing.point(232, 216)
linklabel3.text = "linklabel3"
linklabel3.size = new system.drawing.size(0, 16)
linklabel3.tabindex = 15
linklabel3.tabstop = true
linklabel3.location = new system.drawing.point(352, 88)
lbexit.location = new system.drawing.point(32, 48)
lbexit.text = "退出"
lbexit.size = new system.drawing.size(64, 24)
lbexit.tabindex = 11
lbexit.backcolor = system.drawing.systemcolors.desktop
lbexit.textalign = system.winforms.horizontalalignment.center
me.text = "form1"
me.autoscalebasesize = new system.drawing.size(6, 14)
me.borderstyle = system.winforms.formborderstyle.none
me.backgroundimage = ctype(resources.getobject("$this.backgroundimage"), system.drawing.image)
me.clientsize = new system.drawing.size(392, 288)
me.controls.add(lbshow)
me.controls.add(label3)
me.controls.add(linklabel3)
me.controls.add(lbexit)
me.controls.add(lbpre)
me.controls.add(axagent1)
axagent1.endinit()
end sub
#end region
'上面的是非编辑模块,就不用看了
protected sub lbexit_click(byval sender as object, byval e as system.eventargs)
if frmpre <> nothing then '如果加载了新窗体
frmpre.dispose() '终止新窗体
frmpre = nothing '释放占用的资源
end if
me.dispose() '终止程序
end '彻底终止程序(如果程序无法退出,请使用此关键字)
end sub
'下面是动画过程,在前面的文章中很详细,可以不用看了!
protected sub lbshow_click(byval sender as object, byval e as system.eventargs)
genie.left = 500 '设定agent的位置
genie.show() '使用show方法显示agent
genie.moveto(12, 180) 'moveto方法是移动agent到一个位置,如果加上定时器,你可以很容易地让他在屏幕上 乱跑()
messagebox.show("如果你是mm,请按ctrl+alt+del关闭 " & chr(10) & chr(13) & "您真的要继续吗, 等到我不 动再说!")
genie.speak("ni hao") '发出声音
messagebox.show("你好") '对话框,更多的参数请看以前的相关文章
genie.speak("wo shi hao kan di") '发出声音
messagebox.show("我是好看的") '对话框,更多的参数请看以前的相关文章
genie.speak("ni shi nan kan di") '发出声音
messagebox.show("你是难看的") '对话框,更多的参数请看以前的相关文章
genie.speak("zia jie mimi ") '发出声音
messagebox.show("再见 mm") '对话框,更多的参数请看以前的相关文章
genie.play("wave") '挥手致意
'众mm请勿生气
'上面是开一个小玩笑,如果要真正的读中文,就用下面的
'genie.speak("cnstring ",cnstring.wav) '这里的cnstring就是中文的语音文件
genie.hide() '使用hide方法隐藏agent
end sub
protected sub lbpre_click(byval sender as object, byval e as system.eventargs)
if frmpre <> nothing then frmpre.dispose() '如果新窗体已经存在,清除之
dim strim as string '定义一个字符类型变量
if imindex <> 6 then '反过来想,就是说如果到了6就从头开始,因这我只有这么几张图片了
imindex = imindex + 1
else
imindex = 1 '从头开始
end if
strim = "sk" & imindex.tostring 'tostring的意思是从字符类型转为数字类型
'在vb.net中label控件有image控件一样的作用,不但可以显示文本而且可以显示图片,而在vb6中是只能显示图片的
label3.image = label3.image.fromfile(system.winforms.application.startuppath & "/" & strim & ".gif") 'formfile是从一个路径装载图片
'system.winforms.application.startuppath的意思是当前目录,同vb6中的app.path
'请注意调试过程中使用的当前目录是在bin目录下,在下一个版本有可能更改
frmpre = new form1(strim) '初始化一个实例(对象)
frmpre.visible = true '显示新窗体,如果没有这个只怕你什么也看不到!
end sub
'下面是移动窗体的代码,请参考前面的文章
private sub form1_mousedown(byval eventsender as system.object, byval eventargs as system.winforms.mouseeventargs)
me.capture = false '释放鼠标捕获
me.sendmessage(&ha1s, 2, 0) '这是vb6中最有名的api消息函数
end sub
'下面是鼠标移动_mousemove时发生的事件了
public sub lbpre_mousemove(byval sender as object, byval e as system.winforms.mouseeventargs) handles lbpre.mousemove
lbpre.backcolor = system.drawing.color.black '设置颜色
lbpre.forecolor = system.drawing.color.aliceblue '设置颜色
end sub
public sub lbexit_mousemove(byval sender as object, byval e as system.winforms.mouseeventargs) handles lbexit.mousemove
lbexit.backcolor = system.drawing.color.black '设置颜色
lbexit.forecolor = system.drawing.color.aliceblue '设置颜色
end sub
public sub lbshow_mousemove(byval sender as object, byval e as system.winforms.mouseeventargs) handles lbshow.mousemove
lbshow.backcolor = system.drawing.color.black '设置颜色
lbshow.forecolor = system.drawing.color.aliceblue '设置颜色
end sub
'下面是鼠标按下_mousemove时发生的事件了
public sub lbpre_mousedown(byval sender as object, byval e as system.winforms.mouseeventargs) handles lbpre.mousedown
lbpre.backcolor = system.drawing.color.blue '设置颜色
lbpre.forecolor = system.drawing.color.aliceblue '设置颜色
end sub
public sub lbexit_mousedown(byval sender as object, byval e as system.winforms.mouseeventargs) handles lbexit.mousedown
lbexit.backcolor = system.drawing.color.blue '设置颜色
lbexit.forecolor = system.drawing.color.aliceblue '设置颜色
end sub
public sub lbshow_mousedown(byval sender as object, byval e as system.winforms.mouseeventargs) handles lbshow.mousedown
lbshow.backcolor = system.drawing.color.blue '设置颜色
lbshow.forecolor = system.drawing.color.aliceblue '设置颜色
end sub
public sub lbpre_mouseup(byval sender as object, byval e as system.winforms.mouseeventargs) handles lbpre.mouseup
lbpre.backcolor = system.drawing.color.black '设置颜色
lbpre.forecolor = system.drawing.color.aliceblue '设置颜色
end sub
public sub lbexit_mouseup(byval sender as object, byval e as system.winforms.mouseeventargs) handles lbexit.mouseup
lbexit.backcolor = system.drawing.color.black '设置颜色
lbexit.forecolor = system.drawing.color.aliceblue '设置颜色
end sub
public sub lbshow_mouseup(byval sender as object, byval e as system.winforms.mouseeventargs) handles lbshow.mouseup
lbshow.backcolor = system.drawing.color.black '设置颜色
lbshow.forecolor = system.drawing.color.aliceblue '设置颜色
end sub
'下面是鼠标离开_mouseleave时发生的事件了
public sub lbshow_mouseleave(byval sender as object, byval e as system.eventargs) handles lbshow.mouseleave
lbshow.backcolor = system.drawing.color.blanchedalmond '设置颜色
lbshow.forecolor = system.drawing.color.black '设置颜色
end sub
public sub lbexit_mouseleave(byval sender as object, byval e as system.eventargs) handles lbexit.mouseleave
lbexit.backcolor = system.drawing.color.blanchedalmond '设置颜色
lbexit.forecolor = system.drawing.color.black '设置颜色
end sub
public sub lbpre_mouseleave(byval sender as object, byval e as system.eventargs) handles lbpre.mouseleave
lbpre.backcolor = system.drawing.color.blanchedalmond '设置颜色
lbpre.forecolor = system.drawing.color.black '设置颜色
end sub
end class
'###################################################################################################################
'!!!0001!!!04!!!26!!!!!!
'建议不要修改此模块 以免产生不必要的错误(此代码已相当完美) 如欲修改请先备份 _______vb.net中文站 hejianzhong
'此模块可真接粘贴到您的程序中使用。
'不要删除此信息,我免费为您提供此代码,想得到的回报就是最起码的尊重,虽然最终用户并不能看到,我仍感到欣慰
'!!!0001!!!04!!!26!!!!!!
public module skin
public rect1 as new rectangle(0, 0, 0, 0)
public region1 as new system.drawing.region(rect1)
public sub skinregion(byval skform as form, optional byval skinnaskform as string = nothing)
dim x, y, transpix, opacipix, bgwidth, bgheight as integer
dim rect2 as new rectangle()
dim firargb as integer = getpixel(skform, 1, 1)
dim region1 as new system.drawing.region(rect1)
rect1 = nothing
'skform.visible = false
if skinnaskform <> nothing then skform.backgroundimage = skform.backgroundimage.fromfile(system.winforms.application.startuppath & "/" & skinnaskform & ".gif")
bgwidth = skform.backgroundimage.width
bgheight = skform.backgroundimage.height
skform.height = bgheight
skform.width = bgwidth
for y = 1 to bgheight - 1 '这里参考了vb6中的扫描方法,请参考相关资料
x = 0
do
x = x + 1
while (getpixel(skform, x, y) = firargb) and (x < bgwidth)
x = x + 1
end while
transpix = x
while (getpixel(skform, x, y) <> firargb) and (x < bgwidth)
x = x + 1
end while
opacipix = x - 1
if transpix <= opacipix then
rect2 = rect2.fromltrb(transpix - 1, y - 1, opacipix, y)
region1.union(rect2)
rect2 = nothing
end if
loop until x >= bgwidth
next y
skform.region = region1
skform.refresh()
'skform.visible = true
end sub
public function getpixel(byval skform as form, byval x as integer, byval y as integer) as integer
dim pm as bitmap = skform.backgroundimage
try
return pm.getpixel(x, y).toargb
catch
exit function
end try
end function
end module