• as3AIR在win7下实现磨砂窗体


      很多学习AIR的同学都知道,这个几乎是不可能的,因为AIR有限的能力,还不能达到那种效果。

      我曾今也单纯地以为,只要通过AS3的模糊滤镜,就能达到窗体磨砂的效果,答案是不行的,显然没那么简单,否则为啥市面上那么多AIR怎么就没有实现窗体磨砂的案例呢。如果单纯地通过AS3的模糊滤镜,可以实现舞台内部磨砂窗体,如果只是做子窗体效果,那也挺推荐用的。但现在要做的是顶级窗体的磨砂效果。

      我曾今用C++成功实现过windows7下的磨砂,那是系统的窗体,通过createWindow()创建出来的,然后调用了微软在Vista版本以上系统才有的DWM库,该库可以让开发者轻松实现磨砂窗体,这里也不再赘述,详情请看牛人的文章http://blog.csdn.net/ntwilford/article/details/5656633

      其实实现窗体磨砂并不难,难的是如何把这个技术用在AIR上面,其实这个也不怎么难,最难的是如何把AIR窗体的HWND句柄传给DLL,下面听我一步步道来。

      先说如何把这个技术用在AIR上面,答案就是ANE,ANE是ADOBE为AIR开发的一个本地代码扩展功能,可以使用的语言有C/C++或者JAVA,如果是做windows应用开发的,那建议用C/C++(还有MAC OS 开发objective-c),如果做android应用开发的,那就用JAVA。本文用的C++,开发环境是VS2012(其实VS版本没啥关系,因为就使用VC库而已),系统是windows7旗舰版。这里需要注意的是,磨砂窗体需要Vista及以上的系统内核才支持的,否则会提示缺少DLL,就算有了DLL,也会出不来效果。还有就是需要主题开启Aero效果,这是废话?有些开发者为了使系统达到一定的开发效率,就把Aero关掉了,现在开启吧。本人的是台式机,Aero效果无压力。

      废话不多说了,看代码:

     1 package
     2 {
     3     import flash.display.NativeWindow;
     4     import flash.external.ExtensionContext;
     5     /**
     6      * 
     7      * @author RockyF
     8      * 磨砂窗体类,首先必须通过bindWindow来绑定一个窗体(为了提高效率,采用了先绑定的方案)
     9      */    
    10     public class BlurWindow
    11     {
    12         private var context:ExtensionContext;
    13         public function BlurWindow()
    14         {
    15             context = ExtensionContext.createExtensionContext("BlurWindow","");
    16         }
    17         
    18         /**
    19          * 绑定窗体句柄,以提高效率
    20          * @param window 要应用磨砂窗体的NativeWindow对象
    21          * @return 
    22          * 
    23          */        
    24         public function bindWindow(window:NativeWindow):Boolean{
    25             var titleOld:String = window.title;
    26             
    27             var titleNew:String = "";
    28             
    29             var chars:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    30             for(var i:int = 0; i < 20; i++){
    31                 titleNew += chars.charAt(int(Math.random() * 26));
    32             }
    33             window.title = titleNew;
    34             
    35             var result:Boolean = Boolean(context.call("bindWindow", titleNew));
    36             
    37             window.title = titleOld;
    38                 
    39             return result;
    40         }
    41         
    42         /**
    43          * 你无需传入窗体的句柄,只需要提供要应用磨砂窗体的NativeWindow对象
    44          * 
    45          * @param padding    该磨砂窗体的内边距,这个参数在设置窗体阴影的时候很重要
    46          * @param radius        磨砂窗体的圆角半径
    47          * @return 返回结果该系统是否支持磨砂窗体
    48          * 
    49          */        
    50         public function apply(padding:int, radius:int):void{
    51             context.call("apply", padding, padding, padding, padding, radius, radius)
    52         }
    53         
    54         /**
    55          * 你无需传入窗体的句柄,只需要提供要应用磨砂窗体的NativeWindow对象
    56          * 
    57          * @param padding    该磨砂窗体的内边距,这个参数在设置窗体阴影的时候很重要
    58          * @param radius        磨砂窗体的圆角半径
    59          * @return 返回结果该系统是否支持磨砂窗体
    60          * 
    61          */        
    62         public function applyAdvance(paddingLeft:int, paddingTop:int, paddingRight:int, paddingBottom:int, radiusX:int, radiusY:int):void{
    63             context.call("apply", paddingLeft, paddingTop, paddingRight, paddingBottom, radiusX, radiusY);
    64         }
    65         /**
    66          * 判断该系统是否支持磨砂窗体
    67          * @return 返回结果该系统是否支持磨砂窗体
    68          * 
    69          */        
    70         public function isSupported():Boolean{
    71             var ispt:Boolean = Boolean(context.call("isSupported"));
    72             return ispt;
    73         }
    74     }
    75 }

      该类提供了四个方法和一个构造方法,构造方法是要的,通过构造方法创建一个上下文环境context, 以后对DLL的调用都会通过这个context(具体了解ANE,可以查看ADOBE官方文档,这里不再赘述了)。

      在new了这个类之后,需要绑定一个AIR窗体,为啥要绑定?我也是通过很多地试验得出的结论,每次都要获取AIR窗体的句柄,何不就获取一次,然后保留在DLL中呢,这样的话,每次apply一次窗体,都不会做同样的事了。

      看到这里,有人就要问了,这么多废话,那个AIR窗体的句柄到底怎么传递给DLL啊?

      记得我在论坛回复道:拐几个弯就行了。我猜那位兄弟是理解了我的话,然后,他就动用了WIN 32 api大军,从进程到模块,都用了遍,最后还是得不到句柄。

      现在就公布答案:WIN 32 API那么多,何愁得不到一个窗体的句柄。其实,在BlurWindow这个类中,就可以看到如何传递句柄了,我就是用了窗体的title属性,很容易联想到吧,在c++端就是接收了这个title,然后通过FindWindow()来获得句柄的。然而,又有人要问,那如果有同名的窗体,那怎么办?看代码中,我拐了一个弯:我先把原窗体的title存下来,然后用一个随机的20个字母的字符串来覆盖掉,可想而知,随机的20个字母组成的字符串,要碰到相同的title,那几率是多少,很小很小,所以我忽略不计了。如果你要还是担心会重名,那建议你用MD5好了。

      好了,关键的技术点我已经放出来,有意向的同学就可以开始动手了。

      要是懒得动啊,那下载源码好了。源码中的效果图:

      

      转载请注明:http://www.cnblogs.com/rockyf/archive/2013/03/11/AIR_Win7_BlurWindow.html

      源码下载:

        BlurWindow.zip flash pro版

        BlurWindow.zip flash builder版

  • 相关阅读:
    基于Lucene/XML的站内全文检索解决方案
    内容管理系统(CMS)的设计和选型
    Lucene入门与使用[转]
    为自己的系统搞个全文搜索 参考值:2 (转)
    C# 时间函数
    Lucene倒排索引原理(转)
    什么是内容管理系统CMS?
    网络测试常用命令
    C#与C的区别
    人生致命的八个经典问题
  • 原文地址:https://www.cnblogs.com/rockyf/p/AIR_Win7_BlurWindow.html
Copyright © 2020-2023  润新知