




已阅读5页,还剩25页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
跟我学做c#皮肤美化(一) -概述与导航每每看着QQ,360等等那些软件漂亮的外衣时,你是不是总是在想我的软件什么时候才能穿上这么漂亮的外衣呢?不过现在当你看到这篇文章的时候不必再发出这样的疑问了,因为接下来我会带领大家一步一步”画出”这些漂亮的外衣!在写这系列文章之前要感谢博客园的苏飞,我也是看来他的文章后才开始接触皮肤的制作的!我写的这系列文章中有和苏飞相同的地方,也有不同的地方。还有因为我想使这个系列的文章能使刚刚接触皮肤编程的初学者都能跟着我一步一步的实现皮肤的制作,所以我会讲解的很详细很详细。呵呵,不知道这点算不算和苏飞大哥的一点小小的区别呢?!另外我写的这一系列暂时还不会包括换肤功能在里面,而且控件的健壮性,功能的全面性上也可能有不足的地方,希望大家包涵,毕竟我也是刚刚接触皮肤制作这一方面的内容,写的不好或者难免有一些错误的地方还请大家包涵。当然,如果大家有好的建议或者是想和我交流这方面的内容,我也很乐意。我的邮箱接下来所有的控件我都会编写在一个用户控件库QLFUI中,以后的软件中想要应用这些皮肤只要简单的继承或者使用控件就是了。整个控件库可以简单的分成两大类:用户控件类和窗体类。用户控件类就是普通的用户控件比如说Button控件,让其不再单调!窗体类就是写一个带有皮肤的窗体,以后其他的窗体只要继承一下就会自动带有了皮肤(多方便)。说了这么多还是先让大家看看最终做出来的效果图吧!以后我讲解的内容大体是这个样子的:(因为时间原因可以会有有一些控件会增加或减少,不过我会尽量都讲解全的) 控件类: -Button控件的制作 -CheckBox控件的制作 -RadioButton控件的制作窗体类: -MainForm窗体的制作 (只要继承这个窗体基本上就能披上最简单的外衣了) 本文归qianlifeng和如鹏网所共有,装载请注明出处,谢谢!跟我学做c#皮肤美化(二) -Button控件的制作概述与导航先来看看我们最终要做的效果图(分别对应普通、悬停、按下时的状态):下面就开始正式做。首先让我们新建一个控件库项目,命名为QLFUI。如图:然后将默认的UserControl1重命名为 Button。接下来,我们就要在这上面来做文章了。先来稍稍设置一下,让这个用户控件看起来更像一个按钮吧!Button的Size: 78,30 BackgroundImageLayout:Stretch然后拖一个label控件到这个用户控件上,并设置label1的属性为AutoSize:false , Dock:fill, TextAlign:MiddleCenter, BackColor: Transparent, Font: 宋体, 9pt这几个属性。好了,是不是开始像一个按钮了呢?哦,差点忘了最后还要将整个控件(BUTTON)的背景色设置为Trasparent透明色。因为如果不设置成透明色那么透明的图片下面就会显示出button的背景色(默认灰色),不好看。好了,现在样子的已经大概有了,接下来就是编程了。先贴代码,然后我一个一个解释: DefaultEvent(Click) public partial class Button : UserControl #region 变量 /三种不同状态下的图片 Image _normalImage = null; Image _moveImage = null; Image _downImage = null; #endregion #region 属性 Category(QLFSkinDll) public Image NormalImage get return _normalImage; set _normalImage = value; Category(QLFSkinDll) public Image DownImage get return _downImage; set _downImage = value; Category(QLFSkinDll) public Image MoveImage get return _moveImage; set _moveImage = value; Category(QLFSkinDll) public string Caption get return this.label1.Text; /控件运行时会自动运行get方法得到值 set this.label1.Text = value; #endregion #region 构造函数 public Button() this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true); /默认的是自带的图片样式,如果使用该按钮则必须手工指定当前按钮你想要的背景图片 _normalImage = Image.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(QLFUI.Res.button.btnnomal.bmp); _moveImage = Image.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(QLFUI.Res.button.btnfore.bmp); _downImage = Image.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(QLFUI.Res.button.btndown.bmp); MakeTransparent(_normalImage); MakeTransparent(_moveImage); MakeTransparent(_downImage); InitializeComponent(); this.BackgroundImage = _normalImage; #endregion #region 辅助函数 private void MakeTransparent(Image image) Bitmap bitmap = image as Bitmap; bitmap.MakeTransparent(Color.FromArgb(255, 0, 255); #endregion #region 事件 private void label1_MouseEnter(object sender, EventArgs e) this.BackgroundImage = _moveImage; private void label1_MouseDown(object sender, MouseEventArgs e) this.BackgroundImage = _downImage; private void label1_MouseLeave(object sender, EventArgs e) this.BackgroundImage = _normalImage; private void label1_MouseUp(object sender, MouseEventArgs e) this.BackgroundImage = _normalImage; private void label1_Click(object sender, EventArgs e) this.OnClick(e); #endregion 先看第一句:DefaultEvent(Click),这句话是什么意思呢?我们知道平常我们拖一个按钮后,在设计模式下双击这个按钮就会自动产生这个按钮的Click事件。这个默认的Click事件从哪里来的呢,毫无疑问就是DefaultEvent(Click)这一句来设置的啦!这里默认的是Click事件,如果写成DefaultEvent(MouseEnter)就是MouseEnter事件啦!接下来的四句分别定义了按钮三种不同状态下的bitmap。下面的四个属性分别是三种不同状态下Image的属性和按钮的文字属性Caption,大家一看应该就明白。具体要解释的就是Category(QLFSkinDll)。这句话的意思是将这些属性分类,看个图片大家就都明白了:以后在项目中设置属性时,我们定义的属性就自动分类在QLFSkinDll下面了。接下来是构造函数:public Button()中的内容。第一句是开始了窗体的双缓冲。双缓冲的意思就是现在内容中将图像画好了然后再显示到界面上去。在c#中图像一多最怕的就是图像闪烁的问题,开启了双缓冲虽说不能完全避免图像闪烁,但起码也能有一定的效果,我们就先开着吧 !接下来的三句就是给三个状态的图像赋值了,这里我是把图像嵌入进来了,并没有放置在外部。要应用嵌入的资源分两步走:第一步在项目中点击图片的属性,然后将“生成操作”改为嵌入的资源。第二步应用就是我们用到的代码啦:Assembly.GetExecutingAssembly().GetManifestResourceStream(QLFUI.Res.button.btnnomal.bmp),这句话前面的照写,后面的路径规则是“命名空间+文件夹名+你的文件名+文件名后缀”,当然如果你的文件直接放在项目下就没有文件夹名了。聪明的大家应该明白吧?呵呵!其中我们要用到的文件大家可以从我给的项目例子中复制。接下来的MakeTransparent(_normalImage);MakeTransparent(_moveImage);MakeTransparent(_downImage);三句先不看,可以注释掉,下面会讲解它的作用的。第八句InitializeComponent()是系统自带的初始化控件一些代码,我们不用去管它。最后一句this.BackgroundImage = _normalImage;就是设置按钮的其实的图片的样子啦!好啦,写了这么久,咱们还是先来看看能运行出个什么样子出来吧!看看目前的状态下,它离我们的目标还差多远!见图:从图中我们可以看到明显的一个问题,就是按钮的边缘有粉红色。而且如果你也正好做到这里也会发现鼠标经过按钮时,按钮没有任何反应(废话,我们还什么都没做呢)。好了,接下来就有目标了,解决这两个问题我们这个按钮美化的就差不多了!先来解决第一个问题,去掉粉红色。我们需要用到Bitmap的一个函数MakeTransparent(Color),这个函数的作用是使指定的颜色对 Bitmap 透明。也就是说我们只要将这个函数的Color设置为我们需要去掉的粉红色不就行了?!继续看代码,我们先写一个函数private void MakeTransparent(Image image),这个函数的作用就是将传进来的图片的指定的颜色进行透明处理。函数里就两句话,第一句话先将Image转为Bitmap。第二句话就是进行透明处理,这里的Color.FromArgb(255, 0, 255)就是我们要去的粉红色啦。那什么时候进行去色呢?毫无疑问,当然是在给三种状态赋值后紧接着就去色啦!所以我们在构造函数中的5,6,7句加上透明处理。(倒过来讲这个作用,大家习惯不习惯呢?)好了,现在我们再来运行一下:看图:呵呵,正如预料的那样,粉红色没有了(图中的灰色其实是透明的,只要在另外一个项目中引用一下就知道了),第一个问题解决!再来看第二个问题,要实现按钮的变色肯定是跟鼠标的事件相关啦,比如说鼠标一进入按钮的范围之内我们就让按钮的背景改变,按下和离开按钮的时候也响应的改变背景。所以我们用到这四个事件(注意,事件都是label1的事件,因为我们将label覆盖在按钮上,所以我们点击的其实是label1):MouseEnter,MouseDown, MouseLeave, MouseUp。具体的事件里面执行的代码也很简单,就是更换按钮的背景图片。好了,让我们再运行一下看看效果:OK!两个问题都解决了,我们的按钮运行的好像也很正常!鼠标进入,移出,按下的时候也会变换背景!但是,如果你另外建一个项目,并双击产生点击事件并编写相应代码时就会发现点击事件没作用了。多么郁闷的一件事情啊,点击事件都没作用了,我们还要这个按钮干嘛啊!别急,让我们来解决它。首先要明白的就是我们在其他项目中引用的这个的button控件的点击事件是整个用户控件的点击事件(还记得我们在整个button类的上方设置了默认的点击事件吗?),而当我们去点击按钮时我们实际点击的只是label1。问题很明了了,我们点击的是label1,设置的却是整个用户控件的事件,当然触发不了事件了。既然问题已经搞明白了,下面就去解决它。继续看代码:既然我们点击的是label1那么我们就在label1的点击事件中做文章,如代码所示,我们在label1的点击事件中触发了整个类(this)的onclick事件,然后这个onclick会去找相应的类的click事件,就是我们在其他项目中直接双击的那个事件啦!OK,至此这个按钮空间的美化就做好了看看效果吧!本文归qianlifeng和如鹏网所共有,转载请注明出处,谢谢!跟我学做c#皮肤美化(三) -CheckBox控件的制作概述与导航先看最终的效果图:或许大家已经猜出来我这个checkbox是怎么实现的吧?不错,就是前面的框是一个图片,后面的文字是label。经过前面button的讲解我想有能力的人完全可以单独制作出来。还不熟悉的现在就开始跟我一步一步的来吧!GO。打开上次的项目QLFUI,新建一个名为CheckBox的用户控件。如图同样的,我们先设置一下,使其看起来像一个checkbox。具体设置如下:CheckBox控件,Size:70,13 MinimumSize:70,13 BackColor:Transparent 然后拖一个picturebox并设置以下属性:Size:13,13 Location:0,0 , BackgroundImageLayout:Stretch再拖一个label上来设置以下属性:AutoSize:false Location:15,0 Size:50:13最终应该是这个样子:好了,样子有了接下来就是编码了!还是一样,先贴代码,然后我一句一句解释:【代码】CheckBox类的开头我定义了四个image的变量用来分别表示选中和未选中状态下鼠标的移进移出的图像!接下来的bool check变量就是代表该控件是否已经被选中(checkbox最重要的属性就是这个了吧?!)。接下来,就是2个属性了,我代码里面也注释的很清楚。这里只有两个地方需要解释一下:1, Description(显示的文字)是干什么的?看图你就明白了,这下明白了吧?对,就是用来解释你这个属性的(别人用你的控件都不知道什么意思,我们当然要适当的注释一下啦)!第二点要注意的就是,在设置Checked这个属性的时候要注意更换图片,选中和不选中的时候的图片不同!其他的属性我想大家经过button控件的讲解已经能很容易看明白里面的内容了。这里就不再罗嗦了。接下来看构造函数。第一句this.SetStyle我就不说了,不懂可以看button里面的讲解。接下来的六句话就是得到四种状态下的图片了,不过得到的好像不是很简单!这是因为我们的原始图片是这样的看见没有,图片是画在一张图片中的,所以我们需要使用bitmap的clone函数将不同矩形区域下的图片给截取出来。这样解释大家应该明白了Clone的意思了吧。剩下的两句不罗嗦了,和button里面的一样。接下来该做什么呢,根据制作button控件的经验,我们就该开始编写鼠标的各种事件了,并在这些事件中处理不同的背景。开始。事件里面我们一共写了三个事件,与button不同的是这里并没有MouseUp事件,为什么呢?因为不需要,哈哈!开个玩笑,因为背景对于mouseup事件并不需要改变!不过如果你高兴当然可以加上去。事件里面的内容也很简单,就是根据当前check的状态,然后依据鼠标的状态更换picturebox的背景。很简单,我就不多说了。另外要注意的就是把label的对应的事件也与生成的鼠标事件关联起来(怎么关联?直接在label的属性的对应事件里面选择那些个已经存在的事件就行了)好了,来运行一下看看效果吧!运行的好像还不错呢,我们设置的属性都能成功应用。不过,如果我们在其他项目中引用这个控件并将CheckBoxText属性设置的稍微长一些,我们就会发现有一部分文字显示不出来了。这是因为我们的控件的宽度是固定的70个像素,当label的长度更改时超过整个控件长度的部分就会被隐藏。所以我们还需要在label的内容更改时同时改变整个控件的长度以完全显示文字的内容。看代码:我们写一个label文字更改时的事件label1_TextChanged,当label中的文字改变时就会触发这个事件。事件里面的第一句就是根据文字的个数计算label需要显示的宽度。字体的宽度是用(int)this.Font.Size+ 5来得到的(这个宽度我测试的基本能得到要求),得到了label的宽度我们只要将这个宽度加20(图片的宽度)就大概得到了整个控件的宽度,这样文字就能正常显示了。当然为了以防万一我们还要加一个事件(基本用不上,不过保险嘛,呵呵)就是CheckBox SizeChanged事件了(见代码),当我们手动拉动checkbox时手动改变label的长度,这样即使上面一个事件打不到要求有些文字没有显示出来,我们只要手动拖一下checkbox的长度那文字肯定就能显示出来了。OK,checkbox控件制作完成。本文归qianlifeng和如鹏网所共有,转载请注明出处,谢谢!跟我学做c#皮肤美化(四) -MainForm窗体的制作1做了许多的用户控件,现在让我们换换口味,开始窗体的制作吧!这个窗体的制作可以说是整个美化中比较重要的一部分,因为她显示的是整个美化的窗体。而且内容也比较多,所以我会分几篇把她讲完,而且窗体制作的时候会和前面控件将的时候不一样,我不会在第一篇把最后的代码就放出来,而是希望做成跟着我一起一个版本一版本的完成不断的修改不断的发现问题并去完善。这也是我做这个时候的一个思路:先做一个大致的框架,然后在其基础上增加功能或者发现问题,最后完成功能和解决问题。不知道大家感觉这样是不是更好一点呢?好了,不多说了,先看最终的效果图:怎么样?是不是有点心动了?下面就正式开始吧!首先在以前的项目QLFUI上新建一个窗体(不是用户控件咯)并重新命名为MainForm。如图:接着来设置几个属性,如下:FormBorderStyle:NoneSize:300,300接下来就是用picturebox 和 panel来布局了。这一部分可能比较繁琐。 首先总体介绍一下大概的布局。见图:因为我们做的窗体是圆角的,所以窗体的四个角上(红色)我们会放上四个picturebox。标题栏和状态栏(蓝色)会是两个panel。二个边框线(绿色)是两个picturebox。最后的主体部分(棕色)是一个panel。说完了大体的布局,下面就来动手做啦。一个一个来:左上角Name:ptbtlLocation:0,0Size:10,31上方的标题栏Modifiers:Protected;Name:paneltLocation:10,0Size:280,31右上角Name:ptbtrLocation:290,0Size:10,31左侧的边框线Name:ptbmlLocation:0,31Size:2,232主窗体部分Modifiers:Protected;BackgroundImageLayout: StretchName:panelmLocation:2,31Size:296,232右侧的边框线Name:ptbmrLocation:298,31Size:2,232左下角Name:ptbblLocation:0,263Size:10,37下方的状态栏Modifiers:Protected;Name:panelbLocation:10,263Size:280,37右下角Name:ptbbrLocation:290,263Size:10,37最后还有右上方的三个按钮可不要忘记了,注意按钮都是在panelt里面设置的而且这三个按钮都是我们前面做的按钮哦,终于派上用场啦!最小化按钮Caption:0Name:btminLocation:180,0Size:31,22最大化按钮Caption:0Name:btmaxLocation:211,0Size:31,22关闭按钮Caption:0Name:btcloseLocation:243,0Size:37,22还原按钮Caption:0Name:btresLocation:211,-30Size:31,22最后再加上一个label作为窗体的标题Name:lbtitleLocation:6,9Size:35,12BackColor:Transparent呼,终于结束了!不知道大家有没有晕乎乎的感觉,反正我是有点儿了,呵呵。最后的布局图应该是这个样子滴:老规矩,界面的事情弄完了,现在开始编码了。上代码:【代码】变量部分:变量我在代码里都注明了其作用。这里只会说说为什么要这些变量。首先needMaxbt和needMinbt是指示该窗体是否需要最大化或最小化按钮的,毕竟窗体有很多种吧,比如说一个消息框就没必要用最大化按钮吧,所以我们这边也就设置的灵活一点,下面会将这两个变量封装成属性以便在设计模式下方便的选择。接下来的四个变量orginWidth;orginHeight;X;Y;都是用来记录窗体的信息的,分别是窗体的宽,高,x坐标值,y坐标值。为什么要设置一些变量呢?说起来也比较郁闷,这些都是为了窗口的最大化和还原准备的。可能有人会问了最大化不就一句话嘛 this.WindowState = FormWindowState.Maximized;何必还要这些个变量呢。关键郁闷就郁闷在这里啦,假如直接用这一句话最后窗体虽然也能最大化可就是右上角的一小段边框线莫名其妙的没有了,如图:搞了半天也不明白。最后不得已才想出个自己手动最大化的方法来,讲到具体的地方再和大家说吧。接下来我又定义了一个枚举stat,用来表示窗体的三种状态,正常,最大化,最小化。下面的那个st就是枚举的一个变量,默认的是normal也就是窗体正常显示啦。变量讲完了接下来讲属性。第一个属性Size。这个属性有点特别,因为它里面有一个new关键字,为什么呢?因为Size这个属性在设计器里面原来就有了所以我们加上这个new就相当于重写这个属性啦。这个属性里面我只写了一个get方法。我写这个属性的目的就是要将设计器下原来的size属性隐藏(看见了上面的那个Browsable(false)吗?就是用它来隐藏的),这样别人如果要设置窗体的大小就得修改我们下面提到的BorderWidth和BorderHeight了。那为什么要隐藏原来的实现呢,这是因为当我们设置窗体大小的时候窗体上相应的picturebox和panel也需要相应的改变,这里面就需要设置很多的东西。所以我们另外设置属性来完成这些工作。第二个属性BorderWidth。毫无疑问,这个就是用来设置窗体的宽度的啦。CategoryAttribute(QLFSkinDll), Description(设置窗体宽度)我就不讲了,前面已经提到过了。里面的get也很简单就是返回当前窗口的宽度。重点讲解set。首先我们用if语句限制了用户设置的值不能小于180像素,因为当小于180个像素的时候,界面上的最小化按钮就有将标题都“挤”没了。所以最小180啦。接下来如果用户设置的值和设置前的不一样,那么就开始一下一连串的设置了。我们用newwidth把用户设置的这个值记录下来,下面要用到。然后紧接着就改变窗体的大小。如果仅仅这样就结束了你会发现panel,picturebox那些控件的位置都没有动,这不是我们想要的。接下来就是设置这些控件的位置啦。一开始我做的时候也被这些设置搞乱了,最后我用的相对位置才搞清楚的。什么叫相对位置,打比方说无论你窗体的大小怎么变化,关闭按钮总是在距窗体右侧57个像素的位置。按照这个一句来做我们也会发现其他的控件都是一样的。于是一个一个的设置,找相对距离。当然我现在已经找好了,大家就不必再麻烦一个一个找一遍来了。至此,BorderWidth属性讲完。第三个属性BorderHeight。经过上面BorderWidth属性的讲解,我想height属性就不要我再讲解了,都是一样的道理。第四个属性FormTitle。看意思就应该看出来了吧,这个是用来设置窗体的标题的。这个在前面讲到的button,checkbox等控件里也有差不多的属性,这里也不就不罗嗦了。第五个属性NeedMax。这个属性是用来指定窗体是否需要最大化按钮的。怎么指定呢?看代码。如果用户设置的是false也就是不需要,那我们就会将btmax按钮向上移动50个像素(this.btmax.Top = -50;)同时btmin按钮顶替最大化按钮的位置(this.btmin.Left = this.Width - 89;),怎么样?是不是很简单就实现了按钮的隐藏呢?第六个属性NeedMin。用法参见上面的第五个属性。接下来讲构造函数。前四句就不要我讲了吧,前面也遇到过就是开启双缓冲和系统默认的是初始化控件。剩下的N多的语句都是用来加载图片的,其实也没啥好说的要说的点前面控件制作的时候也已经介绍过了,呵呵。说一下最后一句的意思吧。因为我们的窗体默认是没有状态栏什么的,所以也就决定了当窗体最小化后右击任务栏上的窗体没有菜单弹出来。如果要实现这个功能就需要借助系统API来完成了。不过在c#里面是不可以直接调用API的,需要实现声明一下。在这里就偷懒一下直接将别人封装好的API类(win32.cs)。一句话完成这个功能:Win32.SetWindowLong(this.Handle, -16, Win32.WS_SYSMENU + Win32.WS_MINIMIZEBOX);好了,来运行看看吧:发现问题:大体的模样是出现了。不过也许大家看图看不清楚,图中被我画圈的其实都不是透明的,而是灰色的。我们在下一篇文章的讲解中将解决或实现以下几个问题:1. 消除图中不透明的地方2. 实现标题栏的拖动3. 实现窗体的最大化,最小化,关闭功能。敬请期待。本文归qianlifeng和如鹏网所共有,转载请注明出处,谢谢!跟我学做c#皮肤美化(五) -MainForm窗体的制作2先来回顾一下我们上次遗留的问题1. 消除图中不透明的地方2. 实现标题栏的拖动3. 实现窗体的最大化,最小化,关闭功能。下面就来一个一个解决。解决不透明的问题:首先为什么会有灰色的出现呢。不难想到这些灰色就是Picturebox的背景色。边角上的图片对粉红色透明了,但却露出了背景的颜色。知道了原因就好了解决了,就是我们需要将这一块的背景色给透明掉。有人说可以讲picturebox的背景色设置为透明的啊。不错,是可以,但整个窗体的背景色呢?picturebox下面不还是有整个被覆盖的窗体的嘛!窗体是不能像用户控件那样背景色设置为透明的,不过却有一个属性TransparencyKey可以间接的为我们解决这个问题。这个属性的作用是这样的,当这个属性设置为某一种颜色后,那该窗体上的所有的这种颜色将都变为透明色。所以我们只需将TransparencyKey的颜色和窗体的背景色设置成一样,那么背景色不就自动透明了嘛!在这里我们将所有控件的背景色和TransparencyKey都设置成系统里面的Info颜色(这个颜色你可以自己指定,不过不建议是原来的Control色,因为这样后你再添加一个普通的控件,那么这个控件的一部分也会被透明掉)实现标题栏的拖动因为我们的窗体是没有状态栏的,所以当我们想移动窗口的时候发现怎么也”移不动”(不是有个笑话的嘛“中国移不动“,呵呵)。要解决这个问题还是需要借助API来完成。那如何知道别人需要移动窗体呢?这里我们就通过MouseDown这个事件来判断。即如果用户在特定的区域内按下了鼠标左键,那么我们就认为用户需要移动客户端了。这个时候我们调用相应的API向系统通知(SendMessage)让系统做出响应。为了效果好一点,我们将状态栏那一行的所有的MouseDown事件都用这个方法。于是现在我们运行一下看看能否移动窗体。很不错嘛!又是一个问题解决了,现在只要将右上方的三个按钮的功能完成那这个窗体就算基本完成了啦。好了,我们继续。 要处理按钮的事件,毫无疑问我们在设计模式中双击对应的按钮,然后处理。这里还要提一下的就是我们需要在这些事件的每个方法钱加一个virtual让这些个方法可以被重写。道理很简单,假如我按关闭按钮的时候不想其直接关闭而是先弹出对话框提醒一下用户怎么办呢?总不能让用这个控件的人再去修改这个皮肤控件吧,最好的办法就是可以让他们重写按钮的click事件,他们想干嘛干嘛,不想有其他的功能只要不重写就是了。好了开始说最小化功能吧。很简单,一句话搞定:this.WindowState = FormWindowState.Minimized;然后是关闭按钮,还是一句话的事情:this.close();呵呵貌似这两个功能真简单那!原本最大化也不复杂的,可是遇到了前面说到的那个问题,我们就知道想点儿其他的办法啦。看代码:当用户点击最大化按钮的时候我们先将最大化按钮上移隐藏,然后将还原按钮降下(还记得我们一开始给他设置的位置是-30吗?),然后我们最大化之前就先记录窗体的大小和位置(就是最开始赋值的那四句话)信息便于后面的还原。接下来的四句就是咱们手动来制造一种窗体最大化的状态啦,首先位置肯定在左上角。然后大小应该就是用户电脑屏幕客户区的大小,这个大小我是用Screen.PrimaryScreen.WorkingArea这个函数得到的。状态设置完了我们只要改一下窗体的状态标识st为stat.Max。然后当用户想还原的时候我们只要在btres的click的点击事件中做一下刚才那个动作的反就行了。怎么样,是不是也不难啊!Ok,最后看一下运行效果:发现问题:终于是做好了。不过假如你也实际跟我动手做出了一个,你或许会发现以下一些问题:1. 点击最大化的时候反应好像有点慢,意思就是大概要过个这个半秒钟才会最大化。 2. 还有一个问题就是从最小化状态下恢复到最大化状态,窗体左上角会有闪烁现象(闪的实在太快了,没办法截图啊,大家可以应用下我下面上传的DLL运行下就知道了)。我们本来就是想美化窗口,但是如果这些个问题一来实在是给人感觉不好,甚至还不如不美化。在下一篇中我将会带领大家解决这个问题。 3. 我们的窗体位置虽然能移动了,不过大小还不能拖动。在下一篇中我会带领大家解决这些问题,敬请期待!本文归qianlifeng和如鹏网所共有,转载请注明出处,谢谢!跟我学做c#皮肤美化(六) -MainForm窗体的制作3在上一篇中,我们虽然已经做出界面大概的样子出来了。不过还是存在着一些问题,包括运行缓慢和闪烁等一些问题。那么下面就让我们一起来解决吧。先来说说闪烁和缓慢的问题。我认为最主要的还是由于我们设置了transparent所造成的。网上的一些解释是这样的,当窗体显示时我们设置的透明部分在显示的时候会先呈现出黑色然后再在上面显示图片。这样一来控件一多我们很容易就看见了。不管解释的对不对,反正我们知道设置窗体的transparent肯定是对窗体的显示有一些负面影响的(接下来的窗体避免设置transparent也确实证明了这一点)。既然是这个transparent“搞的鬼”,那能不能不用它来实现窗体的透明呢?答案是我还没找到。但是不代表这个问题解决不了。我们不妨先来回忆一下我们为什么要使用这个transparent。还记得下面这张图吧?我们运用transparent就是为了解决四个角上透明度的问题。现在我们不想使用transparent怎么办呢?其实简单的换个思路就行了。我们为什么非要那边是透明的啊,它不透明就让它不透明呗,我们只要在显示的时候“切掉”它不就行了。也就是说我们自己先要在原有的窗口内画出一个圆矩形出来然后四个直角就自然切掉不要了。那怎么画怎么切?看下面的系统API,第一个是用来画的,而第二个当然就是用来切的啦。MSDN上面已经给我们解释的很清楚了。CreateRoundRectRgn前面四个参数分别是左上角和右下角的坐标,我们在画的时候只需要将其起点设置为(1,1)终点设置为(this.width-1,this.height-1)就能得到一个外边距相当于1的矩形啦。如图:图中的蓝色部分就是我们需要省略的部分。最后两个参数分别是椭圆形的宽高(其实就是我们切的圆角的弧度啦)。这个函数执行成功了就会返回切好的区域的句柄,然后我们只要在SetWindowRgn中拿到这个handle就可以把我们需要的圆矩形部分切下来啦。可是好像又有一个问题那!到底该什么时候切呢?铅笔,刀都准备好了,但总不能让他傻傻站那儿不知道什么时候动手吧!时机很重要。我们应该让他在窗体大小变化的时候就行动一次,这样才能保证每次窗体大小变化(比如说最大化)后还能保证是圆角矩形。好啦,原理讲好了,现在该真正动手干活咯。首先第一步就是切掉原来窗体的transparent,这个就不用我多说了吧!会设置还不会取消嘛!接着就重写一个OnResize函数就可以啦。两句话搞定, protected override void OnResize(EventArgs e) base.OnResize(e); int Rgn = Win32.CreateRoundRectRgn(1, 1, this.Width - 1, this.Height - 1, 7, 7); Win32.SetWindowRgn(this.Handle, Rgn, true); 好了,来运行一下看看效果吧!现在我们再来最大化,最小化还原看看效果确实比上次好多
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025至2030中国皮卡通行证行业深度研究及发展前景投资评估分析
- 2025至2030中国男性不育行业产业运行态势及投资规划深度研究报告
- 2025至2030中国电视媒体行业发展研究与产业战略规划分析评估报告
- 2025至2030中国电动调节仪表行业产业运行态势及投资规划深度研究报告
- 2025至2030中国生猪养殖行业市场发展分析及投资发展战略前景预测报告
- 2025至2030中国牲猪饲料行业发展研究与产业战略规划分析评估报告
- 工厂秋季消防培训
- 世界环保日培训课件
- 从国家层面探讨儿童的心理健康教育与疏导机制
- 基于心理测评的学生个性化教学方案设计
- 国家开放大学药学考试试题及答案
- SJG 130 – 2023《混凝土模块化建筑技术规程》
- 2025厌氧好氧缺氧(AOA)活性污泥法设计标准
- 2025年采供血机构上岗证考试试题
- DB37-T5321-2025 居住建筑装配式内装修技术标准
- 《视网膜色素变性》课件示例
- 2025-2030中国火箭发动机行业市场发展趋势与前景展望战略分析研究报告
- 自卸车安全培训
- T-CHSA 090-2024 年轻恒牙根尖诱导成形术操作专家共识
- 区块链在虚拟电厂分布式能源管理中的应用-全面剖析
- 贵州企业招聘2025贵州贵旅国际旅行服务有限公司招聘笔试参考题库附带答案详解
评论
0/150
提交评论