大部分时候,我们会放弃系统的默认镶边,自定义自己想要的镶边。这个时候,就需要自己手动来写效果了。基本过程是这样的。
1,屏蔽系统的镶边。
2,自己写皮肤,写逻辑(拖拽窗体,resize窗体,最大化,最小化,关闭,恢复等)。
每个AIR都有一个默认的xml配置文件,这里边定义了一些参数。通过打开注释,改变下边两个参数来关闭系统的镶边。一个是关闭镶边,另一个是打开透明。

        <!-- The type of system chrome to use (either "standard" or "none"). Optional. Default standard. -->
        <systemChrome>none</systemChrome>

        <!-- Whether the window is transparent. Only applicable when systemChrome is none. Optional. Default false. -->
        <transparent>true</transparent>

通过以上的设置,关闭了系统的镶边显示。然后来看怎么写自定义的镶边。最大化,最小化这些,比较好处理。这里主要讲下自由拖拽和自由resize。air提供了一个很好的方法(nativeWindow.startResize),来启动窗体的自由resize。里边可以带参数。参数标明拖拽的八个方向。仅仅这个是不够的,还要定义鼠标效果。鼠标移上去,拖拽光标要显示出来,拖拽的时候,光标跟着走。这里细节还是比较多。先记下光标的实现。
1,自己定义光标的显示对象。(位图,自己绘制都行)。
2,通过Mouse.registerCursor注册光标。registerCursor方法有两个参数,第一个参数是光标的名字,后边调用的时候需要,第二个参数是一个BitmapData的数组。就是光标的显示。
3,通过调用Mouse.cursor方法来更换光标。
其实,到了这里。在做这些之前,系统就已经有了一些光标效果。如鼠标遇到输入的时候的输入光标,遇到按钮的时候手型光标。当然通过上边的步骤,可以实现光标的定义。

下边说下拖拽。八个方向(上,上左,上右,左,右,下,下左,下右),通过定义sprite和范围来启动。可以通过定义一个sprite,然后通过Rectange来区分,调用resize,也可以通过建立八个sprite,分配好坐标来resize。我自己用的是后边一种方法。感觉还行。
建立八个sprite,然后对八个sprite进行侦听MouseDown,RollOver,RollOut事件。MouseDown事件,用来启动拖拽的,RollOver来显示光标的,RollOut来恢复到默认光标的。
RollOver的时候,根据不同的Sprite,取不同的光标效果。然后按下的时候,关掉mouseChildren属性。要不拖拽的时候,会出现泄露等瑕疵。同时,侦听stage的mouseUp事件,这个用来恢复默认光标。仅仅RllOut是不够的。还有,在RollOut的时候,如果鼠标状态是mouseDown状态,应不恢复默认光标。

上边这些可以定义到一个父类里边,以后用的时候,直接继承过来。至于按钮这些,可以定义在子类中。还有如果窗体是不规则的,可以自由对待。好了,细节有一些。贴出完整的代码吧。还需要更完善一些。

package com.vini123.chrome
{
    import flash.display.NativeWindow;
    import flash.display.NativeWindowResize;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.NativeWindowBoundsEvent;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.ui.MouseCursor;
    
    public class ChromeBase extends Sprite
    {
        /**
         * 其他显示对象的容器 
         */        
        protected var contentContainer:Sprite;
        
        protected var win:NativeWindow;
        
        /**
         * 拖拽的范围(顶部的高度) 
         */        
        protected var dragHeadHeight:int;
        
        /**
         * 拖拽,引动resize对象 
         */        
        private const DRAG_WEIGHT:int = 12;
        private var dragContainer:Sprite;
        private var dragTLButton:Sprite;
        private var dragTButton:Sprite;
        private var dragTRButton:Sprite;
        private var dragRButton:Sprite;
        private var dragBRButton:Sprite;
        private var dragBButton:Sprite;
        private var dragBLButton:Sprite;
        private var dragLButton:Sprite;
        
        private var _width:Number;
        private var _height:Number;
        
        public function ChromeBase()
        {
            addEventListener(Event.ADDED_TO_STAGE , addToStageHandler);
        }
        
        protected function addToStageHandler(e:Event):void
        {
            removeEventListener(Event.ADDED_TO_STAGE , addToStageHandler);
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            win = stage.nativeWindow;
            
            contentContainer = new Sprite();
            addChild(contentContainer);
            
            dragContainer = new Sprite();
            addChild(dragContainer);
            
            initializeDragButton();
            redrawDragButton(new Rectangle(0 , 0 , stage.stageWidth , stage.stageHeight));
            
            dragHeadHeight = 30;
            win.minSize = new Point(480 , 360);
            win.maxSize = new Point(1280 , 720);
            win.addEventListener(NativeWindowBoundsEvent.RESIZE , boundsResizeHandler);
            contentContainer.addEventListener(MouseEvent.MOUSE_DOWN , mouseDownHandler);
            dragContainer.addEventListener(MouseEvent.ROLL_OUT , dragRollOutHandler);
        }
        
        private function upHandler(e:MouseEvent):void
        {
            mouseChildren = true;
            stage.removeEventListener(MouseEvent.MOUSE_UP , upHandler);
            
            WinCursor.cursor = MouseCursor.AUTO;
        }
        
        private function dragMouseDownHandler(e:MouseEvent):void
        {
            stage.addEventListener(MouseEvent.MOUSE_UP , upHandler);
            mouseChildren = false;
            
            switch(e.currentTarget)
            {
                case dragTLButton:
                    win.startResize(NativeWindowResize.TOP_LEFT);
                    break;
                case dragBRButton:
                    win.startResize(NativeWindowResize.BOTTOM_RIGHT);
                    break;
                case dragTButton:
                    win.startResize(NativeWindowResize.TOP);
                    break;
                case dragBButton:
                    win.startResize(NativeWindowResize.BOTTOM);
                    break;
                case dragTRButton:
                    win.startResize(NativeWindowResize.TOP_RIGHT);
                    break;
                case dragBLButton:
                    win.startResize(NativeWindowResize.BOTTOM_LEFT);
                    break;
                case dragLButton:
                    win.startResize(NativeWindowResize.LEFT);
                    break;
                case dragRButton:
                    win.startResize(NativeWindowResize.RIGHT);
                    break;
            }
        }
        
        private function dragRollOverHandler(e:MouseEvent):void
        {
            switch(e.currentTarget)
            {
                case dragTLButton:
                case dragBRButton:
                    WinCursor.cursor = WinCursor.DESKTOP_RESIZE_TL;
                    break;
                case dragTButton:
                case dragBButton:
                    WinCursor.cursor = WinCursor.DESKTOP_RESIZE_TB;
                    break;
                case dragTRButton:
                case dragBLButton:
                    WinCursor.cursor = WinCursor.DESKTOP_RESIZE_TR;
                    break;
                case dragLButton:
                case dragRButton:
                    WinCursor.cursor = WinCursor.DESKTOP_RESIZE_LR;
                    break;
            }
        }
        
        /**
         * 
         * @param e
         *  手型移出
         */        
        private function dragRollOutHandler(e:MouseEvent):void
        {
            if(e.buttonDown)
                return;
            WinCursor.cursor = MouseCursor.AUTO;
        }
        
        /**
         * 
         * @param e
         *  窗口大小改变
         */        
        private function boundsResizeHandler(e:NativeWindowBoundsEvent):void
        {
            var rect:Rectangle = e.afterBounds;
            redrawDragButton(rect);
        }
        
        /**
         * 
         * @param e
         *  拖动窗口
         */        
        private function mouseDownHandler(e:MouseEvent):void
        {
            if(mouseY < dragHeadHeight)
                win.startMove();
        }
        
        private function initializeDragButton():void
        {
            dragTLButton = getDragButton(null , new Rectangle(0 , 0 , DRAG_WEIGHT , DRAG_WEIGHT) , dragMouseDownHandler , dragRollOverHandler);
            dragTButton = getDragButton(null , new Rectangle(0 , 0 , DRAG_WEIGHT , DRAG_WEIGHT) , dragMouseDownHandler , dragRollOverHandler);
            dragTRButton = getDragButton(null , new Rectangle(0 , 0 , DRAG_WEIGHT , DRAG_WEIGHT) , dragMouseDownHandler , dragRollOverHandler);
            dragRButton = getDragButton(null , new Rectangle(0 , 0 , DRAG_WEIGHT , DRAG_WEIGHT) , dragMouseDownHandler , dragRollOverHandler);
            dragBRButton = getDragButton(null , new Rectangle(0 , 0 , DRAG_WEIGHT , DRAG_WEIGHT) , dragMouseDownHandler , dragRollOverHandler);
            dragBButton = getDragButton(null , new Rectangle(0 , 0 , DRAG_WEIGHT , DRAG_WEIGHT) , dragMouseDownHandler , dragRollOverHandler);
            dragBLButton = getDragButton(null , new Rectangle(0 , 0 , DRAG_WEIGHT , DRAG_WEIGHT) , dragMouseDownHandler , dragRollOverHandler);
            dragLButton = getDragButton(null , new Rectangle(0 , 0 , DRAG_WEIGHT , DRAG_WEIGHT) , dragMouseDownHandler , dragRollOverHandler);
        }
        
        private function redrawDragButton(value:Rectangle):void
        {
            var half:int = DRAG_WEIGHT * 0.5;
            getDragButton(dragTLButton , new Rectangle(-half , -half , DRAG_WEIGHT , DRAG_WEIGHT) , null);//顶左
            getDragButton(dragTButton , new Rectangle(half , -half , value.width - DRAG_WEIGHT , DRAG_WEIGHT) , null); //
            getDragButton(dragTRButton , new Rectangle(value.width - half , -half , DRAG_WEIGHT , DRAG_WEIGHT) , null); //顶右
            getDragButton(dragRButton , new Rectangle(value.width - half , half , DRAG_WEIGHT , value.height - DRAG_WEIGHT) , null); //
            getDragButton(dragBRButton , new Rectangle(value.width - half , value.height -half , DRAG_WEIGHT , DRAG_WEIGHT) , null); //底右
            getDragButton(dragBButton , new Rectangle(half , value.height - half , value.width - DRAG_WEIGHT , DRAG_WEIGHT) , null); //
            getDragButton(dragBLButton , new Rectangle(-half , value.height-half , DRAG_WEIGHT , DRAG_WEIGHT) , null); //底左
            getDragButton(dragLButton , new Rectangle(-half , half , DRAG_WEIGHT , value.height - DRAG_WEIGHT) , null); //
            
            width = value.width;
            height = value.height;
        }
        
        private function getDragButton(sp:Sprite , value:Rectangle , downHandler:Function = null , overHandler:Function = null , outHandler:Function = null):Sprite
        {
            if(!sp)
            {
                sp = new Sprite();
                dragContainer.addChild(sp);
            }
            sp.graphics.clear();
            sp.graphics.beginFill(0xffffff,  0.0);
            sp.graphics.drawRect(value.x , value.y , value.width , value.height);
            sp.graphics.endFill();
            
            if(downHandler)
            {
                sp.addEventListener(MouseEvent.MOUSE_DOWN , downHandler);
            }
            
            if(overHandler)
            {
                sp.addEventListener(MouseEvent.ROLL_OVER , overHandler);
            }
            
            if(outHandler)
            {
                sp.addEventListener(MouseEvent.ROLL_OUT , outHandler);
            }
            return sp;
        }
        
        override public function set width(value:Number):void
        {
            if(_width != value)
            {
                _width = value;
                redraw();
            }
        }
        
        override public function get width():Number
        {
            return _width;
        }
        
        override public function set height(value:Number):void
        {
            if(_height != value)
            {
                _height = value;
                redraw();
            }
        }
        
        override public function get height():Number
        {
            return _height;
        }
        
        protected function redraw():void
        {
        
        }
    }
}

 

package com.vini123.chrome
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.geom.Point;
    import flash.ui.Mouse;
    import flash.ui.MouseCursorData;
    
    public class WinCursor extends Object
    {
        [Embed(source="/assets/cursor/tl.png")]
        private static const TLSkin:Class;
        
        [Embed(source="/assets/cursor/tb.png")]
        private static const TBSkin:Class;
        
        [Embed(source="/assets/cursor/tr.png")]
        private static const TRSkin:Class;
        
        [Embed(source="/assets/cursor/lr.png")]
        private static const LRSkin:Class;

        private static var hasRegData:Boolean = false;
        
        public function WinCursor():void
        {
            super();
        }
        
        public static function get cursor() : String
        {
            return Mouse.cursor;
        }
        
        public static function set cursor(param1:String) : void
        {
            if((_locked) || Mouse.cursor == param1)
            {
                return;
            }
            
            if(!hasRegData)
            {
                regData();
            }
            
            Mouse.cursor = param1;
        }
        
        private static var _locked:Boolean = false;
        
        public static function get locked() : Boolean
        {
            return _locked;
        }
        
        public static function set locked(param1:Boolean) : void
        {
            _locked = param1;
        }
        
        public static const DESKTOP_CIRCLE:String = "appCircle";
        
        public static const DESKTOP_RESIZE_TL:String = "desktop_resize_tl"; //左上 - 右下
        public static const DESKTOP_RESIZE_TB:String = "desktop_resize_tb"; //上下
        public static const DESKTOP_RESIZE_TR:String = "desktop_resize_tr"; //右上 - 左下
        public static const DESKTOP_RESIZE_LR:String = "desktop_resize_lr"; //左右
        
        
        private static function regData() : void
        {
            var bitmapData:BitmapData;
            var mouseCursorData:MouseCursorData;
            
            bitmapData = (new TLSkin() as Bitmap).bitmapData;
            mouseCursorData = new MouseCursorData();
            mouseCursorData.data = new <BitmapData>[bitmapData];
            mouseCursorData.hotSpot = new Point(bitmapData.width * 0.5 , bitmapData.height * 0.5);
            Mouse.registerCursor(DESKTOP_RESIZE_TL , mouseCursorData);

            bitmapData = (new TBSkin() as Bitmap).bitmapData;
            mouseCursorData = new MouseCursorData();
            mouseCursorData.data = new <BitmapData>[bitmapData];
            mouseCursorData.hotSpot = new Point(bitmapData.width * 0.5 , bitmapData.height * 0.5);
            Mouse.registerCursor(DESKTOP_RESIZE_TB , mouseCursorData);
            

            bitmapData = (new TRSkin() as Bitmap).bitmapData;
            mouseCursorData = new MouseCursorData();
            mouseCursorData.data = new <BitmapData>[bitmapData];
            mouseCursorData.hotSpot = new Point(bitmapData.width * 0.5 , bitmapData.height * 0.5);
            Mouse.registerCursor(DESKTOP_RESIZE_TR , mouseCursorData);
            
            bitmapData = (new LRSkin() as Bitmap).bitmapData;
            mouseCursorData = new MouseCursorData();
            mouseCursorData.data = new <BitmapData>[bitmapData];
            mouseCursorData.hotSpot = new Point(bitmapData.width * 0.5 , bitmapData.height * 0.5);
            Mouse.registerCursor(DESKTOP_RESIZE_LR , mouseCursorData);
            
            hasRegData = true;
        }
    }
}

 

package com.vini123.chrome
{
    import com.vini123.library.component.display.ScaleBitmap;
    
    import flash.display.Bitmap;
    import flash.geom.Rectangle;

    public class Chrome extends ChromeBase
    {
        [Embed(source="/assets/background.png")]
        private var Background:Class;
        
        private var background:ScaleBitmap;
        
        public function Chrome()
        {
            super();
        }
        
        override protected function redraw():void
        {
            if(!width|| !height)
                return;
            
            if(!background)
            {
                background = new ScaleBitmap((new Background() as Bitmap).bitmapData);
                background.scale9Grid = new Rectangle(15 , 15 , 50 , 20);
                contentContainer.addChild(background);
            }
            background.width = width;
            background.height = height;
        }
    }
}

 

默认窗体外的其他窗体,可以通过New NativeWindow出来。参数可以这样定义。

package com.vini123.window
{
    import flash.display.NativeWindowInitOptions;
    import flash.display.NativeWindowSystemChrome;
    import flash.display.NativeWindowType;
    import flash.utils.Dictionary;

    public class WindowOptions
    {
        /**
         * 使用chrome系统镶边
         */        
        public static const USE_CHROME:String = "use_chrome";
        
        /**
         * 不使用chrome系统镶边
         */        
        public static const NO_USE_CHROME:String = "no_use_chrome";
        
        private static var optionsDic:Dictionary;
        
        public function WindowOptions()
        {
            
        }
        
        public static function getOptions(value:String):NativeWindowInitOptions
        {
            if(!optionsDic)
                optionsDic = new Dictionary();
            
            if(optionsDic[value])
                return optionsDic[value];
            
            var useChrome:String = "";
            var transparent:Boolean = false;
            switch(value)
            {
                case USE_CHROME:
                    useChrome = NativeWindowSystemChrome.STANDARD;
                    transparent = false;
                    break;
                case NO_USE_CHROME:
                    useChrome = NativeWindowSystemChrome.NONE;
                    transparent = true;
                    break;
                default:
                    if(optionsDic[USE_CHROME])
                    {
                        return optionsDic[USE_CHROME];
                    }
                    useChrome = NativeWindowSystemChrome.STANDARD;
                    transparent = false;
                    break;
            }
            
            var options:NativeWindowInitOptions = new NativeWindowInitOptions();
            options.systemChrome = useChrome;
            options.transparent = transparent;
            options.type = NativeWindowType.UTILITY;
            
            optionsDic[value] = options;
            return options;
        }
    }
}