//layered 分层窗口 import gdip.graphics; import gdip.solidBrush; import gdip.bitmap; namespace win.ui; class layered{ ctor( winform,delayTime ){ this._form = winform; winform.modifyStyle(0xC40000/*_WS_BORDER|_WS_CAPTION|_WS_SIZEBOX|_WS_DLGFRAME*/); winform.setPos(,,,,,0x20/*_SWP_FRAMECHANGED*/|0x10/*_SWP_NOACTIVATE*/); winform.transparent = true; winform.background.drawRect = function(){}; winform.background.update = function(){ this.redraw() }; this.background = winform.background.getLayeredBitmap(); this.backgroundColor = winform.background.getLayeredColor(); if( delayTime === null ) delayTime = -1; winform._onControlCreated = function(ctrls){ for( name,ctrl in ctrls ){ if(ctrl.directDrawBackgroundOnly){ ctrl.directDrawBackgroundOnly(); if(ctrl.predraw ) ctrl.predraw(); } } } if( ..win.isVisible(winform.hwnd) ) { for( name,ctrl in winform.eachControl() ){ if(ctrl.directDrawBackgroundOnly){ ctrl.directDrawBackgroundOnly(); if(ctrl.predraw ) ctrl.predraw(); } } } this.redraw = function(){ return ..gdi.layeredBuffer( winform.hwnd, function( hdc,hMemDc,hMemBitmap,width,height,left,top,hwnd,blendFunction ){ var graphics = ..gdip.graphics(hMemDc); if( this.background || ( this.backgroundColor!== null ) ){ if( ! ( (width == this.cacheBitmapWidth) && (height == this.cacheBitmapHeight ) && (this.background==this.cacheBackground) && (this.backgroundColor==this.cacheBackgroundColor)) ){ this.predraw(); } if(this.cacheBitmap){ graphics.drawCachedBitmap(this.cacheBitmap,0,0); } } if( this.onDrawBackground ) this.onDrawBackground(graphics,left,top,width,height); if(! this.updateDrawing ){ this.updateDrawing = true; var rc = ::RECT(); rc.xywh(left,top,width,height); this._form.directDrawBackground(hMemDc,graphics,rc); this.updateDrawing = false; } graphics.resetClip(); graphics.delete(); return ..gdi.updateLayeredWindow(hwnd,hMemDc,::SIZE(width,height) ,blendFunction); } ) }; winform.adjust = function(){ this.redraw(); } winform.beforeShowWindow = function(shown,status){ if(shown){ for( name,ctrl in winform.eachControl() ){ if(ctrl.directDrawBackgroundOnly){ ctrl.directDrawBackgroundOnly(); if(ctrl.predraw ) ctrl.predraw(); } } winform.setTimeout(this.redraw); if(delayTime>0) && (this.timerId===null) this.timerId = winform.setInterval(this.redraw,delayTime) } else { if(this.timerId!==null){ winform.clearInterval(this.timerId); this.timerId = null; } } } winform.beforeShowWindow( ..win.isVisible(winform.hwnd) ); winform._beforeDestroy = function(){ if( this.cacheBitmap ) { ..gdip.DeleteCachedBitmap(this.cacheBitmap); this.cacheBitmap = null; } }; }; predraw = function(){ if( this.cacheBitmap ) { ..gdip.DeleteCachedBitmap(this.cacheBitmap); this.cacheBitmap = null; } if(( this.background ) || ( this.backgroundColor!== null )){ if( type(this.background) == "string" ){ this.background = ..gdip.bitmap(this.background); }; var rc = this._form.getRect(); var width,height = rc.right - rc.left,rc.bottom - rc.top; var bmpMem = ..gdip.bitmap(width,height); var g = bmpMem.getGraphics(); g.smoothingMode = 2/*_SmoothingModeHighQuality*/; if( this.backgroundColor!== null ){ var brush = ..gdip.solidBrush(this.backgroundColor); if( this.borderRadius ){ var path = ..gdip.path(1/*_FillModeWinding*/) path.addRoundRect(::RECT(0,0,width,height),this.borderRadius); g.fillPath(brush,path); path.delete(); } else { g.fillRectangle(brush,0,0,width,height); } } if(this.background){ if(this._form .bkTop!==null){ g.drawImageExpand(this.background ,::RECT(0,0,width,height),this._form .bkTop ,this._form .bkRight,this._form .bkBottom,this._form .bkLeft); } else { g.drawImage(this.background); } } g.delete(); var graphics = ..gdip.graphics(this._form); this.cacheBitmap = graphics.createCachedBitmap(bmpMem); graphics.delete(); this.cacheBackground = this.background; this.cacheBackgroundColor = this.backgroundColor; this.cacheBitmapWidth = width; this.cacheBitmapHeight = height; bmpMem.dispose(); } } } /**intellisense() win.ui.layered( = 创建分层窗口\n支持窗体设计器指定的 png 透明背景图,背景色,\n支持窗口上的 plus,bkplus 控件,其他子窗口可通过调用 orphanWindow 函数正常显示 win.ui.layered(.(窗体对象,主动刷新间隔) = 创建分层窗口\n主动刷新间隔为可选参数,以毫秒为单位,过快会降低性能\n刷新间隔设为负数可禁止主动刷新,但plus控件仍然可以自动刷新,\n注意创建分层窗口以后不应再改变窗口大小 win.ui.layered() = !winuilayered. end intellisense**/ /**intellisense(!winuilayered) onDrawBackground() = @.onDrawBackground = function(graphics,left,top,width,height){ __/*可以在这里继续在窗口背景上绘图*/ } background = 指定背景图像路径或数据 backgroundColor = 指定背景色,ARGB格式 borderRadius = 指定圆角半径,仅在使定背景色时有效 redraw() = 重绘窗口,不要在onDrawBackground里调用此函数 predraw() = 更新窗口绘图缓存但并不立即重绘,不要在onDrawBackground里调用此函数 end intellisense**/