C#中窗体的美化窗体圆角的处理.doc_第1页
C#中窗体的美化窗体圆角的处理.doc_第2页
C#中窗体的美化窗体圆角的处理.doc_第3页
C#中窗体的美化窗体圆角的处理.doc_第4页
C#中窗体的美化窗体圆角的处理.doc_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C#中窗体Form的美化 VS足够强大,强大到只需动动鼠标就可以写出个基本的界面出来,但是其自带的控件都是千篇一律的样式,对于追求完美的我而言,实在是忍不下去了,只好自己亲自动手对其进行改造-继承已有的控件,再对其相关的消息或事件进行处理。窗体Form作为界面的主体部分,必先对其进行美化,在窗体自绘的过程中,需要使用到GDI+,如若对GDI+不是很了解的同学可移步我的CSDN博客或者搜索下相关的介绍。这篇文章将要介绍到的内容: 窗体圆角的处理 无边框窗体大小的改变与移动 窗体边框的绘制与边框阴影的实现 系统按钮的绘制与事件处理 窗体标题栏的绘制 解决窗体闪烁的问题实现效果演示:代码下载一:窗体圆角的处理 对于无边框窗体圆角矩形的处理,我这里采用的是使用API函数CreateRoundRectRgn,相比于自己用GDI+写的处理圆角的函数,效果要稍微好点,至少线条在圆角处过渡的比较平滑,为了便于复用,我把其封装到窗体自绘辅助类RenderHlper的SetFormRoundRectRgn函数中:View Code / / 设置窗体的圆角矩形 / / 需要设置的窗体 / 圆角矩形的半径 public static void SetFormRoundRectRgn(Form form, int rgnRadius) int hRgn = 0; hRgn = Win32.CreateRoundRectRgn(0, 0, form.Width + 1, form.Height + 1, rgnRadius, rgnRadius); Win32.SetWindowRgn(form.Handle, hRgn, true); Win32.DeleteObject(hRgn); 此处需要把所需要的API函数引用到类Win32中,引用的时候注意添加System.Runtime.InteropServices 命名空间:View Code DllImport(gdi32.dll) public static extern int CreateRoundRectRgn(int x1, int y1, int x2, int y2, int x3, int y3); DllImport(user32.dll) public static extern int SetWindowRgn(IntPtr hwnd, int hRgn, Boolean bRedraw); DllImport(gdi32.dll, EntryPoint = DeleteObject, CharSet = CharSet.Ansi) public static extern int DeleteObject(int hObject);重写窗体的OnSizeChanged事件,并在此事件中调用SetFormRoundRectRgn,此处的Radius参数为定义的窗体圆角半径属性:View Code protected override void OnSizeChanged(EventArgs e) base.OnSizeChanged(e); RenderHelper.SetFormRoundRectRgn(this, Radius); 二:无边框窗体大小的改变与移动 当把窗体的FormBorderStyle属性调整为FormBorderStyle.None时,此时,窗体的大小改变不了,同时窗体不能移动。要想实现无边框窗体大小的改变与移动,可采用如下方法:(1)重写窗体的过程WndProc:主要是对WM_NCHITTEST消息进行处理,根据事件的发生位置来进行不同方向箭头的调整,窗体大小改变与移动的函数:View Code /调整窗体大小 private void WmNcHitTest(ref Message m) int wparam = m.LParam.ToInt32(); Point mouseLocation = new Point(RenderHelper.LOWORD(wparam),RenderHelper.HIWORD(wparam); mouseLocation = PointToClient(mouseLocation); if (WindowState != FormWindowState.Maximized ) if (CanResize = true) if (mouseLocation.X 5 & mouseLocation.Y Width - 5 & mouseLocation.Y 5) m.Result = new IntPtr(Win32.HTTOPRIGHT); return; if (mouseLocation.X Height - 5) m.Result = new IntPtr(Win32.HTBOTTOMLEFT); return; if (mouseLocation.X Width - 5 & mouseLocation.Y Height - 5) m.Result = new IntPtr(Win32.HTBOTTOMRIGHT); return; if (mouseLocation.Y Height - 3) m.Result = new IntPtr(Win32.HTBOTTOM); return; if (mouseLocation.X Width - 3) m.Result = new IntPtr(Win32.HTRIGHT); return; m.Result = new IntPtr(Win32.HTCAPTION); 重写窗体过程:View Code protected override void WndProc(ref Message m) switch (m.Msg) case Win32.WM_NCHITTEST: WmNcHitTest(ref m); break; default: base.WndProc(ref m); break; (2)对于仅仅只想实现窗体的移动而不改变窗体的大小,可以重写OnMouseDown事件中发送HTCAPTION消息来实现无边框窗体的移动,具体的实现代码如下:View Code / / 移动窗体 / public static void MoveWindow(Form form) Win32.ReleaseCapture(); Win32.SendMessage(form.Handle, Win32.WM_NCLBUTTONDOWN, Win32.HTCAPTION, 0); 调用窗体移动函数:View Code protected override void OnMouseDown(MouseEventArgs e) base.OnMouseDown(e); if (e.Button = MouseButtons.Left) Render.MoveWindow(this); 三:窗体边框的绘制与边框阴影的实现边框的绘制:边框的绘制使用用PS制作好的图片来进行贴图操作,在贴图的过程中使用九宫图贴图方法,保证此边框图片能满足任何大小的窗体。窗体边框的实现:此部分主要涉及到对CS_DropSHADOW的了解,只要在窗口的ClassStyle添加此样式即可,关键代码如下:View Code protected override CreateParams CreateParams get CreateParams cp = base.CreateParams; if (!DesignMode) cp.ClassStyle |= (int) ClassStyle.CS_DropSHADOW; return cp; 四:系统按钮的绘制与事件处理此部分是所有部分中最难的部分,在此部分中既要实现系统按钮不同状态下(鼠标操作改变按钮状态)的绘制,还有对其相应的事件进行处理,所以我创建了2个类:SystemButton类和SystemButtonManager类。SystemButton类表示系统按钮类,而SystemButtonManager的功能是对系统按钮各个状态与事件的管理。类SystemButtonManager的类图如下所示:属性、方法、事件的功能介绍如下表: 对于类SystemButtonManager,主要是管理三个系统按钮的状态与事件,其他特别要介绍的是定义的系统按钮状态索引器,根据提供的索引来获取或者设置按钮的当前状态。五:窗体标题栏的绘制 标题栏的绘制主要涉及到窗体Icon图标的绘制与窗体标题的绘制,绘制的过程中定义了2个属性:IconRect,TextRect,分别对应着图标的坐标矩形与窗体标题的坐标矩形,图标与标题的绘制在这个矩形中绘制,需要提醒的时,图标的绘制需要注意到是否窗体的ShowIcon属性。六:解决窗体闪烁的问题 在窗体的自绘过程中,当调整窗体的大小等操作而触发窗体重绘,此时窗体的闪烁现象更为明显,相信大部分同学在自定义控件的过程中或多或多的出现这种问题,对于此问题,每个人又不同的解决方法,这里我提供四种解决方案类解决窗体的闪烁:方法一:第一个容易想到的是采用双缓冲机制来进行图形的绘制,对双缓冲不了解的同学可以参考下我的另外一篇文章浅谈C#中是双缓冲。方法二:当将CS_DropSHADOW样式添加到窗体的ClassStyle样式中可以明显的解决窗体闪烁的现象。代码见本文的第三部分-窗体边框的绘制与边框阴影的实现。方法三:当窗体进行重绘时,对WM_ERASEBKGND消息进行忽略,应用代码如下:View Code protected override void WndProc(ref Message m) switch (m.Msg) case Win32.WM_ERASEBKGND: m.Result = IntPtr.Zero; break; default: base.WndProc(ref m); break; 方法四:将WS_CLIPCHILDREN样式添加到

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论