WINFORM窗体界面设计技巧-不规则、可改变大小、边框半透明效果.doc_第1页
WINFORM窗体界面设计技巧-不规则、可改变大小、边框半透明效果.doc_第2页
WINFORM窗体界面设计技巧-不规则、可改变大小、边框半透明效果.doc_第3页
WINFORM窗体界面设计技巧-不规则、可改变大小、边框半透明效果.doc_第4页
WINFORM窗体界面设计技巧-不规则、可改变大小、边框半透明效果.doc_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

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

文档简介

网上也看过很多做.NET窗体的例子,我只是把网上的这些东西综合了一下,主要有下面这些特点:1、边框是半透明的,透明度可根据需要自己更改;2、可以改变窗体的大小,改变后样式不变;3、窗体的边框是不规则的;4、重点解决了窗体会出现闪烁的问题,在窗体移动的时候也不会闪烁;5、使用方便,只要将AlphaFormPanel拖动到一般的窗体上就可以实现换肤;设计思路说明:一、.NET下处理一个窗体部分透明我所知道的有两种方法: 1、用一张支持Alhpa通道的图片来处理半透明,这种方式处理出来的效果会很好,甚至可以用一张动态的图片来做背景。相信有人看过那个游动的鱼的程序,鱼的边缘是半透明的,就是用这种方式做的。这种方式整个窗体都是通过UpdateLayeredWindow画出来的,如果要在上面加控件的话,所有的控件都要自己来绘制,显然在具体的项目中用这种方式的话会大大增加开发的难度。有兴趣的人可以看看这个程序:/Files/liutao409/游动的鱼.rar关键的代码就是根据这种支持Alhpa通道的图片来绘制窗体DllImport(user32.dll, ExactSpelling = true, SetLastError = true)public static extern int UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref Point pptDst, ref Size psize,IntPtr hdcSrc, ref Point pptSrc, Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags);public void SetBits(Bitmap bitmap)if (!haveHandle) return;if(!Bitmap.IsCanonicalPixelFormat(bitmap.PixelFormat)| !Bitmap.IsAlphaPixelFormat(bitmap.PixelFormat) throw new ApplicationException(图片必须是32位带Alhpa通道的图片。);IntPtr oldBits = IntPtr.Zero;IntPtr screenDC = Win32.GetDC(IntPtr.Zero);IntPtr hBitmap = IntPtr.Zero;IntPtr memDc = Win32.CreateCompatibleDC(screenDC);tryWin32.Point topLoc = new Win32.Point(Left, Top);Win32.Size bitMapSize = new Win32.Size(bitmap.Width, bitmap.Height);Win32.BLENDFUNCTION blendFunc = new Win32.BLENDFUNCTION(); Win32.Point srcLoc = new Win32.Point(0, 0);hBitmap = bitmap.GetHbitmap(Color.FromArgb(0);oldBits = Win32.SelectObject(memDc, hBitmap);blendFunc.BlendOp = Win32.AC_SRC_OVER;blendFunc.SourceConstantAlpha = 255;blendFunc.AlphaFormat = Win32.AC_SRC_ALPHA;blendFunc.BlendFlags = 0;Win32.UpdateLayeredWindow(Handle, screenDC, ref topLoc, ref bitMapSize, memDc, ref srcLoc, 0, ref blendFunc, Win32.ULW_ALPHA); finally if (hBitmap != IntPtr.Zero) Win32.SelectObject(memDc, oldBits); Win32.DeleteObject(hBitmap); Win32.ReleaseDC(IntPtr.Zero, screenDC); Win32.DeleteDC(memDc); 2、用两个窗体来实现边框半透明后面的窗体用来做边框,前面的窗体放其他的控件,前面的窗体跟随后面的窗体移动和改变大小,这样就很容易的控制后面的窗体半透明显示。这种方式虽然麻烦一点,但是不用像第一种方式那样自己绘制所有的控件,所以还是可以在项目中使用的。我的这个例子用的就是这种方式实现的。二、窗体边框的处理我的窗体的边框是用图片来处理的,为了使窗体的边框在改变大小后的样式不改变,上下边框做成了3段式的,中间部分平铺,两端保持不变这样窗体任意缩放后样式都不会改变。如果对GDI+熟悉的话,也可以不用图片来处理,直接绘制渐变填充也可以。我重写的承载图片的PictureBox,让PictureBox将所有的消息都传给父窗体来处理,这样就可以由父窗体统一的处理窗体的缩放和移动了,具体的代码如下:public partial class PictureBoxEX : PictureBox public delegate void delSetFormSize(int intInfo); public event delSetFormSize evtSetFormSize; #region 属性 private bool _bTopLeft = false; public bool BTopLeft get return _bTopLeft; set _bTopLeft = value; private bool _bTop = false; public bool BTop get return _bTop; set _bTop = value; private bool _bTopRight = false; public bool BTopRight get return _bTopRight; set _bTopRight = value; private bool _bLeft = false; public bool BLeft get return _bLeft; set _bLeft = value; private bool _bBottomLeft = false; public bool BBottomLeft get return _bBottomLeft; set _bBottomLeft = value; private bool _bBottom = false; public bool BBottom get return _bBottom; set _bBottom = value; private bool _bRight = false; public bool BRight get return _bRight; set _bRight = value; private bool _bBottomRight = false; public bool BBottomRight get return _bBottomRight; set _bBottomRight = value; #endregion #region 构造函数 / / 构造函数 / public PictureBoxEX() ; #endregion #region 重新鼠标消息 const int WM_NCHITTEST = 0x0084; const int HTTRANSPARENT = -1; const int HTLEFT = 10; const int HTRIGHT = 11; const int HTTOP = 12; const int HTTOPLEFT = 13; const int HTTOPRIGHT = 14; const int HTBOTTOM = 15; const int HTBOTTOMLEFT = 0x10; const int HTBOTTOMRIGHT = 17; protected override void WndProc(ref Message m) base.WndProc(ref m); switch (m.Msg) case WM_NCHITTEST: Point vPoint = new Point(int)m.LParam & 0xFFFF, (int)m.LParam 16 & 0xFFFF); vPoint = PointToClient(vPoint); int intInfo = -1; if (_bTopLeft) if (vPoint.X = ClientSize.Width - 10) intInfo = HTTOPRIGHT; else if (_bTop) if (vPoint.Y = 5) m.Result = (IntPtr)HTTOP; intInfo = HTTOP; if (evtSetFormSize != null & intInfo != -1) evtSetFormSize(intInfo); /将消息传给父窗体来处理 m.Result = (IntPtr)HTTRANSPARENT; break; #endregion 关键代码说明:一、用到的消息 private const int WM_NCLBUTTONDBLCLK = 0x00A3; private int _intInfo = -1; /消息回传值 private const int HTLEFT = 10; private const int HTRIGHT = 11; private const int HTTOP = 12; private const int HTTOPLEFT = 13; private const int HTTOPRIGHT = 14; private const int HTBOTTOM = 15; private const int HTBOTTOMLEFT = 0x10; private const int HTBOTTOMRIGHT = 17; private const int WM_NCHITTEST = 0x84; private const int HTCLIENT = 0x01; private const int HTCAPTION = 0x02;1、改变窗体大小和移动窗体的位置 所有的和边框有关的消息都传到后面的窗体的处理,承载边框的PictureBoxEx 会将传给它的系统消息忽略掉 protected override void WndProc(ref Message m) if (m.Msg = WM_NCHITTEST) this.DefWndProc(ref m);/移动窗体位置 if (m.Result.ToInt32() = HTCLIENT & this.WindowState != FormWindowState.Maximized) m.Result = new IntPtr(HTCAPTION); else base.WndProc(ref m); /改变窗体大小 if (ChangeFormSize & _intInfo != -1 & this.WindowState != FormWindowState.Maximized) m.Result = (IntPtr)_intInfo; _intInfo = -1; /双击鼠标左键的消息 else if (m.Msg = WM_NCLBUTTONDBLCLK) if (ChangeFormSize) /相当于单击一次最大化按钮 btnMax_MouseClick(null, EventArgs.Empty); else base.WndProc(ref m); 2、减少窗体闪烁 下面的是比较常见的减少窗体闪烁的方法 private void SetStyles() SetStyle( ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor, true); SetStyle(ControlStyles.Selectable, false); UpdateStyles(); 还可以设置窗体双缓存在减少闪烁 this.DoubleBuffered = true; 在窗体控件的创建过程中,如果控件过多的话,用下面这个函数来处理控件的创建也可以减少闪烁 public class AvoidControlFlicker private int _paintFrozen; public void FreezePainting(Control toFreezeControl, bool isToFreeze) if (null = toFreezeControl) throw new ArgumentNullException(toFreezeControl); if (isToFreeze & toFreezeControl.IsHandleCreated & toFreezeControl.Visible) if (0 = _paintFrozen+) NativeMethods.SendMessage(toFreezeControl.Handle, NativeConsts.WM_SETREDRAW, 0, 0); if (!isToFreeze) if (0 = _paintFrozen) return; if (0 = -_paintFrozen) NativeMethods.SendMessage(toFreezeControl.Handle, NativeConsts.WM_SETREDRAW, 1, 0); toFreezeControl.Invalidate(true); 3、为了给初学者提供一些帮助,其它一些处理函数也写出来 / / 窗体位置改变 / / / private void formStyle_LocationChanged(object sender, EventArgs e) if (PForm != null) /同时改变前面的子窗体的位置 CForm.Location = new Point(this.Location.X + pbLeft.Width, this.Location.Y + panelTop.Height); CForm.Update(); / / 关闭按钮单击事件 / / / private void btnExit_MouseClick(object sender, EventArgs e) this.Close(); /关闭窗体时要同时关闭窗体所在的父窗体 protected override void OnClosing(CancelEventA

温馨提示

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

评论

0/150

提交评论