做过.NET Winform窗体美化的人应该都很熟悉UpdateLayeredWindow吧,UpdateLayeredWindow可以实现窗体的任意透明,效果很好,不会有毛边。不过使用这个API之后,会有一个问题就是无法使用普通控件,而且没有Paint消息。为了解决这个问题,有两种方法。

一、使用双层窗体,底层窗体使用UpdateLayeredWindow作为背景,上层窗体用普通窗体,并且可以使用TransparencyKey或者Region来实现去除不需要的窗体内容,让上层窗体能看到底层的窗体。

二、直接单层窗体,使用控件的DrawToBitmap把控件图像绘制到UpdateLayeredWindow的窗体上,这样就可以看到普通控件了。不过这个也有问题:1.控件内容不能自动更新  2.效率低,很多控件使用DrawToBitmap绘制出的图像不完整,甚至绘制不出图像。比如TextBox无法显示光标,WebBrowser无法显示内容。

三、采用DirectUI技术,重写所有基础控件。效果最好,不过工作量巨大。

使用UpdateLayeredWindow时,一般是需要对Bitmap缓存起来,通过设置剪辑区域,局部重绘来提高效率。另外还可以异步重绘,模拟Winform的失效到重绘。

有些人会说为什么不直接用WPF啊,Wpf和Winform各有优缺点,适应不同的场合。Winform相对于使用更简单一些,系统要求更低。当然需要看人的习惯了和擅长的。

UpdateLayeredWindow 基本使用方法:

重写窗体的 CreateParams 属性

protected   override  CreateParams CreateParams
{
get
{
CreateParams cp = base .CreateParams;
cp.ExStyle |= 0x00080000 ; // WS_EX_LAYERED 扩展样式
return cp;
}
}

  

API调用:

          public   void  SetBitmap(Bitmap bitmap,  byte  opacity)
{
if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
throw new ApplicationException( "位图必须是32位包含alpha 通道" ); IntPtr screenDc = Win32.GetDC(IntPtr.Zero);
IntPtr memDc = Win32.CreateCompatibleDC(screenDc);
IntPtr hBitmap = IntPtr.Zero;
IntPtr oldBitmap = IntPtr.Zero; try
{
hBitmap = bitmap.GetHbitmap(Color.FromArgb( 0 )); // 创建GDI位图句柄,效率较低
oldBitmap = Win32.SelectObject(memDc, hBitmap); Win32.Size size = new Win32.Size(bitmap.Width, bitmap.Height);
Win32.Point pointSource = new Win32.Point( 0 , 0 );
Win32.Point topPos = new Win32.Point(Left, Top);
Win32.BLENDFUNCTION blend = new Win32.BLENDFUNCTION();
blend.BlendOp = Win32.AC_SRC_OVER;
blend.BlendFlags = 0 ;
blend.SourceConstantAlpha = opacity;
blend.AlphaFormat = Win32.AC_SRC_ALPHA; Win32.UpdateLayeredWindow(Handle, screenDc, ref topPos, ref size, memDc, ref pointSource, 0 , ref blend, Win32.ULW_ALPHA);
}
finally
{
Win32.ReleaseDC(IntPtr.Zero, screenDc);
if (hBitmap != IntPtr.Zero)
{
Win32.SelectObject(memDc, oldBitmap); Win32.DeleteObject(hBitmap);
}
Win32.DeleteDC(memDc);
}
}

  

API声明:

      class  Win32
{
public enum Bool
{
False = 0 ,
True
} ; [StructLayout(LayoutKind.Sequential)]
public struct Point
{
public Int32 x;
public Int32 y; public Point(Int32 x, Int32 y)
{ this .x = x; this .y = y; }
} [StructLayout(LayoutKind.Sequential)]
public struct Size
{
public Int32 cx;
public Int32 cy; public Size(Int32 cx, Int32 cy)
{ this .cx = cx; this .cy = cy; }
} [StructLayout(LayoutKind.Sequential, Pack = 1 )]
struct ARGB
{
public byte Blue;
public byte Green;
public byte Red;
public byte Alpha;
} [StructLayout(LayoutKind.Sequential, Pack = 1 )]
public struct BLENDFUNCTION
{
public byte BlendOp;
public byte BlendFlags;
public byte SourceConstantAlpha;
public byte AlphaFormat;
} public const Int32 ULW_COLORKEY = 0x00000001 ;
public const Int32 ULW_ALPHA = 0x00000002 ;
public const Int32 ULW_OPAQUE = 0x00000004 ; public const byte AC_SRC_OVER = 0x00 ;
public const byte AC_SRC_ALPHA = 0x01 ; [DllImport( " user32.dll " , ExactSpelling = true , SetLastError = true )]
public static extern Bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pprSrc, Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags); [DllImport( " user32.dll " , ExactSpelling = true , SetLastError = true )]
public static extern IntPtr GetDC(IntPtr hWnd); [DllImport( " user32.dll " , ExactSpelling = true )]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC); [DllImport( " gdi32.dll " , ExactSpelling = true , SetLastError = true )]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC); [DllImport( " gdi32.dll " , ExactSpelling = true , SetLastError = true )]
public static extern Bool DeleteDC(IntPtr hdc); [DllImport( " gdi32.dll " , ExactSpelling = true )]
public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject); [DllImport( " gdi32.dll " , ExactSpelling = true , SetLastError = true )]
public static extern Bool DeleteObject(IntPtr hObject); [DllImport( " user32.dll " , EntryPoint = " SendMessage " )]
public static extern int SendMessage( int hWnd, int wMsg, int wParam, int lParam);
[DllImport( " user32.dll " , EntryPoint = " ReleaseCapture " )] public static extern int ReleaseCapture();
public const int WM_SysCommand = 0x0112 ;
public const int SC_MOVE = 0xF012 ; public const int SC_MAXIMIZE = 61488 ;
public const int SC_MINIMIZE = 61472 ;
}

  

需要呈现图像的时候调用 SetBitmap 方法。只要优化好,呈现效率比普通的Paint重绘方式高很多,并且不卡不闪烁,支持任意透明。

下面是自己开发出来的效果:

这个是用OpenGL绘制的

推荐一款C#界面库:DSkin界面库(Winform平台首个DirectUI界面库)  http://d.cskin.net

还有一个也是我开发的免费界面库LayeredSkin http://bbs.cskin.net/forum-56-1.html 也可以实现很多效果
 
Winform也可以很炫丽的!

C# Winform实现炫酷的透明动画界面的更多相关文章

  1. 8个超炫酷仿HTML5动画源码

    1.jQuery万年历插件 带农历老皇历功能 这是一款基于jQuery的日历插件,这款日历插件和之前分享的日历控件有很大差异,它是一本万年历,包含了农历已经老皇历的功能,是一个挑好日子的工具.同时日历 ...

  2. 手把手带你做一个超炫酷loading成功动画view Android自定义view

    写在前面: 本篇可能是手把手自定义view系列最后一篇了,实际上我也是一周前才开始真正接触自定义view,通过这一周的练习,基本上已经熟练自定义view,能够应对一般的view需要,那么就以本篇来结尾 ...

  3. HTML5 Canvas 超炫酷烟花绽放动画教程

    这是一个很酷的HTML5 Canvas动画,它将模拟的是我们现实生活中烟花绽放的动画特效,效果非常逼真,但是毕竟是电脑模拟,带女朋友看就算了,效果还是差了点,呵呵.这个HTML5 Canvas动画有一 ...

  4. WPF炫酷UI及动画

    偶然看见了一张图,感觉挺好看的,花了点时间将他转化成了我代码仓库的一部分.虽然不难但也费时间.其中除了背景是百度的一张底图,其他所有内容均通过WPF的Path.Line.TextBlock.Borde ...

  5. 如何在你的blog中添加炫酷的飘雪动画效果

    将下面的代码复制到你的设置栏下页眉html代码框中即可 <script> (function($){$.fn.snow=function(options){,maxSize:,newOn: ...

  6. 8个经典炫酷的HTML5 Canvas动画欣赏

    HTML5非常强大,尤其是Canvas技术的应用,让HTML5几乎可以完成所有Flash能完成的效果.本文精选了8个经典炫酷的HTML5 Canvas动画欣赏,每一个都提供全部的源代码,希望对你有所帮 ...

  7. iOS任何界面全屏炫酷倒计时,一句代码就够了

    概述 iOS全屏炫酷倒计时,任何界面只需要调用一句代码就能实现,支持定制倒计时数字.倒计时结束时显示的文本.支持倒计时播放图片.开始倒计时和结束倒计时的block和delegate回调.支持定制文本颜 ...

  8. 使用Three.js实现炫酷的赛博朋克风格3D数字地球大屏 🌐

    声明:本文涉及图文和模型素材仅用于个人学习.研究和欣赏,请勿二次修改.非法传播.转载.出版.商用.及进行其他获利行为. 背景 近期工作有涉及到数字大屏的需求,于是利用业余时间,结合 Three.js ...

  9. html5跟随鼠标炫酷网站引导页动画特效

    html5跟随鼠标炫酷网站引导页动画特效一款非常不错的引导页,文字效果渐变,鼠标跟随出绚丽的条纹.html5炫酷网站引导页,鼠标跟随出特效. 体验效果:http://hovertree.com/tex ...

随机推荐

  1. maven 的 pom.xml 文件报错:ArtifactTransferException: Failure to transfer

    因为maven下载依赖jar包时,特别慢,所以取消了下载过程,再次打开eclipse时,maven的pom.xml文件报错如下: ArtifactTransferException: Failure ...

  2. phpcms v9 下拉菜单 二级 三级子栏目调用方法

    很多网站的导航栏可以实现下拉二级菜单,三级菜单等效果,今天我们就来分享phpcms v9 支持下拉菜单的方法,可以支持无限子栏目调用,具体写法如下: <ul> {pc:content ac ...

  3. windows下 MySQL数据库双向同步 配置步骤

          最近在项目中遇到了要实现服务器上MySql数据双向同步,在网上找了很多资料,但是大部分都是在liux系统下配置的, 而且都是互相转载,没有一个详细的步骤,于是决定写一个windows系统下 ...

  4. 在VMware上安装CentOS-6.5 minimal - 配置网络

    CentOS的minimal版本默认不启动网络,所以安装完CentOS要自己配置网络. 老伯的VMware虚拟机网络连接方式采用NAT方式(其他方式没试过). 1 修改配置文件/etc/sysconf ...

  5. 离散化+线段树 POJ 3277 City Horizon

    POJ 3277 City Horizon Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 18466 Accepted: 507 ...

  6. HDU 1556 Color the ball

    这题用线段树的话简直就是一个水题..不过刚学树状数组,要用一下. 题意:每次给你a,b,表明a~b之间涂色,然后最后一次输出每个气球被涂色的次数. 要用树状数组就要考虑怎么转化为前缀和问题,这题可以这 ...

  7. Hanoi塔

    2016-03-19 17:01:35 问题描述: 假设有三个命名为 A B C 的塔座 ,在塔座A上插有n个直径大小不相同,由小到大编号为1 ,2 ,3 ,··· ,n的圆盘,要求将A座上的圆盘移至 ...

  8. UMLUnified Modeling Language (UML)又称统一建模语言或标准建模语言

    1.用例图(use case diagram) 2.活动图(activity diagram) 3.静态结构图 4.顺序图(Sequence Diagram):时序图 5.交互纵览图(Interact ...

  9. java 15-1 Collection集合的概述以及小功能介绍

     集合的由来:  我们学习的是面向对象语言,而面向对象语言对事物的描述是通过对象体现的,为了方便对多个对象进行操作,我们就必须把这多个对象进行存储.  而要想存储多个对象,就不能是一个基本的变量,而应 ...

  10. Android ant自动打包 crunch 报错

    解决办法: 修改SDK_HOME/tool/ant/build.xml. <property name="aapt.ignore.assets" value="&l ...