C# Winform实现炫酷的透明动画界面

做过.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 属性

?


1

2

3

4

5

6

7

8

9

protected   override  CreateParams CreateParams

           {

              get

                  {

                 CreateParams cp  =   base .CreateParams;

                 cp.ExStyle  |=   0x00080000 ;  //  WS_EX_LAYERED 扩展样式

                  return  cp;

             }

         }

  

API调用:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

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声明:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

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也可以很炫丽的!

时间: 2024-10-12 20:51:15

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

C# Winform实现炫酷的透明动画界面(转载)

本文转自:http://www.cnblogs.com/dskin/p/4606293.html 做过.NET Winform窗体美化的人应该都很熟悉UpdateLayeredWindow吧,UpdateLayeredWindow可以实现窗体的任意透明,效果很好,不会有毛边.不过使用这个API之后,会有一个问题就是无法使用普通控件,而且没有Paint消息.为了解决这个问题,有两种方法. 一.使用双层窗体,底层窗体使用UpdateLayeredWindow作为背景,上层窗体用普通窗体,并且可以使用

8个超炫酷仿HTML5动画源码

1.jQuery万年历插件 带农历老皇历功能 这是一款基于jQuery的日历插件,这款日历插件和之前分享的日历控件有很大差异,它是一本万年历,包含了农历已经老皇历的功能,是一个挑好日子的工具.同时日历还可以查看本年度的放假安排,功能非常强大.有兴趣的朋友可以下载学习. 在线演示 源码下载 2.CSS3发光进度条动画 超炫酷的样式 这次我们要来分享一款非常炫酷的CSS3进度条动画,其样式风格类似于星球大战里面的那些激光剑效果.页面初始化时,可以设定进度条的值,但是我们也可以利用其配套的借口来动态改

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

写在前面: 本篇可能是手把手自定义view系列最后一篇了,实际上我也是一周前才开始真正接触自定义view,通过这一周的练习,基本上已经熟练自定义view,能够应对一般的view需要,那么就以本篇来结尾告一段落,搞完毕设的开题报告后去学习新的内容. 有人对我说类似的效果网上已经有了呀,直接拿来就可以用,为什么还要写.我个人的观点是:第三方控件多数不能完全满足UI的要求,如果需要修改,那么必须理解他的实现,所以很有必要自己去写一款出来,成为程序的创造者,而不单单是使用者.所以,写一写已经实现的效果,

html5炫酷购物车结算动画特效

这是一款效果十分炫酷的html5购物车结算动画特效插件.该购物车结算动画提供了4种效果,每种效果都使用CSS3来制作炫酷的动画特效,这些效果使用户的购物结算体验大大的增强了. 在线演示:http://www.htmleaf.com/Demo/201501231255.html 下载地址 :http://www.htmleaf.com/html5/html5muban/201501231254.html

28种CSS3炫酷加载动画特效

这是一组效果非常炫酷的纯CSS3 Loading加载动画特效.这组loading动画共有27种不同的效果.每一种loading动画都是通过CSS3的keyframes帧动画来完成的,每一个加载动画都构思新颖,效果非常的酷. 效果演示:http://www.htmleaf.com/Demo/201503301597.html 下载地址:http://www.htmleaf.com/css3/css3donghua/201503301596.html

【OneAPM】极客编程挑战#025:发挥想象生成漂亮炫酷的SVG动画效果

活动链接:http://www.gbtags.com/gb/share/5610.htm 本期挑战 提供如下的SVG图形,请使用任何技术生成基于如下SVG图形的动画效果,看看谁设计的动画效果最酷 ~~ <svg width="720px" height="486px"> <g id="layer1"> <path style="fill:#888888" d="m 434.02002,3

10个web炫酷的jQuery动画插件及源码

1.基于jquery漂亮的按钮 今天给大家分享一款基于jquery漂亮的按钮.这款按钮背景下用了一张图片.当鼠标经过的时候背景用半透明div遮住. 在线演示 源码下载 2.jquery自适应动态内容翻转特效 jquery自适应动态内容翻转特效 在线演示 源码下载 3.多功能网页幻灯片jQuery Cycle 多功能网页幻灯片jQuery Cycle 在线演示 源码下载 4.jQuery书本翻页3D动画特效 记得以前我们有介绍过不少书本翻页的动画,比如这款CSS3书本翻页动画,制作就非常逼真.今天

利用SVG和css3实现炫酷的边框动画

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>line</title> </head> <style> .empat { position: relative; overflow: hidden; width: 200px; height: 200px; background-c

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

HTML5非常强大,尤其是Canvas技术的应用,让HTML5几乎可以完成所有Flash能完成的效果.本文精选了8个经典炫酷的HTML5 Canvas动画欣赏,每一个都提供全部的源代码,希望对你有所帮助. 1.HTML5 Canvas可拖动的弹性大树摇摆动画 今天让我们继续来分享一个炫酷的HTML5动画,它是一款基于HTML5 Canvas的大树摇摆动画,这款HTML5动画的特点是我们可以拖拽树枝,从而让整棵树摇摆起来,这样就真实地模拟了大树从摇摆到静止的整个过程,相当逼真. 在线演示