//plus 高级图像控件 import win.ui.tracker; import win.ui.ctrl.richedit; import win.ui.ctrl.metaProperty; import gdip.font; import gdip.textureBrush; import gdip.solidBrush; import gdip.lineBrush; import gdip.pathGradientBrush; import gdip.stringformat; import gdip.path; import gdip.pen; import gdip.graphics; namespace win.ui.ctrl; class plus { ctor( parent,tParam ) { this.state = {}; tParam.cls = __className; if(tParam.edge) tParam.exstyle |= 0x20000/*_WS_EX_STATICEDGE*/; this.transparent = tParam.transparent; this.notify = tParam.notify; this.animation = tParam.animation; this.bkTop = tParam.bkTop : 0; this.bkRight = tParam.bkRight : 0; this.bkBottom = tParam.bkBottom : 0; this.bkLeft = tParam.bkLeft : 0; this.foreTop = tParam.foreTop : 0; this.foreRight = tParam.foreRight : 0; this.foreBottom = tParam.foreBottom : 0; this.foreLeft = tParam.foreLeft : 0; this.paddingLeft = tParam.paddingLeft : 0; this.paddingRight = tParam.paddingRight : 0; this.paddingTop = tParam.paddingTop : 0; this.paddingBottom = tParam.paddingBottom : 0; this.x = tParam.x : 0; this.y = tParam.y : 0; if(!_WINXP) { if( !tParam.font ) tParam.font = ::LOGFONT(name="Segoe UI"); elseif( tParam.font.name=="Tahoma" ) tParam.font.name="Segoe UI"; } else { if( !tParam.font ) tParam.font = ::LOGFONT(name="MS Shell Dlg"); elseif( tParam.font.name=="Tahoma" ) tParam.font.name="MS Shell Dlg"; } if(tParam.font.name!="Segoe UI" || this.transparent){ this.textRenderingHint = 3/*_GdipTextRenderingHintAntiAliasGridFit*/; } else { this.textRenderingHint = 5/*_TextRenderingHintClearTypeGridFit*/; } if( tParam.iconStyle[["font"]] != "Segoe UI" || this.transparent){ this.iconTextRenderingHint = 3; } else { this.iconTextRenderingHint = 5; } if(!#tParam.repeat) tParam.repeat = "expand"; if(!#tParam.foreRepeat) tParam.foreRepeat = "point"; this[["(text)"]] = tParam.text; this.smoothingMode = 4/*_GdipSmoothingModeAntiAlias*/; this.interpolationMode = 7/*_InterpolationModeHighQualityBicubic*/; this.clipBk = true; if(tParam.bgcolor!==null){ if(!(tParam.bgcolor & 0xFF000000)){ this.backgroundColor = ..gdi.rgbReverse( tParam.bgcolor ) | 0xFF000000; } else this.backgroundColor = tParam.bgcolor; tParam.bgcolor = null; } if(tParam.forecolor!==null){ if(!(tParam.forecolor & 0xFF000000)){ this.foregroundColor = ..gdi.rgbReverse( tParam.forecolor ) | 0xFF000000; } else this.foregroundColor = tParam.forecolor; tParam.forecolor = null; } if( type(tParam.border) == "number" ){ tParam.border = {width=tParam.border;color=0xFF000000} }; var border = tParam.border; if(border){ if(border[["color"]] && !(border.color & 0xFF000000)){ border.color = ..gdi.argbReverse(border.color); } this.border = border; tParam.border = null; } tParam.style= tParam.style &~0x800000/*_WS_BORDER*/; this.trimming = 3/*_StringTrimmingEllipsisCharacter*/; this.stringFormatFlags = 0x800/*_GdipStringFormatFlagsMeasureTrailingSpaces*/ | 0x1000/*_StringFormatFlagsNoWrap*/; this.hotkeyPrefix = 1/*_GdipHotkeyPrefixShow*/; //先禁用避免触发属性表 this[["editable"]] = tParam.editable; if(tParam.editable){ tParam.style= tParam.style &~0x100000/*_WS_HSCROLL*/; tParam.style= tParam.style &~0x200000/*_WS_VSCROLL*/; } if((tParam.iconColor!==null) && !(tParam.iconColor & 0xFF000000) ){ tParam.iconColor = ..gdi.argbReverse(tParam.iconColor); } }; redrawTransparent = function(){ if( owner[["initializing"]] ) return; this.updateBitmapCache(true); if(this.drawToBackgroundEnabled){ var winform = owner[["_parentForm"]]; winform.background.update(); winform.invalidate(owner); winform.update(); return; } if( ( ( this.transparent || ( this.isHyperlink() && !this.clipBk) ) ) && !owner.cacheOrphanWindowRect__){ var hParent = ..win.getParent(owner.hwnd); var rc = ..win.getRect(owner.hwnd); ::InvalidateRect( hParent,rc,1 ); ::UpdateWindow( hParent ); if( ..win.getStyle(hParent,0x2000000/*_WS_CLIPCHILDREN*/) ){ ::RedrawWindow(this[["hwnd"]],{},null,0x105 /*_RDW_INVALIDATE | _RDW_UPDATENOW*/ ); } } else { ::RedrawWindow(this[["hwnd"]],{},null,0x105 /*_RDW_INVALIDATE | _RDW_UPDATENOW*/ ); } }; redraw = function( flag = 0x105 /*_RDW_INVALIDATE | _RDW_UPDATENOW */ ) { if( owner[["initializing"]] ) return; this.updateBitmapCache(); if(this.drawToBackgroundEnabled){ var winform = owner[["_parentForm"]]; winform.background.update(); winform.invalidate(owner); winform.update(); return; } ::RedrawWindow(owner[["hwnd"]],{},null,flag); }; predraw = function(){ this.updateBitmapCache(true); this.invalidate(); }; _preadjust = function(cx,cy){ this.updateBitmapCache(true); this.invalidate(); if(this.drawToBackgroundEnabled){ var winform = owner[["_parentForm"]]; winform.background.update(); } }; _beforeDpiChanged = function(scaleX,scaleY,origScaleX,origScaleY){ this[["(iconFont)"]] = null; this[["(iconFontOrig)"]] = null; }; updateBitmapCache = function(erase){ if( owner._closed ) return; if( this.$bitmapCacheUpdating ) return; if( this.cacheBitmap ) { ..gdip.DeleteCachedBitmap(this.cacheBitmap); this.cacheBitmap = null; } if( !..win.isWindow(this.hwnd) ) return; var foreground = this[["(foreground)"]]; var background = this[["(background)"]]; var rcClient = this.getClientRect(); var rc = rcClient.copy(); var width,height = rc.right - rc.left,rc.bottom - rc.top; var bmpMem = ..gdip.bitmap(width,height); if( !bmpMem ) return; var graphics = bmpMem.graphics; graphics.smoothingMode = this.smoothingMode; graphics.compositingQuality = 2/*_GdipCompositingQualityHighQuality*/; graphics.textRenderingHint = this.textRenderingHint; graphics.interpolationMode = this.interpolationMode;; var winform = owner[["_parentForm"]]; var clipBk = erase && !this.transparent && winform && this.clipBk && (!this.cacheOrphanWindowRect__ ); var clipBkRect; if( clipBk && winform.background ){ var hdc = graphics.getDc(); if(!hdc) return; clipBkRect = ..win.getRect(owner.hwnd); if( this.parent != winform) ..win.mapRect(this.parent.hwnd,winform.hwnd,clipBkRect); winform.background.drawRect(hdc, clipBkRect); graphics.releaseDc(hdc); } if( this.scale ) graphics.scaleRect(rc,this.scale,this.scale); if( this.argbColor === null ) this.argbColor = 0xFF000000; this.$bitmapCacheUpdating = true; var dpiScaleX,dpiScaleY = (this.dpiScaleX : 1) ,(this.dpiScaleY : 1); var cancel; if( this.onDrawBackground ){ cancel = this.onDrawBackground(graphics,rc,this.backgroundColor,this.argbColor) } if( ! cancel ){ if( background ? background.isValid() ){ graphics.drawBackground(background,this["(repeat)"] ,rc,this.bkTop,this.bkRight,this.bkBottom,this.bkLeft ,null,dpiScaleX,dpiScaleY); } elseif( ( this.backgroundColor !== null ) && ( this.mode != "trackbar" ) ){ var pixelOffsetMode = graphics.pixelOffsetMode; graphics.pixelOffsetMode = 4/*_PixelOffsetModeHalf*/; if( ( this.linearGradient !== null ) && (this.foregroundColor!==null)){ if(this.linearGradient>=0){ var rf = rc.float(); rf.angle = this.linearGradient; var brush = ..gdip.lineBrush(rf,this.backgroundColor,this.foregroundColor); if(dpiScaleY > 1 && height <= 2 && height!=dpiScaleY ){ height = dpiScaleY; } if(dpiScaleX > 1 && width <= 2 && width!=dpiScaleX ){ width = dpiScaleX; } graphics.fillRectangle( brush,0,0,width,height); brush.delete(); } else { var pathGradient = ..gdip.path(); pathGradient.addEllipse(rc.left,rc.top,rc.width(),rc.height()); var brush = ..gdip.pathGradientBrush(pathGradient); brush.setCenterColor(this.backgroundColor); brush.setSurroundColors(this.foregroundColor); brush.gammaCorrection = true; graphics.fillEllipse(brush,0,0,width,height); brush.delete(); pathGradient.delete(); } } elseif( ! this[["(progress-clip-path)"]] ) { var brush = ..gdip.solidBrush(this.backgroundColor); graphics.fillRectangle( brush,0,0,width,height); brush.delete(); } graphics.pixelOffsetMode = pixelOffsetMode; } } var paddingTop,paddingBottom,paddingLeft,paddingRight = owner.paddingTop*dpiScaleY,owner.paddingBottom*dpiScaleY ,owner.paddingLeft*dpiScaleX,owner.paddingRight*dpiScaleX; var rcText; var text = this[["(text)"]]; if( #text or this.onDrawString ){ var x,y = paddingLeft,paddingTop; if( ( background ? this.state[["active"]] ? (!this[["(progress-range)"]]) ) ) { x++;y++; }; rcText = ::RECTF(x,y,width - x - paddingRight,height - y - paddingBottom); } var rcContent = ::RECT(); rcContent.right = rc.right - paddingRight; rcContent.bottom = rc.bottom - paddingBottom; rcContent.left = paddingLeft; rcContent.top = paddingTop; cancel = false; if( this.onDrawContent ){ cancel = this.onDrawContent(graphics,rc,this.argbColor,rcContent,this.foregroundColor,this[["(font)"]]) } if( ! cancel ){ var hasForeground = foreground ? foreground.isValid(); var pixelOffsetMode = graphics.pixelOffsetMode; graphics.pixelOffsetMode = 2/*_PixelOffsetModeHighQuality*/ if( this[["(progress-range)"]] && this[["(progress-pos)"]]!== null && this.mode ){ var rcTrackBar; var rc = {left=paddingLeft;top=paddingTop; right=width - paddingRight;bottom=height- paddingBottom}; var w = rc.right - rc.left; var h = rc.bottom - rc.top; var r = (this[["(progress-pos)"]])/(this[["(progress-range)"]]); var path = this[["(progress-clip-path)"]]; if( path && this.mode=="pie" ){ path.reset(); if(this.backgroundColor!==null){ path.addEllipse(rc.left,rc.top,w,h); graphics.setClipPath(path,0/*_GdipCombineModeReplace*/); var brush = ..gdip.solidBrush(this.backgroundColor); graphics.fillEllipse( brush,0,0,width,height); brush.delete(); } path.reset(); path.addPie( rc.left ,rc.top,w,h,90,360 * r ); graphics.setClipPath(path,1/*_CombineModeIntersect*/); } else{ if( this.mode = "trackbar" ){ var bx,by,bcx,bcy; if( r > 1 ) r = 1; if( w > h ){ var foreRight = this.foreRight*dpiScaleX; var p = (this.foreLeft*dpiScaleX) + (foreRight); rc.right = rc.left + (w - p) * r + p; if(rcText && this.align == "right") rcText.width = rc.right - rcText.x; bx,by,bcx,bcy = 0,rc.top,width,rc.bottom-rc.top; if( (!hasForeground) && this.foreRight){ var left = rc.right - (foreRight); rcTrackBar = ::RECT(left,0,left+foreRight,height); } } else { var foreTop = this.foreTop*dpiScaleY; var p = foreTop + this.foreBottom*dpiScaleY; rc.top = rc.bottom - ( h - p) * r - p ; if(rcText && this.valign == "top") { rcText.y = rc.top; rcText.height = rc.bottom - rc.top; }; bx,by,bcx,bcy = rc.left,0,rc.right-rc.left,height; if((!hasForeground) && this.foreTop){ rcTrackBar = ::RECT(0,rc.top,width,rc.top+foreTop); } } if(this.backgroundColor!==null){ if( (this.linearGradient>=0) && (this.foregroundColor!=null) ) { var rf = ::RECTF(bx,by,bcx,bcy); rf.angle = this.linearGradient; var brush = ..gdip.lineBrush(rf,this.backgroundColor,this.foregroundColor); graphics.fillRectangle(brush,bx,by,bcx,bcy); brush.delete(); } else { var brush = ..gdip.solidBrush(this.backgroundColor); graphics.fillRectangle( brush,bx,by,bcx,bcy); brush.delete(); } } } else{ if( w > h ){ w = ( w - this.foreLeft ) * r + this.foreLeft; graphics.setClipRect(rc.left,rc.top,w,h,0/*_GdipCombineModeReplace*/); if(rcText && this.align == "right") { rcText.width = ( rc.left + w ) - rcText.x }; } else { var top = rc.bottom - ( h - this.foreBottom ) * r - this.foreBottom; graphics.setClipRect(rc.left,top,w,rc.bottom,0/*_GdipCombineModeReplace*/); if(rcText && this.valign == "top") { rcText.y = top; rcText.height = rc.bottom - top; }; } } } if(hasForeground){ graphics.drawBackground(foreground,this["(foreRepeat)"] ,rc,this.foreTop,this.foreRight,this.foreBottom,this.foreLeft,this.imageAttributes ,dpiScaleX,dpiScaleY); } else { if( this.linearGradient === null ){ var brush = ..gdip.solidBrush(this.foregroundColor); graphics.fillRectangle( brush,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top); brush.delete() } if(rcTrackBar && this.argbColor){ var brush = ..gdip.solidBrush(this.argbColor); if(this.border[["radius"]]){ if(this.border[["radius"]]<0){ graphics.fillEllipse( brush,rcTrackBar.xywh() ); } else { var path = ..gdip.path(1/*_FillModeWinding*/) path.addRoundRect(rcTrackBar,this.border.radius*dpiScaleX); graphics.fillPath(brush,path); path.delete(); } } else { graphics.fillRectangle( brush,rcTrackBar.xywh() ); } brush.delete(); } } graphics.resetClip(); } elseif(hasForeground){ var rc = rc; if( this["(foreRepeat)"] != "point"){ rc = ::RECT(paddingLeft,paddingTop,width - paddingRight,height- paddingBottom); } elseif( background ? #text ? this.state[["active"]] ){ rc.left = rc.left + 1; rc.top = rc.top + 1; } if( this.border[["radius"]] && this.border[["radius"]] < 0 ){ if( graphics.transform(this["(foreRepeat)"],foreground,rc,this.x,this.y) ){ var textureBrush = ..gdip.textureBrush(foreground,this.imageAttributes ); graphics.fillEllipse(textureBrush,0,0,foreground.width,foreground.height); textureBrush.delete(); graphics.resetTransform(); if( this.scale ) graphics.scaleRect(rcClient,this.scale,this.scale); } else { var bmpMem2 = ..gdip.bitmap(foreground.width,foreground.height); var textureBrush = ..gdip.textureBrush(foreground,this.imageAttributes); var g = bmpMem2.getGraphics(); g.smoothingMode = this.smoothingMode; g.fillEllipse(textureBrush,0,0,foreground.width,foreground.height); textureBrush.delete(); graphics.drawBackground(bmpMem2,this["(foreRepeat)"] ,rc,this.foreTop,this.foreRight,this.foreBottom,this.foreLeft ,null,dpiScaleX,dpiScaleY); bmpMem2.dispose(); } } elseif( this["(foreRepeat)"] == "point"){ graphics.drawImagePoint(foreground,rc,this.x,this.y,this.imageAttributes,dpiScaleX,dpiScaleY) } else { graphics.drawBackground(foreground,this["(foreRepeat)"] ,rc,this.foreTop,this.foreRight,this.foreBottom,this.foreLeft,this.imageAttributes ,dpiScaleX,dpiScaleY); } } elseif( this.foregroundColor !== null ){ if( this.linearGradient === null ){ var rc = ::RECT(paddingLeft,paddingTop,width - paddingRight,height- paddingBottom); var brush = ..gdip.solidBrush(this.foregroundColor); if( this.border[["radius"]] && this.border[["radius"]] < 0 ){ graphics.fillEllipse(brush,rc.xywh()); } else { graphics.fillRectangle(brush,rc.xywh()); } brush.delete(); } } if( this.onDrawForegroundEnd ){ this.onDrawForegroundEnd(graphics,rc,rcContent); } graphics.pixelOffsetMode = pixelOffsetMode; } if( type(this.border) == "table" ){ var pixelOffsetMode = graphics.pixelOffsetMode; graphics.pixelOffsetMode = 3/*_PixelOffsetModeNone*/; var border = this.border; var left,top,right,bottom = border.left,border.top,border.right,border.bottom; var width = border.width; if(left==top && top==right && right==bottom){ if(!width) width = left; if( width && border.color ){ var width = width * dpiScaleX; var w1 = ..math.floor((width-1)/2); var w2 = ..math.ceil(width/2); var rc = ::RECT(rc.left+w1,rc.top+w1,rc.right-w2,rc.bottom-w2); if( border.radius && ( border.radius > 0 ) ){ var pen = ..gdip.pen(border.color,width); var pathRadius = ..gdip.path(1/*_FillModeWinding*/) pathRadius.addRoundRect(rc,this.border.radius*dpiScaleX); graphics.drawPath(pen,pathRadius); pathRadius.delete(); pen.delete() } else { var pen = ..gdip.pen(border.color,width); graphics.drawRectangle(pen,rc.left,rc.top,rc.width(),rc.height()); pen.delete(); } } } else{ var padding = border.padding : 0; if( width ){ if( left === null ) left = width; if( top === null ) top = width; if( right === null ) right = width; if( bottom === null ) bottom = width; } if( left ){ left = left * dpiScaleX; var w = ..math.floor((left-1)/2); var color = border.leftColor ; if( color === null ) color = border.color; if( color != null ) { var pen = ..gdip.pen( color,left); graphics.drawLine(pen,rc.left+w,rc.top-1+padding*dpiScaleY,rc.left+w,rc.bottom-padding*dpiScaleY); pen.delete(); } } if( top ){ top = top * dpiScaleY; var w = ..math.floor((top-1)/2); var color = border.topColor ; if( color === null ) color = border.color; if( color != null ) { var pen = ..gdip.pen( color,top); graphics.drawLine(pen,rc.left-1+padding*dpiScaleX,rc.top+w,rc.right-padding*dpiScaleX,rc.top+w); pen.delete(); } } if( right ){ right = right * dpiScaleX; var w = ..math.ceil(right/2); var color = border.rightColor ; if( color === null ) color = border.color; if( color != null ) { var pen = ..gdip.pen( color,right); graphics.drawLine(pen,rc.right-w,rc.top-1+padding*dpiScaleY,rc.right-w,rc.bottom-padding*dpiScaleY); pen.delete(); } } if( bottom ){ bottom = bottom * dpiScaleY; var w = ..math.ceil(bottom/2); var color = border.bottomColor ; if( color === null ) color = border.color; if( color != null ) { var pen = ..gdip.pen( color,bottom); graphics.drawLine(pen,rc.left-1+padding*dpiScaleX,rc.bottom-w,rc.right-padding*dpiScaleX,rc.bottom-w); pen.delete(); } } } graphics.pixelOffsetMode = pixelOffsetMode; } if( this[["(iconText)"]] && this.iconStyle ){ var iconStyle = this.iconStyle; var strformat = ..gdip.stringformat(); strformat.align = __stringAlignment[ iconStyle.align : "center" ] strformat.lineAlign = __stringAlignment[ iconStyle.valign : "center" ] var padding = iconStyle.padding; var x,y = (padding[["left"]]:0)*dpiScaleX,(padding[["top"]]:0)*dpiScaleY; var rcText = ::RECTF(x,y,width - x - ((padding[["right"]]:0)*dpiScaleX),height- y - ((padding[["bottom"]]:0)*dpiScaleY)); if( background ? this.state[["active"]] ){ rcText.x = rcText.x + 1; rcText.y = rcText.y + 1; } if( iconStyle.font ) { var color = this.iconColor if(color===null)color=this.argbColor; var brush = ..gdip.solidBrush(color); if((!this[["(iconFont)"]]) || (this[["(iconFontOrig)"]]!=iconStyle.font) ){ var hdc = ::GetDC(owner.hwnd); if(!::LOGFONT.is(iconStyle.font)) iconStyle.font = ::LOGFONT(iconStyle.font); iconStyle.font.stripPoint(hdc); var h = iconStyle.font.h; if( this.dpiScaleY ) iconStyle.font.h = h * this.dpiScaleY; this[["(iconFont)"]] = ..gdip.font( hdc,iconStyle.font ); this[["(iconFontOrig)"]] = iconStyle.font; iconStyle.font.h = h; ::ReleaseDC(owner.hwnd,hdc); } var hint = graphics.textRenderingHint; graphics.textRenderingHint = this.iconTextRenderingHint; graphics.drawString( this[["(iconText)"]],this[["(iconFont)"]],rcText, strformat,brush); graphics.textRenderingHint = hint; brush.delete(); } strformat.delete(); } if( rcText ){ var strformat = ..gdip.stringformat(); strformat.align = __stringAlignment[ this.align : "center" ] strformat.lineAlign = __stringAlignment[ this.valign : "center" ] strformat.hotkeyPrefix = this.hotkeyPrefix; strformat.flags = this.stringFormatFlags; if(this.trimming!==null) strformat.trimming = this.trimming; var brush = ..gdip.solidBrush( this.argbColor ); if( this[["(font)"]] ) { var p = this.textPadding; if( p ){ ..table.mix(p,{left=0;top=0;right=0;bottom=0}); rcText.x = rcText.x + p.left*dpiScaleX; rcText.y = rcText.y + p.top*dpiScaleY; rcText.width = rcText.width - p.left*dpiScaleX - p.right*dpiScaleX; rcText.height = rcText.height - p.top*dpiScaleY - p.bottom*dpiScaleY; } if( !this.onDrawString ){ var map = this.fontCharMap; if(map){ var w = rcText.width/#text; var rc = ::RECT(rcText.x,rcText.y,rcText.x+w,rcText.y+rcText.height) ..string.replace(text,":|.",function(c){ if(map[c]){ graphics.drawBackground(map[c],"scale",rc,,,,,,dpiScaleX,dpiScaleY); rc.offset(w,0); } }) } else { graphics.drawString( text ,this[["(font)"]],rcText, strformat,brush); } } else{ this.onDrawString(graphics,text,this[["(font)"]],rcText, strformat,brush) } } brush.delete(); strformat.delete(); } if( this.border[["radius"]] && this.border[["radius"]] > 0 ){ var rc = rcClient; var width,height = rc.right - rc.left,rc.bottom - rc.top; var bmpMem2 = ..gdip.bitmap(width,height); var path = ..gdip.path(1/*_FillModeWinding*/) path.addRoundRect(rc,this.border.radius*dpiScaleX); var textureBrush = ..gdip.textureBrush( bmpMem ); var g = bmpMem2.getGraphics(); g.pixelOffsetMode = 2/*_PixelOffsetModeHighQuality*/; g.smoothingMode = this.smoothingMode; if( clipBkRect ){ var hdc = g.getDc(); winform.background.drawRect(hdc,clipBkRect); g.releaseDc(hdc); } g.fillPath(textureBrush,path); textureBrush.delete(); path.delete(); if( this.onDrawEnd ){ this.onDrawEnd(g,rc,bmpMem2); } bmpMem.dispose(); bmpMem = bmpMem2; } else { if( this.onDrawEnd ){ this.onDrawEnd(graphics,rcClient,bmpMem); } } graphics.delete(); if( this.cacheOrphanWindowRect__ && ..win.getStyleEx(this.hwnd,0x80000/*_WS_EX_LAYERED*/) ){ ..gdi.layeredBuffer( this.hwnd, function( hdc,hMemDc,hMemBitmap,width,height ){ var graphics = ..gdip.graphics(hMemDc); graphics.drawImage(bmpMem); graphics.delete(); ..gdi.updateLayeredWindow( this.hwnd,hMemDc,::SIZE(width,height) ,..gdi.blendFunction() ); } ) bmpMem.dispose(); this.cacheBitmap = null; } else { graphics = ..gdip.graphics(this) this.cacheBitmap = graphics.createCachedBitmap(bmpMem); graphics.delete(); bmpMem.dispose(); } this.cacheBitmapWidth = width; this.cacheBitmapHeight = height; this.$bitmapCacheUpdating = false; return this.cacheBitmap; }; drawToDevice = function(hdc,x,y){ if(x===null)x,y = owner.getPos(); var graphics = ..gdip.graphics(hdc); var cacheBitmap = owner.cacheBitmap : owner.predraw(); if(cacheBitmap) graphics.drawCachedBitmap(cacheBitmap,x,y); graphics.delete(); }; drawToGraphics = function(graphics,x,y){ if(x===null)x,y = owner.getPos(); var cacheBitmap = owner.cacheBitmap : owner.predraw(); if(cacheBitmap) graphics.drawCachedBitmap(cacheBitmap,x,y); }; directDrawBackgroundOnly = function(){ if(this.drawToBackgroundEnabled) return; if( !..win.getStyle(this.hwnd,0x40000000/*_WS_CHILD*/) ) return; this.clipBk = false; this.drawToBackgroundEnabled = true; this.modifyStyleEx(,0x20/*_WS_EX_TRANSPARENT*/) this.wndproc = { [ 0xF/*_WM_PAINT*/] = function (hwnd, message, wParam, lParam) { var ps = ::PAINTSTRUCT(); var hdc,ps = ::BeginPaint(hwnd, ps); ::EndPaint(hwnd, ps); return 1; } } owner.onDirectDrawBackground = function(hdc,graphics){ if(graphics) return owner.drawToGraphics(graphics); graphics = ..gdip.graphics(hdc); owner.drawToGraphics(graphics); graphics.delete(); } }; onCreated = function () { this.wndproc = { [ 0xF/*_WM_PAINT*/] = function (hwnd, message, wParam, lParam) { ..gdi.paintBuffer( hwnd, function( hdc,hMemDc,hMemBitmap,width,height,rcPaint,fErase,paintStruct ){ if( ! ( (width == this.cacheBitmapWidth) && (height == this.cacheBitmapHeight ) ) ){ this.updateBitmapCache(); } if(this.cacheBitmap){ var graphics = ..gdip.graphics(hMemDc); graphics.setClipRect( rcPaint.left,rcPaint.top,rcPaint.right,rcPaint.bottom,0/*_GdipCombineModeReplace*/); graphics.drawCachedBitmap(this.cacheBitmap,0,0); graphics.delete(); } } ); return 1; } [ 0x14/*_WM_ERASEBKGND*/] = function (hwnd, uMsg, wParam, lParam) { return 0; } [ 0xC/*_WM_SETTEXT*/ ] = function (hwnd, uMsg, wParam, lParam) { if(lParam){ var text = ..string.fromUtf16( topointer(lParam),,true ); if( text != this[["(text)"]] || owner[["(cueBanner)"]] ){ if(owner[["(editable)"]] ) { if( owner[["(cueBanner)"]] ){ if( text==""){ owner.editBox.text = ""; owner.editBox._precommand(,0x200/*_EN_KILLFOCUS*/); } elseif(owner.cueBannerTextShowing ){ owner.editBox._precommand(,0x100/*_EN_SETFOCUS*/); owner.editBox.text = text; } else { owner.editBox.text = text; } } else{ owner.editBox.text = text; } } else{ this[["(text)"]] = text; this.redrawTransparent(); } } } } [ 0x84/*_WM_NCHITTEST*/ ] = function (hwnd, uMsg, wParam, lParam) { if( !this.notify ) return 0xFFFFFFFF/*_HTTRANSPARENT*/; return 1/*_HTCLIENT*/ } [ 0x87/*_WM_GETDLGCODE*/ ] = function (hwnd, uMsg, wParam, lParam) { if(owner.mode="trackbar"){ return 1/*_DLGC_WANTARROWS*/ } return this.notify? 0x2000/*_DLGC_BUTTON*/ : 0x100/*_DLGC_STATIC*/; } [ 0x20/*_WM_SETCURSOR*/ ] = function (hwnd, uMsg, wParam, lParam) { if( this.isHyperlink() ){ ::SetCursor( __cursor_hand ); return true; } } [0x233/*_WM_DROPFILES*/] = function(hwnd, uMsg, wParam, lParam){ if( this[["onDropFiles"]] ) this.onDropFiles( ..win.getDropFile(wParam) ); } } if( this.notify ){ ..win.ui.tracker(this); } if( this[["editable"]] ){ var cls = this[["editable"]]; this[["editable"]] = null; this.createEditBox( cls = ( cls==="edit"?cls:null ) ); } if(this.onPlusCreated)this.onPlusCreated(); this.predraw();//不加会导致WS_POPUP上TextRenderingHintClearTypeGridFit出现残影 }; _onDestroy = function(){ var foreground = this[["(foreground)"]]; var background = this[["(background)"]]; this[["(foreground)"]] = null; this[["(background)"]] = null; if( this.cacheBitmap ) { var cacheBitmap = this.cacheBitmap; this.cacheBitmap = null; ..gdip.DeleteCachedBitmap(cacheBitmap); } if( this[["(progress-clip-path)"]]) this[["(progress-clip-path)"]].delete(); if( this["(font)"] ) { this["(font)"].delete(); this["(font)"] = null; } if(this[["(iconFont)"]]){ this[["(iconFont)"]].delete(); this[["(iconFont)"]] = null; this[["(iconFontOrig)"]] = null; } if(this.animationId) this.clearInterval(this.animationId); }; @_metaProperty } namespace plus { _metaProperty = ..win.ui.ctrl.metaProperty( _onStateChange = function(state){ if(!state) state = owner.state; var setting = owner[["(skin-setting)"]]; if( setting ){ var text = owner[["(unchecked-text)"]]; var iconText = owner[["(unchecked-iconText)"]]; if( owner.state.checked ) { setting = setting[["checked"]] : setting; text = owner[["(checked-text)"]]; iconText = owner[["(checked-iconText)"]]; }; if( text && ( text != owner[["(text)"]] ) ){ owner.text = text; } if( iconText ){ owner[["(iconText)"]] = iconText; } var bt = setting[["background"]]; var ft = setting[["foreground"]]; var ct = setting[["color"]]; var ci = setting[["iconColor"]]; var dt = setting[["border"]]; var st = setting[["scale"]]; var getStyle = function(t,k){ if( k && t[[k]]!==null ) return t[[k]]; if( t[["focus"]] !==null ) return t[["focus"]]; return t[["default"]] } var b,f,c,i,d,s; if( state.disabled ) { b = bt[["disabled"]] f = ft[["disabled"]] c = ct[["disabled"]] i = ci[["disabled"]] d = dt[["disabled"]] s = st[["disabled"]] } elseif( state.active ){ b = getStyle(bt,"active"); f = getStyle(ft,"active"); c = getStyle(ct,"active"); i = getStyle(ci,"active"); d = getStyle(dt,"active"); s = getStyle(st,"active"); } elseif( state.hover ){ b = getStyle(bt,"hover"); f = getStyle(ft,"hover"); c = getStyle(ct,"hover"); i = getStyle(ci,"hover"); d = getStyle(dt,"hover"); s = getStyle(st,"hover"); } elseif( state.focus ){ b = getStyle(bt); f = getStyle(ft); c = getStyle(ct); i = getStyle(ci); d = getStyle(dt); s = getStyle(st); } else { b = bt[["default"]] f = ft[["default"]] c = ct[["default"]] i = ci[["default"]] d = dt[["default"]] s = st[["default"]] } owner.scale = s; if(dt) owner.border = d; if(bt) owner.setBackground(b,,false); if(ft) owner.setForeground(f,,false); owner.iconColor = i : ci[["default"]]; owner.argbColor = c : ct[["default"]]; if( owner.onStateChange ) owner.onStateChange(state); var newStyle = { b = b; f = f; c = c; i = i; d = d; s = s; t = owner[["(iconText)"]]; } var preStyle = owner[["(preStyle)"]]; if( ( preStyle[["b"]] != newStyle.b ) || ( preStyle[["f"]] != newStyle.f ) || ( preStyle[["c"]] != newStyle.c ) || ( preStyle[["i"]] != newStyle.i ) || ( preStyle[["d"]] != newStyle.d ) || ( preStyle[["s"]] != newStyle.s ) || ( preStyle[["t"]] != newStyle.t ) ){ owner.redrawTransparent(); }; owner[["(preStyle)"]] = newStyle; return; } if( owner.onStateChange ) owner.onStateChange(state); }; checked = { _get = function () { return owner.state.checked; } _set = function (v) { if(v!=owner.state.checked){ owner.notify = true; if( v ? owner.radioGroup ){ owner.radioClick() } else owner.state.checked = v; owner._onStateChange(owner.state); } } }; oncommand = { _get = lambda () null; _set = function(v){ owner.notify = true; owner[["oncommand"]] = v; } }; notify = { _get = lambda () null; _set = function(v){ if( v && !owner.notify ) { ..win.ui.tracker(owner); } owner[["notify"]] = v; } }; skin = { _get = function(ownerCall){ if(ownerCall) return owner.setSkin; else return owner.getSkin(); } _set = function(v){ owner.setSkin(v); } }; getSkin = lambda () (owner[["(skin-setting)"]] || { background = { default = owner.background}; foreground = { default = owner.foreground}; color = { default = owner.argbColor}; iconColor = owner.iconColor; iconStyle = owner.iconStyle; }); setSkin = function(s,clone){ if( type(s) != "table" ) { error("参数 @1 类型错误",2); } if(s.hwnd){ s = s[["(skin-setting)"]] if(!s) error("参数 @1 指定的源控件没有找到可复制的样式!",2); } if( s.group ) owner.radioGroup = s.group; if(clone){ s = ..table.clone(s); } owner[["(checked-text)"]] = null; owner[["(checked-iconText)"]] = null; if(s.iconStyle) owner.iconStyle = s.iconStyle; if(s.iconText) owner.iconText = s.iconText; if(s.font) owner.font = s.font; //@AIFIX if(s.textPadding) owner.textPadding = s.textPadding //@AIFIX if(s.text) owner.text = s.text; if( s.checked ){ if( type(s.checked) != type.table) error("checked字段必须是表对象",2); if( !s.checked.color ) s.checked.color = {}; var iconTextChk = s.checked.iconText; if( #iconTextChk ){ if(!owner[["(unchecked-iconText)"]] ){ owner[["(unchecked-iconText)"]] = s.iconText : owner.iconText; if(!owner[["(unchecked-iconText)"]] ){ //@Deprecated if(iconTextChk=='\uF14A') owner[["(unchecked-iconText)"]] = '\uF0C8' //@Deprecated elseif(iconTextChk=='\uF058') owner[["(unchecked-iconText)"]] = '\uF111' //@Deprecated if(owner[["(unchecked-iconText)"]]) { //@Deprecated owner.iconTextRenderingHint = 3; //@Deprecated if(!owner.iconStyle){ //@Deprecated owner.iconStyle = {align="left";font=LOGFONT(h=-15;name='FontAwesome')}; } } } } owner[["(checked-iconText)"]] = iconTextChk; } if( #s.checked.text ){ var current = owner[["(unchecked-text)"]] : owner.text; var ck = s.checked.text; var unck = s.text; var a = ..string.split(current," ",2); if( #a == 2 ){ if( ck && ! ..string.indexOf(ck," ") ){ ck = ck + " " + a[#a]; } if( unck && ( !..string.indexOf(unck," ") ) ){ unck = unck + " " + a[#a]; } } if(!owner[["(unchecked-text)"]] ){ owner[["(unchecked-text)"]] = unck : owner.text; } owner[["(checked-text)"]] = ck; } if( s.checked.border ) if(!s.border)s.border={}; if( s.checked.background ) if(!s.background)s.background={}; if( s.checked.foreground ) if(!s.foreground)s.foreground={}; } if(!owner[["(checked-text)"]]) { if(owner[["(unchecked-text)"]] ) owner.text = owner[["(unchecked-text)"]]; owner[["(unchecked-text)"]] = null; } if(!owner[["(checked-iconText)"]]) { if(owner[["(unchecked-iconText)"]] ) owner.text = owner[["(unchecked-iconText)"]]; owner[["(unchecked-iconText)"]] = null; } if( s.background ) { if( s.background.default === null ) { s.background.default = owner.getBackground() : owner.backgroundColor; } elseif(!owner[["(skin-setting)"]]){ var old = owner.setBackground(s.background.default,,false); //if( old ? ( ! old.isCached() ) ) { old.dispose(); } } }; if( s.foreground ){ if( s.foreground.default === null ) { s.foreground.default = owner.getForeground(); } elseif(!owner[["(skin-setting)"]]){ var old = owner.setForeground(s.foreground.default,,false); //if( old ? ( ! old.isCached() ) ) { old.dispose(); } } } if( s.border ){ if( s.border.default === null ) { s.border.default = owner.border; } } if( !s.color ) s.color = {}; ..table.mix( s.color,{ default = owner.argbColor;disabled = ::GetSysColor(0x11/*_COLOR_GRAYTEXT*/)| ( 0xFF << 24 ) } ); if( s.checked ){ if( s.checked.color.default=== null ) s.checked.color.default = s.color.default; } if( owner.iconColor ) { s.iconColor = ..table.mix(s.iconColor,{default=owner.iconColor} ); } owner[["(skin-setting)"]] = s; //开启[事件回调属性 owner.notify = true; owner._onStateChange(owner.state); }; background = { _get = function () { return owner.getBackground() || owner.backgroundColor; } _set = function (v) { var old = owner.setBackground(v,,!owner[["initializing"]]); //if( old ? ( ! old.isCached() ) ) { old.dispose(); } } } foreground = { _get = function () { return owner.getForeground() || owner.foregroundColor; } _set = function (v) { var old = owner.setForeground(v,, !owner[["initializing"]]); //if( old ? ( ! old.isCached() ) ) { old.dispose(); } } } repeat = { _get = function () { return owner.getRepeat(); } _set = function (v) { owner.setRepeat(v, !owner[["initializing"]]); } } getRepeat = function(){ return owner[["(repeat)"]]; }; setRepeat = function(v,redraw=true){ owner[["(repeat)"]] = v; if( redraw ) owner.redrawTransparent(); }; foreRepeat = { _get = function () { return owner.getForeRepeat(); } _set = function (v) { owner.setForeRepeate(v, !owner[["initializing"]]); } } getForeRepeat = function(){ return owner[["(foreRepeat)"]]; }; setForeRepeate = function(v,redraw=true){ owner[["(foreRepeat)"]] = v; if( redraw ) owner.redrawTransparent(); }; getBackground = function(){ return owner[["(background)"]]; }; setBackground = function(bmp,cacheName,redraw=true){ var background = owner[["(background)"]]; if( bmp === (background || owner.backgroundColor ) ) return; if(type(bmp)==type.number){ if( background ) background.stopAnimation(); owner[["(background)"]] = null; if( bmp == owner.backgroundColor ) return; owner.backgroundColor = bmp; if( redraw ) owner.redrawTransparent(); return; } owner.backgroundColor = null; var old = background; if( bmp ){ background = ..gdip.loadCachedBitmap(bmp,cacheName); if( background ){ if( old ) old.stopAnimation(); if( owner.animation === null || (owner.animation) ){ background.createAnimation(owner,owner.redrawTransparent); } owner[["(background)"]] = background; } else { return; } } else { owner[["(background)"]] = null; } if( redraw ) owner.redrawTransparent(); return old; }; getForeground = function(){ return owner[["(foreground)"]]; }; setForeground = function(bmp,cacheName,redraw=true){ var foreground = owner[["(foreground)"]]; if( bmp === (foreground || owner.foregroundColor ) ) return; if(type(bmp)==type.number){ if( foreground ) foreground.stopAnimation(); owner[["(foreground)"]] = null; if( bmp == owner.foregroundColor ) return; owner.foregroundColor = bmp; if( redraw ) owner.redrawTransparent(); return; } owner.foregroundColor = null; var old = foreground; if( bmp ){ foreground = ..gdip.loadCachedBitmap(bmp,cacheName); if( foreground ){ if( old ) old.stopAnimation(); if( owner.animation === null || (owner.animation) ){ foreground.createAnimation(owner,owner.redrawTransparent); } owner[["(foreground)"]] = foreground; } else { return; } } else { owner[["(foreground)"]] = null; } if( redraw ) owner.redrawTransparent(); return old; }; isHyperlink = function(){ return ( owner.notify ? (#owner[["(text)"]]||#owner[["(iconText)"]]) ? ( !owner[["(background)"]] ) ? ( !owner[["(foreground)"]] ) ); }; setFocus = function(text){ if(text!==null){owner.text=text} if(owner[["editBox"]]) return owner.editBox.setFocus(); ..win.setFocus(owner.hwnd) }; createEditBox = function(p){ if( ( p !== null ) && (type(p) != type.table) ) error("参数错误",2) if(owner[["editBox"]]){ if(p===null) return owner.editBox; owner[["(editable)"]] = null; owner.editBox.close(); } var tp = owner.textPadding : {left=0;right=0;top=0;bottom=0};; var margin = { marginLeft=(owner.paddingLeft + (tp[["left"]]:0))*owner.dpiScaleX; marginRight=(owner.paddingRight + (tp[["right"]]:0))*owner.dpiScaleX; marginBottom=(owner.paddingBottom + (tp[["bottom"]]:0))*owner.dpiScaleY; marginTop=(owner.paddingTop + (tp[["top"]]:0))*owner.dpiScaleY; } var param = ..table.assign({ hidesel = owner.hidesel; align=owner.align : "center"; color=owner.color; font=owner.getFont(true); disabled=owner.disabled; multiline=owner.multiline; autovscroll=owner.autovscroll; autohscroll=owner.autohscroll; hscroll=owner.hscroll; vscroll=owner.vscroll; password=owner.password; wrap=owner.wrap; link=owner.link; tabstop=owner.tabstop; num=owner.num; dpiScaleX=owner.dpiScaleX; dpiScaleY=owner.dpiScaleY; },p,margin); if(!param.cls){ param.cls="richedit" } if(param.cls=="richedit" ){param.transparent=true;} else { if( (owner.backgroundColor !== null) && (0xFF000000 >>> 24 == 0xFF ) ){ param.bgcolor = ..gdi.rgbReverse(owner.backgroundColor); } } var text = owner.text; if(#text){owner.text = "";} param.text = text; owner.addCtrl({editBox = param}); if(owner[["editBox"]].enablePopMenu) owner[["editBox"]].enablePopMenu(); owner.translateCommand(); owner[["(editable)"]] = param.cls="richedit"?1:"edit"; owner.notify = true; var this = owner; owner[["editBox"]]._onStateChange = function(state){ this.state.focus = state.focus; if(this.editState===false) return this._onStateChange(); var hover = state.hover; state.hover = this.state.hover : state.hover; this._onStateChange(state); state.hover = hover; } owner[["editBox"]] = ..win.ui.tracker(owner[["editBox"]]); var rc = owner.getClientRect(); rc.left = rc.left + margin.marginLeft; rc.top = rc.top + margin.marginTop; rc.right = rc.right - margin.marginRight; rc.bottom = rc.bottom - margin.marginBottom; owner[["editBox"]].setRect(rc); return owner[["editBox"]]; }; passwordChar = { _get = function(){ return owner.editBox.passwordChar}; _set = function( v ){ if(!owner.cueBannerTextShowing) { owner.editBox.passwordChar = v; owner.editBox.redrawTransparent(); } owner[["(cueBannerPwdChr)"]] = v; } }; setCueBannerText = function(txt,color){ var this = owner; var ed = owner.editBox; this[["(cueBanner)"]] = txt; if(!txt){ this[["(cueBannerColor)"]] = null; return; } this[["(cueBannerColor)"]] = color===null?0x999999:color; if(!ed._precommand){ ed._precommand = function(id,ev){ if(ev==0x200/*_EN_KILLFOCUS*/){ if(ed.text==""){ if(ed.cls==="richedit"){ this.argbColor = ..gdi.argbReverse(this[["(cueBannerColor)"]]); this[["(text)"]] = this[["(cueBanner)"]]; this.redrawTransparent(); } else { ed.color = this[["(cueBannerColor)"]]; this[["(cueBannerPwdChr)"]] = ed.passwordChar; ed.passwordChar = null; ed.text = this[["(cueBanner)"]]; } this.cueBannerTextShowing = true; } } elseif(ev==0x100/*_EN_SETFOCUS*/){ if(this.cueBannerTextShowing){ this.cueBannerTextShowing = false; if(ed.cls==="richedit"){ this[["(text)"]] = ""; this.redrawTransparent(); } else { ed.passwordChar = this[["(cueBannerPwdChr)"]]; ed.color = this.color; ed.text = ""; } } } } } if(((..win.getFocus()!=ed.hwnd) && (ed.text=="") ) || this.cueBannerTextShowing){ ed._precommand(,0x200/*_EN_KILLFOCUS*/); }; }; editable = { _get = function () { return owner[["(editable)"]]; } _set = function (v) { if( v == owner[["(editable)"]] ) return; if(v){ if(owner[["editBox"]] && (owner[["editBox"]].cls!=(v==="edit"?v:"richedit")) ){ owner[["(editable)"]] = null; owner[["editBox"]].close(); owner[["editBox"]] = null; } if(!owner[["editBox"]]) { return owner.createEditBox( cls = ( v==="edit"?v:null ) ); } owner.editBox.text = owner[["(text)"]]; owner[["(text)"]] = null; owner.editBox.hide = false; } else { if(owner.editBox){ owner.editBox.hide = true; owner[["(text)"]] = owner.editBox.text; owner.editBox.hide = true; } } owner[["(editable)"]] = v; owner.redrawTransparent(); } }; disabled = { _get = function(){ return ..win.getStyle(owner[["hwnd"]],0x8000000/*_WS_DISABLED*/ ) } _set = function(v){ if(owner[["(editable)"]]) owner.editBox.disabled = v; ..win.enable(owner[["hwnd"]],!v?1:0); } }; iconText = { _get = function(){ return owner[["(iconText)"]]; } _set = function(v){ if(owner[["(unchecked-iconText)"]]){ if(owner.checked) owner[["(checked-iconText)"]] = v; else owner[["(unchecked-iconText)"]] = v; } owner[["(iconText)"]] = v!==null?tostring(v):null; owner.redrawTransparent(); } }; text = { _get = function(){ if(owner[["(editable)"]]) return owner.cueBannerTextShowing ?"" : owner.editBox.text; return ..win.getText( owner[["hwnd"]] ); } _set = function(v){ if(owner[["(unchecked-text)"]]){ if(owner.checked) owner[["(checked-text)"]] = v; else owner[["(unchecked-text)"]] = v; } ..win.setText( owner[["hwnd"]],v !== null ? tostring(v) : "" ); owner.redrawTransparent(); } }; color = { _get = function(){ return ..gdi.rgbReverse(owner.argbColor : 0) } _set = function(v){ v = v!=-1? v : 0; if(!(v&0xFF000000)) v = ..gdi.argbReverse(v);//@Deprecated owner.argbColor = v; if(owner[["editBox"]]) owner[["editBox"]].color = v; else owner.redrawTransparent(); } }; firePosChanged = function(triggeredByUser){ var p = owner[["(progress-pos)"]]; if( p != owner[["(progress-pos-prev)"]] ){ owner[["(progress-pos-prev)"]] = p; if( owner[["onPosChanged"]] ) { owner.onPosChanged( owner[["(progress-min)"]] + p,triggeredByUser); }; } }; progressPercentage = { _get = function () { if(!owner[["(progress-range)"]]) return 100; return ..math.min( 100, ..math.round( owner[["(progress-pos)"]] / owner[["(progress-range)"]],2) * 100 ); } _set = function (v) { if(!owner[["(progress-range)"]]) { if( owner[["(progress-range)"]] === 0 ) return; error("请先设定进度区间",2); } if( v<1) v = 1;if(v>100)v=100; if(owner.state.active) return; owner[["(progress-pos)"]] = owner[["(progress-range)"]] * ( v/100 ); if( owner[["onPosChanged"]] ) owner.firePosChanged(); owner.redrawTransparent(); } }; progressPos = { _get = function () { if(!owner[["(progress-range)"]]) return 0; return owner[["(progress-min)"]] + owner[["(progress-pos)"]]; } _set = function (v) { if( v === null ) error("进度值不能为空",2); if(!owner[["(progress-range)"]]) { if( owner[["(progress-range)"]] === 0 ) return; error("请先设定进度区间",2); } if(owner.state.active) return; v = ..math.max(v, owner[["(progress-min)"]]) owner[["(progress-pos)"]] = ..math.min( v - owner[["(progress-min)"]],owner[["(progress-range)"]]); if( owner[["onPosChanged"]] ) owner.firePosChanged(); owner.redrawTransparent(); } }; setTrackbarRange = function(min,max){ if( type(min) != "number") error("参数@1不是有效的数值",2) if( type(max) != "number") error("参数@2不是有效的数值",2) owner.mode = "trackbar"; owner.setProgressRange(min,max); var rc = owner.getClientRect(); var w = rc.right - rc.left; var h = rc.bottom - rc.top; //宽大于高则为水平滑块 if( w > h ){ if( ! (owner.foreRight || owner.paddingTop) ){ owner.foreRight = 15; owner.paddingTop = 5; owner.paddingBottom = 5; owner.height = 16; owner.border={radius=-1}; h = 16; } owner.onMouseDrag = function(wParam,lParam){ var dpiScaleX,dpiScaleY = (owner.dpiScaleX : 1) ,(owner.dpiScaleY : 1); var x = ..win.getMessagePos(lParam); var rc = owner.getClientRect(); var min = owner[["(progress-min)"]]; var range = owner[["(progress-range)"]]; var p = (owner.foreLeft*dpiScaleX) + (owner.foreRight*dpiScaleX)/2; var left = rc.left + owner.paddingLeft*dpiScaleX; var pos = x > owner.paddingLeft*dpiScaleX ? ..math.ceil( range * ( ( x - (owner.paddingLeft*dpiScaleX) - p ) / (rc.right - owner.paddingLeft*dpiScaleX - owner.paddingRight*dpiScaleX - p ) ) ) : 0; if( pos > range ) pos = range; elseif( pos < 0 ) pos = 0; owner[["(progress-pos)"]] = pos; owner.redrawTransparent(); if( owner[["onPosChanged"]] ) owner.firePosChanged(true); } } else { if( ! (owner.foreRight || owner.paddingTop) ){ owner.foreTop = 15; owner.paddingLeft = 5; owner.paddingRight = 5; owner.width = 16; owner.border={radius=-1}; w = 16; } owner.onMouseDrag = function(wParam,lParam){ var dpiScaleX,dpiScaleY = (owner.dpiScaleX : 1) ,(owner.dpiScaleY : 1); var x,y = ..win.getMessagePos(lParam); var rc = owner.getClientRect(); var min = owner[["(progress-min)"]]; var range = owner[["(progress-range)"]]; var bottom = rc.bottom - owner.paddingBottom *dpiScaleY - (owner.foreBottom*dpiScaleY); var p = owner.paddingTop*dpiScaleY + (owner.foreTop*dpiScaleY)/2; var pos = y < bottom - p ? ..math.ceil( range * ( ( bottom - y - owner.foreTop/2 ) / (bottom - p ) ) ) : 0; if( pos > range ) pos = range; elseif( pos < 0 ) pos = 0; owner[["(progress-pos)"]] = pos; owner.redrawTransparent(); if( owner[["onPosChanged"]] ) owner.firePosChanged(true); } } owner.onMouseDown = owner.onMouseDrag; owner.onKeyDown = function(vk,lParam){ var pos = owner[["(progress-pos)"]]; if(vk==0x25/*_VK_LEFT*/ || vk==0x28/*_VK_DOWN*/) pos = pos-1; elseif(vk==0x27/*_VK_RIGHT*/ || vk==0x26/*_VK_UP*/ ) pos = pos+1; else return; if( pos > owner[["(progress-range)"]] ) pos = owner[["(progress-range)"]]; elseif( pos < 0 ) pos = 0; owner[["(progress-pos)"]] = pos; owner.redrawTransparent(); if( owner[["onPosChanged"]] ) owner.firePosChanged(true); } //开启[事件回调]属性 owner.notify = true; }; setPieRange = function(min,max){ if( type(min) != "number") error("参数@1不是有效的数值",2) if( type(max) != "number") error("参数@2不是有效的数值",2) owner[["(progress-clip-path)"]] = ..gdip.path(); owner.setProgressRange(min,max); owner.mode = "pie"; }; getProgressRange = function(){ var min = owner[["(progress-min)"]]; return min,min + owner[["(progress-range)"]]; }; setProgressRange = function(min,max){ if( type(min) != "number") error("参数@1不是有效的数值",2) if( type(max) != "number") error("参数@2不是有效的数值",2) if( max < min ){ var temp = min;min=max;max=temp; } if( min == max ) { if( min == 1 ) min = 0; } var len = #progressColors; var i = len > 3 ? ..math.random(1,len) : 1; if(owner.background === null)owner.background = progressColors[i] if(owner.foreground === null)owner.foreground = progressColors[ (i + 2) % len : len ] if(owner.mode=="trackbar" && owner.argbColor === 0xFF000000){ owner.argbColor = owner.foreground; } owner[["(progress-min)"]] = min; owner[["(progress-range)"]] = max -min; owner[["(progress-pos)"]] = 0; if(!owner.mode)owner.mode = "progress"; }; stepProgress = function(i,redraw){ if( i === null ) i = 1; if( redraw === null ) redraw = true; var p,r = owner[["(progress-pos)"]],owner[["(progress-range)"]]; if(!r) { if( r === 0 ) return; error("请先设定进度区间",2); } p = p + i; var ret; if( p < 0 ) p = 0; elseif( p > r ) p = r; else ret = true; owner[["(progress-pos)"]] = p; if( owner[["onPosChanged"]] ) owner.firePosChanged(); if(redraw) owner.redrawTransparent(); return ret; }; getFont = function(noScale){ if(owner["(font)"]){ var graphics = ..gdip.graphics(owner); var f = owner["(font)"].getLogFont(graphics); graphics.delete(); if(!noScale){ var yScale = owner[["dpiScaleY"]]; if(yScale && yScale>1) f[["h"]] = f[["h"]] / yScale; } else f.noScale = true; return f; } }; setFont = function(f,own = true ){ if( type(f) == type.pointer ){ var lf = LOGFONT(); if( !::GetObject(f, ..raw.sizeof(lf), lf) ) return; if(own) ::DeleteObject(f); f = lf; } else { if(type(f) != type.table ) error("参数错误@1",2) f = ::LOGFONT(f); if(f[["h"]] && !f[["point"]] && !f[["noScale"]]){ var yScale = owner[["dpiScaleY"]]; if(yScale && yScale>1){ f[["h"]] = f[["h"]] * yScale; } } } if( f.handle && own) f.deleteIndirect(); if(f.color) { owner.color = f.color owner.argbColor = ..gdi.rgbReverse( f.color ) | ( 0xFF << 24 ) } var hdc = ::GetDC(owner.hwnd); if(!hdc) error(..lasterr():"plus 控件已销毁但仍在使用",2); owner[["(font)"]] = ..gdip.font( hdc,f ); ::ReleaseDC(owner.hwnd,hdc); return true; }; setFontEx = function(font){ if( type.rget(font) == "gdip.font" && font.getLogFont ){ owner[["(font)"]] = font; } }; getFontEx = function(){ return owner[["(font)"]]; }; iconFont = { _get = function(){ return owner.iconStyle[["font"]]; } _set = function(v){ if(!owner.iconStyle)owner.iconStyle={} owner.iconStyle.font = ::LOGFONT(v); } }; startAnimation = function(interval,beginning,change,duration){ if(owner.animationId) owner.stopAnimation(); var this = owner; this.animationState = (beginning === null ? true : beginning ); var tkStart = ..time.tick(); if( this.onAnimation ) { this.animationState = this.onAnimation(this.animationState,beginning,change,0,duration); owner.redrawTransparent(); if(this.animationState===null) return; } owner.animationId = owner.setInterval(function(){ if( this.onAnimation ){ var timestamp = ..time.tick() - tkStart; this.animationState = this.onAnimation(this.animationState,beginning,change,timestamp,duration); if( this.animationState === null ){ return this.stopAnimation() } } this.redrawTransparent(); },interval) }; stopAnimation = function(){ if(owner.animationId) owner.clearInterval(owner.animationId); owner.animationId = null; owner.animationState = null; owner.redrawTransparent(); }; startProgress = function(interval,step=1){ owner.hide = false; owner.startAnimation(interval:10); owner.onAnimation = function(state){ if(! owner.stepProgress(step,false) ) owner.progressPos = 0 return true; } }; stopProgress = function(){ owner.stopAnimation(); owner.hide = true; }; measureString = function(text){ var result; var rcText; if(!text) text = owner[["(text)"]]; var graphics = ..gdip.graphics(owner); var rc = owner.getClientRect(); var width,height = rc.right - rc.left,rc.bottom - rc.top; var dpiScaleX,dpiScaleY = (owner.dpiScaleX : 1) ,(owner.dpiScaleY : 1); var tp = owner.textPadding : {left=0;right=0;top=0;bottom=0}; var x,y = (owner.paddingLeft+tp.left)*dpiScaleX,(owner.paddingTop+tp.top)*dpiScaleY; rcText = ::RECTF(x,y,width - x - (owner.paddingRight+tp.right)*dpiScaleX,height - y - (owner.paddingBottom+tp.bottom)*dpiScaleY); var strformat = ..gdip.stringformat(); strformat.align = __stringAlignment[ owner.align : "center" ] strformat.lineAlign = __stringAlignment[ owner.valign : "center" ] strformat.hotkeyPrefix = owner.hotkeyPrefix; strformat.flags = owner.stringFormatFlags; if(owner.trimming!==null) strformat.trimming = owner.trimming; var brush = ..gdip.solidBrush( owner.argbColor ); if( owner[["(font)"]] ) { result = graphics.measureString(text,owner[["(font)"]],rcText, strformat,brush); }; brush.delete(); strformat.delete(); graphics.delete(); return result; }; fitContent = function(){ var rc = owner.measureString(); if(rc){ var dpiScaleX,dpiScaleY = (owner.dpiScaleX : 1) ,(owner.dpiScaleY : 1); var tp = owner.textPadding: {left=0;right=0;top=0;bottom=0};; owner.setPos(,,rc.width + (owner.paddingLeft+tp.left)*dpiScaleX + (owner.paddingRight+tp.right)*dpiScaleX + 1 ,rc.height + (owner.paddingTop+tp.top)*dpiScaleY + (owner.paddingBottom+tp.bottom)*dpiScaleY +1 ); return true; } }; show = function(flag) { ..win.show(owner[["hwnd"]],flag); owner.state.hover = false; }; ); with _metaProperty{ forecolor = {_set = lambda () error("plus 控件请改用 foreground 属性修改前景色(颜色格式 0xAARRGGBB)",2)}; bgcolor = {_set = lambda () error("plus 控件请改用 background 属性修改背景色(颜色格式 0xAARRGGBB)",2)}; } //进度条、扇形进度条、滑尺默认配色方案 progressColors = [0xFFE8684A,0xFFF6BD16,0xFFA9D44A,0xFF48C9B0,0xFF6DC8EC,0xFF5B8FF9,0xFF9270CA,0xFFFF99C3]; __cursor_hand = ::LoadCursor(,topointer(32649/*_IDC_HAND*/)); __stringAlignment = { top =0/*_GdipStringAlignmentNear*/ ;bottom = 2/*_GdipStringAlignmentFar*/ ; left =0/*_GdipStringAlignmentNear*/ ; right = 2/*_GdipStringAlignmentFar*/; center = 1/*_GdipStringAlignmentCenter*/; } __className = ..win.registerClassEx( "AAPicturePlus2",{ lpfnWndProc = ::DefWindowProc; //必须移除static的回调函数,否则读写text会内存错误 style = 0x408B/*_CS_HREDRAW | _CS_VREDRAW | _CS_PARENTDC | _CS_GLOBALCLASS | _CS_DBLCLKS*/ },"static" ); } /***intellisense(!ui_ctrl_plus) notify = 是否启用事件回调\n设为false将不能响应鼠标按键等交互事件 setFontEx(.(字体) = 设置gdip.font字体\n字体由控件接管并负责释放 getFontEx() = 返回gdip.font字体\n注意字体生命期由控件管理\n!gdipfont. textRenderingHint = @.textRenderingHint = _GdipTextRenderingHint__; iconTextRenderingHint = @.iconTextRenderingHint = _GdipTextRenderingHint__; smoothingMode = 绘图画布默认抗锯齿模式,\n默认值为_GdipSmoothingModeAntiAlias interpolationMode = 图像缩放时的默认插值模式,\n默认值为_GdipInterpolationModeHighQualityBicubic trimming = @.trimming = _GdipStringTrimming__; stringFormatFlags = @.stringFormatFlags = _GdipStringFormatFlagsMeasureTrailingSpaces__; hotkeyPrefix = @.hotkeyPrefix = _GdipHotkeyPrefixShow__; isHyperlink() = 是否纯文本链接(非禁用状态下鼠标指针显示为手形)。\nplus 控件未设置背景、前景,\n但设置了显示文本(text)或者图标文本(iconText),\n并启用事件回调则该值返回真。 checked = 该属性可用于切换选取状态 radioGroup = 用于指定单选按钮分组名称。\n也可以在 skin 函数参数表的 group 字段中指定此属性值。 radioValue() = 单选模式下选中控件的文本 radioClick() = 单选模式下选中控件 progressPercentage = 进度条当前百分比。\n如果用户正在控件上按下鼠标(例如拖动滑块),设置此属性会被忽略 progressPos = 获取或设置进度条当前值。\n如果用户正在控件上按下鼠标(例如拖动滑块),设置此属性会被忽略 focusOnClick = 设为false时禁止在单击控件时设置此控件为焦点控件 setTrackbarRange( = 设置滑块范围,并切换到滑块显示模式。\n如果宽大于高显示为水平滑块,高大于宽则显示为垂直滑块。\n用户拖动滑块时触发 onPosChanged 事件,可用于获取当前位置 setTrackbarRange(.(最小值,最大值) = 如果使用图像制作滑块控件,\n请将背景、前景图像设为九宫格拉伸的expand模式,\n使用前景切图在右侧或顶部预留滑块位置不拉伸,\n如果未指定前景图像,aardio将自动使用当前字体颜色绘制滑块按钮,\n同样通过前景切图预留滑块大小,边框圆角属性将作用于滑块按钮,\n前景色将用于绘制滑块左侧或底部,背景色将用于绘制滑块右侧或顶部,\n前景边距将同时限制背景前景色的大小,但不会作用于背景图像 setPieRange( = 设置扇形进度条范围, setPieRange(.(最小值,最大值) = 切换为扇形进度条模式\n在此模式下前景图或前景色被裁剪为扇形,\n如果有背景色则被裁剪为圆角,背景图不裁剪,\n如果指定背景图、前景图,应设为center显示模式以使圆心对齐 setProgressRange( = 设置进度条范围,并切换到进度条显示模式。\n如果宽大于高显示为水平进度条,高大于宽则显示为垂直进度条。\n调用了此函数将会强制使用expand显示模式\n水平进度条文本右对齐,垂直进度条文本上对齐时将限制文本输出于前景内部\n否则不改变文本输出位置\n可选用textPadding属性指定文本内边距 getProgressRange() = 返回进度条最小值,最大值 setProgressRange(.(最小值,最大值) = 设置进度条范围\n调用了此函数将会强制使用expand显示模式 stepProgress( = 增加进度条的值 stepProgress(.(步进单位,是否刷新) = 步进单位可以省略,默认为1\n参数@2可省略,默认为true\n进度条到尾部或头部则返回false,否则返回true passwordChar = 指定隐藏密码的占位字符,\n例如指定为"*"隐藏密码,指定为null正常显示文本\n如果调用了setCueBannerText,passwordChar不会影响提示文本 setCueBannerText( = 并且指定嵌入编辑框为空时的显示的默认提示文本\n嵌入richedit时调用此函数会阻止拖放文件消息,\n嵌入编辑框改为edit即可 setCueBannerText(.("提示文本") = 打开编辑模式,\n并且指定文本为空时的显示的默认提示文本\n注意指定提示文本以后,\n不应再直接访问editBox的text,passwordChar属性,\n请改为读写plus控件的text,passwordChar属性 bkTop = 背景图expand模式下九宫格切图的顶部切线 bkRight = 背景图expand模式下九宫格切图的右侧切线\n如果控件显示为水平滑块控件,此属性用于预留滑块按钮大小 bkBottom = 背景图expand模式下九宫格切图的底部切线 bkLeft = 背景图expand模式下九宫格切图的左侧切线 foreTop = 前景图expand模式下九宫格切图的顶部切线\n如果控件显示为垂直滑块控件,此属性用于预留滑块按钮大小 foreRight = 前景图expand模式下九宫格切图的右侧切线 foreBottom = 前景图expand模式下九宫格切图的底部切线 foreLeft = 前景图expand模式下九宫格切图的左侧切线 argbColor = 8888 ARGB 格式( 0xAARRGGBB )字体颜色,支持透明或半透明。\n注意plus控件、GDI+都是ARGB格式数值表示颜色分量,即:0xAARRGGBB\n与RGB的分量顺序是反过来的 color = 支持 0xBBGGRR 格式或 0xAARRGGBB 格式字体颜色,\n0xAARRGGBB 格式中的 AA 必须是非 0 值,否则视为 0xBBGGRR 格式 。\n\n如果启用了编辑模式,可同步修改编辑框字体颜色,\n注意使用argbColor修改颜色不能同步修改编辑框颜色 setRepeat(.("模式",是否重绘) = 修改背景显示模式\n支持模式expand,stretch,center,tile,scale setForeRepeat(.("模式",是否重绘) = 修改前景显示模式\n支持模式expand,stretch,center,tile,scale repeat = 背景显示模式\n支持模式expand,stretch,center,tile,scale\expand模式foreTop,foreRight,foreBottom,foreLeft为九宫格切图坐标\n其他模式为显示边距 foreRepeat = 前景显示模式\n支持模式expand,stretch,center,tile,scale\n如果为null则foreLeft,foreRight为偏移坐标\expand模式foreTop,foreRight,foreBottom,foreLeft为九宫格切图坐标\n其他模式为显示边距 background = 背景图像或背景色,\n获取值是返回 gdip.bitmap 对象或 ARGB 格式颜色数值,\n赋值时可指定图像路径、资源路径、gdip.bitmap 对象、颜色值,\n颜色值使用0xAARRGGBB格式的数值。\n赋值时指定一个路径或资源路径控件将自动缓存使用频繁的图像\n内存图像建议使用setBackground函数指定缓存名\n!gdipbitmap. foreground = 前景图像或前景色,\n获取值是返回 gdip.bitmap 对象或 ARGB 格式颜色数值,\n赋值时可指定图像路径、资源路径、gdip.bitmap 对象、颜色值,\n颜色值使用0xAARRGGBB格式的数值。\n赋值时指定一个路径或资源路径控件将自动缓存使用频繁的图像\n内存图像建议使用setForeground函数指定缓存名\n如果边框圆角设为-1,前景图或前景色会裁剪为圆形后输出,\n!gdipbitmap. getBackground() = 返回背景图像,返回值为gdip.bitmap对象\n此函数不会返回背景色,仅返回背景图像,\n如果不存在背景图像返回null\n!gdipbitmap. getForeground() = 返回前景图像,返回值为gdip.bitmap对象\n此函数不会返回前景色,仅返回前景图像,\n如果不存在前景图像返回null\n!gdipbitmap. backgroundColor = 当前状态背景颜色,\n修改背景色建议设置 background 属性为数值即可,\n直接修改 backgroundColor 不会释放之前的背景图像且不会重绘 foregroundColor = 当前状态前景颜色,\n修改背景色建议设置 foreground 属性为数值即可,\n直接修改 foregroundColor 不会释放之前的前景图像且不会重绘 linearGradient = 数值,指定背景色线性渐变的角度,\n渐变从背色颜色开始,到前景颜色结束\n只有背景、前景都指定了当前状态下的颜色值才有效,\n270,90为垂直方向的渐变\n180,360为水平方向的渐变\n\n此属性指定为负数启用圆形径向渐变,此时background为中心颜色,foreground为环绕颜色 setBackground( = 修改背景图像 setBackground(.(背景图像,缓存名,刷新重绘) = 参数@1也可以使用0xAARRGGBB格式的数值指定一个颜色值,\n缓存名为可选参数,默认以路径为缓存名,设为false禁止缓存,\n如果参数@1是图像数据则可以使用参数@2指定缓存名\n刷新重绘参数@3默认为true\n该函数设置成功返回原来的背景图(gdip.bitmap 对象) setBackground(.(背景图像,false) = 加载背景图像并禁用缓存\n该函数设置成功返回原来的背景图(gdip.bitmap 对象) setForeground( = 修改前景图像 setForeground(.(前景图像,缓存名,刷新重绘) = 修改前景图像\n参数@1也可以使用0xAARRGGBB格式的数值指定一个颜色值,\n缓存名为可选参数,默认以路径为缓存名,设为false禁止缓存,\n如果参数@1是图像数据则可以使用参数@2指定缓存名\n刷新重绘参数@3默认为true\n该函数设置成功返回原来的前景图图(gdip.bitmap 对象) setForeground(.(背景图像,false) = 加载前景图像并禁用缓存\n该函数设置成功返回原来的背景图(gdip.bitmap 对象) setForeground(.(颜色数值) = 修改foregroundColor的值\n注意plus控件、GDI+都是ARGB格式数值表示颜色分量,即:0xAARRGGBB\n与RGB的分量顺序是反过来的 setForeground() = !gdipbitmap. setBackground() = !gdipbitmap. createEditBox(创建控件参数) = @.createEditBox( \n vscroll = true; \n hscroll = true; \n multiline = true;\n);__/*创建并启用透明背景的richedit文本编辑框,可用参数与窗体设计器相同,\n创建文本框时应用plus控件预设的字体、颜色、水平对齐方式,\n并且使用plus控件预设的内边距限制文本编辑框显示范围。\n\n可使用editBox属性访问此文本编辑框,\n可通过设置plus控件的editable属性显示或隐藏文本编辑框*/ border = @.border = {color=0x805F9EA0;radius=11;width=2}__/*使用一个表对象指定当前边框样式,\n支持的字段请参考窗体设计器中设置边框样式生成的代码,\n表的其他可用字段与 skin 函数指定的 border 样式相同,请参考范例。\n修改此属性不会触发重绘。\n可使用 predraw 或 redraw,redrawTransparent 等函数重绘*/ editable = 是否允许编辑文本\n如果此值设为true则切换到可编辑模式,\n也可以指定要嵌入的编辑框的类名,例如"edit",\n不指定类名则创建透明背景的richedit文本编辑框\n\n在首次切换到可编辑模式下创建文本框,\n并同步应用plus控件预设的字体、颜色、水平对齐方式,\n并使用plus控件预设的内边距限制文本编辑框显示范围。\n\n可使用editBox属性访问此文本编辑框,\n如果文本编辑框已创建,再次修改editable仅显示或隐藏文本编辑框 editBox = 文本编辑框,此文本框也是一个win.ui.tracker对象,\n!richedit. editState = 允许共享内部编辑框的外观状态,不指定默认值为true,\n如果希望利用文本边距、前景边距等模拟分离按钮\n可将此值显示指定为false state.hover = 鼠标是否在控件上方\n注意直接修改该状态控件不负责重绘 state.focus = 是否已得到焦点\n注意直接修改该状态控件不负责重绘 state.active = 鼠标或键盘键按下状态\n注意直接修改该状态控件不负责重绘 state.disabled = 已禁用\n注意直接修改该状态控件不负责重绘 state.checked = 是否选中状态\n注意直接修改该状态控件不负责重绘 state.dragging = 是否按下鼠标且正在拖动 oncommand = @.oncommand = function( id,event ){ __/*控件被单击*/ } onnotify = @.onnotify = function(id,code,ptr){ __/*处理通知消息,\nplus 控件默认不发送通知消息,\n但如果绑定 tooltip 控件这些会触发这个事件*/ } onPosChanged = @.onPosChanged = function( pos,triggeredByUser ){ __/*进度值变更,pos 参数为当前进度数值,\n如果此事件由用户拖动滑块或按键盘方向键触发,则 triggeredByUser 参数为 true*/ } onDrawContent = @.onDrawContent = function(graphics,rc,txtColor,rcContent,foregroundColor,font){ __/*自绘前景,\ngraphics 为gdip.graphics对象(GDI+画板),\ntxtColor 为文本色,ARGB 格式(0xAARRGGBB)数值,\nforeColor 为当前状态前景色,ARGB 格式数值,\nrc为客户区RECT结构体,rcContent为去掉内边距后的 RECT 结构体,\n返回真则取消绘制默认前景的操作(包含进度条、滑块等涉及前景绘制的操作)。*/ } onDrawForegroundEnd = @.onDrawForegroundEnd = function(graphics,rc,rcContent){ __/*背景前景绘制后,绘制文本前触发此事件,\ngraphics 为gdip.graphics对象(GDI+画板),\nrc为客户区RECT结构体,rcContent为去掉内边距后的RECT结构体*/ } onDrawEnd = @.onDrawEnd = function(graphics,rc,bmpMem){ __/*所有绘制操作结束触发此事件,\ngraphics 为gdip.graphics对象(GDI+画板),\nrc 为客户区RECT结构体,\nbmpMem 为当前正在绘制的 gdip.bitmap 对象,\n要注意此函数退出后不可继续使用 bmpMem,\n可使用 bmpMem.clone,bmpMem.copy,bmpMem.getThumbnail 等复制图像*/ } onDrawBackground = @.onDrawBackground = function(graphics,rc,backgroundColor,foregroundColor){ __/*自绘背景,\ngraphics 为gdip.graphics对象(GDI+画板),\nrc为绘图区块,\nbkColor为当前状态背景色,AGGB格式,可能为null\nforeColor为当前状态前景色,ARGB格式,不会出现null值\n返回真取消默认的背景绘图*/ } onDrawString = @.onDrawString = function(graphics,text,font,rectf,strformat,brush){ __/*自定义输出文本,请不要删除传入参数中的GDI+对象*/ graphics.drawString(text,font,rectf,strformat,brush); } onMouseEnter = @.onMouseEnter = function(wParam,lParam){ __/*鼠标移入*/ } onMouseLeave = @.onMouseLeave = function(wParam,lParam){ __/*鼠标移出*/ } onMouseHover = @.onMouseHover = function(wParam,lParam){ __/*鼠标悬停*/ } onMouseMove = @.onMouseMove = function(wParam,lParam){ if( wParam & 0x1/*_MK_LBUTTON*/ ){ var x,y = win.getMessagePos(lParam); __/*鼠标移动*/ } } onMouseDrag = @.onMouseDrag = function(wParam,lParam){ __/*鼠标左键按下拖动,\n自动捕获鼠标,允许拖出控件范围*/ } onMouseDown = @.onMouseDown = function(wParam,lParam){ var x,y = win.getMessagePos(lParam); __/*鼠标左键按下,\norphanWindow模式下如果阻止控件得到焦点,此事件不会被触发*/ } onMouseUp = @.onMouseUp = function(wParam,lParam){ var x,y = win.getMessagePos(lParam); __/*鼠标左键弹起*/ } onRightMouseDown = @.onRightMouseDown = function(wParam,lParam){ var x,y = win.getMessagePos(lParam); __/*鼠标右键按下*/ } onRightMouseUp = @.onRightMouseUp = function(wParam,lParam){ var x,y = win.getMessagePos(lParam); __/*鼠标右键弹起*/ } onMouseWheel = @.onMouseWheel = function(flags,delta,lParam){ delta = delta/(120/3); __/*滚动鼠标滚轮,flags 参数以 _MK_CONTROL 等常量表示按键*/ } onMouseHWheel = @.onMouseHWheel = function(flags,delta,lParam){ delta = -delta/(120/3); __/*水平滚动鼠标滚轮,flags 参数以 _MK_CONTROL 等常量表示按键*/ } onMouseClick = @.onMouseClick = function(wParam,lParam){ var x,y = win.getMessagePos(lParam); __/*鼠标左键在控件上单击,\norphanWindow模式下如果阻止控件得到焦点,此事件不会被触发*/ } onMouseDrag = @.onMouseDrag = function(wParam,lParam){ var x,y = win.getMessagePos(lParam); __/*鼠标左键按下拖动,\n自动捕获鼠标,允许拖出控件范围*/ } onMouseDoubleClick = @.onMouseDoubleClick = function(wParam,lParam){ var x,y = win.getMessagePos(lParam); __/*鼠标左键双击*/ } onKeyDown = @.onKeyDown = function(keyCode,lParam,repeat){ __/*按下键盘键*/ } onKeyUp = @.onKeyUp = function(keyCode,lParam){ __/*放开键盘键*/ } onSysKeyDown = @.onSysKeyDown = function(keyCode,lParam,repeat){ if(keyCode!=0x12/*_VK_ALT*/){ __/*按下键盘ALT组合键*/ } } onSysKeyUp = @.onSysKeyUp = function(keyCode,lParam){ __/*放开键盘键*/ } onFocusGot(hLostFocus) = @.onFocusGot = function(hLostFocus){ ..win.setFocus(hLostFocus);__/*得到焦点触发此事件,hLostFocus为失去焦点的窗口句柄,\n如果在这里将hLostFocus恢复焦点,则阻止当前窗口得到焦点*/ } onFocusLost(hFocus) = @.onFocusLost = function(hFocus){ __/*失去焦点触发此事件,hFocus为得到焦点的窗口句柄*/ } onStateChange = @.onStateChange = function(state){ __/*状态已改变*/ } onSelectChange = @.onSelectChange = function(prev,current){ __/*单选模式下已选中当前控件,prev 为同一分组之前选中的控件。\n同一分组之前没有选中控件时 prev 为 null 。\ncurrent 为当前选中控件。*/ } onMouseActivate = @.onMouseActivate = function(hwndTop,hitTest,message){\n return _MA___/*鼠标点击并且将要激活窗口时触发此事件\nhwndTop表示被激活的顶层窗口,\nhitTest参数请参考WM_NCHITTEST消息\nmessage为鼠标消息ID\n返回值的作用请参数MSDN*/\n} onDropFiles = @.onDropFiles = function(files){\n __/*接受系统拖放,files是拖放的所有文件路径名数组,嵌入编辑框必须是edit控件,richedit*/\n} skin(styleTable,clone) = @.skin({\n foreground = { \n hover = "/res/images/button-hover.png";\n focus = "/res/images/button-focus.png";\n active = "/res/images/button-active.png";\n disabled = 0xFFCCCCCC; \n };\n color = {\n hover = 0xF00000FF;__/*styleTable 指定样式表,可选用 clone 参数指定是复制样式表(默认为 false)。\nskin 函数内所有颜色字段都使用 0xAARRGGBB 格式的颜色值。\nAA 部分为不透明度,RR 为红色分量,GG 为绿色分量,BB 为蓝色分量。\n关于 skin 函数更详细的说明请查看 plus 控件使用指南。*/ \n };\n border = { \n hover = {left=5;color=0xFFFF0000;padding=15;} \n }; \n}) cls = 设计时类名 className = 运行时类名 hwnd = 控件句柄 id = 控件ID text = 控件文本 value = 控件文本,text 属性的别名。 animation = 是否允许自动播放 GIF 动画,\n指定为 false 禁止自动播放。 disabledText = @.disabledText = ['\uF254','\uF251','\uF252','\uF253','\uF250',text='']__/*disabledText 属性可以指定 3 种类型的值:\n1. 如果 disabledText 指定字符串值,则禁用此控件并显示指定文本。\n2. 如果指定一个字符串数组则创建动画逐帧显示数组里的文字图标,\n'\uF254'到'\uF250'的字符用于显示 FontAwesome 字体的沙漏动画。\n如果控件配置了 iconStyle 属性,则用图标属性(iconText)显示文字图标。\n字符串数组也可用 text 字段指定禁用状态显示的文本。\n3. 此属性指定为 null 取消禁用并恢复控件禁用之前的 text、iconText 属性*/ isForm = 标准库 win.ui 创建的所有窗体与控件对象都拥有此属性。\nwin.form 创建的窗体对象返回 true,其他控件对象返回 false 。 getForm() = 标准库 win.ui 创建的所有窗体与控件对象都拥有此属性。\nwin.form 创建的窗体对象返回自身,其他控件对象返回创建控件的容器窗口( _parentForm 属性 ) _parentForm = 返回创建控件的容器窗口(win.form对象),所有窗口控件都拥有此只读属性。\n对于使用窗体设计器创建的窗口,也就是返回设计时窗体容器。\n\n即使子窗口移除子窗口样式、更改父子关系,或以 orphanWindow显示,\n控件的 _parentForm 始终都不会改变\n!winform. getParent() = 返回父窗口 setParent(__/*控件对象*/) = 改变父窗口 autoResize = 是否允许跟随父窗体自动缩放 addCtrl(controlsPropertiesTable) = @.addCtrl(\n cls="plus";\n marginRight=0;marginBottom=2;\n width=32; \n iconText = '\uF023';\n iconStyle={\n align="right";font=LOGFONT(h=-15;name='FontAwesome');padding={top=3}\n }\n __/*在 plus 控件内部添加子控件。\n 参数 @1 可指定以下三种类型参数:\n - 指定包含名值对的表,名为添加到父窗体的控件名称,值为控件构造参数表。返回值为名值对(值为控件对象)。\n - 包含一个或多个创建匿名控件参数表的数组。返回值为数组(数组元素为创建的控件对象)。\n - 直接指定创建单个控件的构造参数表,必须指定 cls 字段。返回创建的控件对象。\n */\n) isDialogMessage = @.isDialogMessage = function(hParent,msg){__/*在控件范围内替代父窗口的 isDialogMessage,\n可用于在控件范围内屏蔽对话框快捷键*/} translateAccelerator = @.translateAccelerator = function(msg){ \n __/*返回是否快捷键*/\n} onSize = @.onSize = function( width,height,wParam ) { \n __/*父窗口改变大小后会自动触发此事件函数。\n注意 onSize 是 adjust 事件的别名,作用相同\n所有 win.form 创建的窗体和控件都支持 onSize(或 adjust)事件,\n重复赋值 onSize(或 adjust)会追加事件触发器而非替换原来的值。\n\nwidth 参数为窗口客户区宽度,height 参数为窗口客户区高度,\nwParam 参数来自 _WM_SIZE 消息的 wParam 参数,一般不用管。\n一般不建议添加一个 wndproc 仅仅是为了处理 _WM_SIZE 消息,\n定义 onSize 事件是更好的选择。\n \n};*/ adjust = @.adjust = function( cx,cy,wParam ) { \n __/*父窗口改变大小后会自动触发此事件函数。\n注意 onSize 是 adjust 事件的别名,作用相同。\n所有 win.form 创建的窗体和控件都支持 adjust 事件,\n重复赋值 adjust 会追加事件触发器而非替换原来的值。\n\ncx 参数为窗口客户区宽度,cy 参数为窗口客户区高度,\nwParam 参数来自 _WM_SIZE 消息的 wParam 参数,一般不用管。\n一般不建议添加一个 wndproc 仅仅是为了处理 _WM_SIZE 消息,\n定义 adjust 事件是更好的选择。\n\n如果主动调用此函数,则检查并执行所有之前添加的 adjust 事件函数。\n省略调用参数时 cx,cy 参数默认设为窗口大小*/ \n}; preadjust = @.preadjust = function( cx,cy,wParam ) { \n __/*窗口缩放后重绘前、触发 adjust 事件之前触发此事件。\n所有 win.form 创建的窗体和控件都支持此事件,\n与 adjust 事件不同,对 preadjust 重复赋值则覆盖而不是追加事件。 \n\ncx 参数为窗口宽度,cy 参数为窗口高度,\nwParam 为 _WM_SIZE 消息参数。*/ \n}; resize(.(宽度,高度) = 如果指定了参数则调整窗口大小,\n无论是否实际调整窗口大小,发送 _WM_SIZE 消息给窗口 _embedObject = 嵌入 COM 控件的容器对象\n!embedObject. createEmbed( = 创建嵌入控件,返回控件容器对象,\n容器对象的 _object 成员是创建的 COM 对象,\n容器对象可通过添加成员函数响应 COM 对象事件,\n容器对象的主要作用是充当访问 COM 对象的中间代理对象。\n通常使用 util.metaProperty 为容器对象添加属性元表,\n属性元表可拦截属性、函数调用并调用 _object 对象,\n\ncreateEmbedEx 返回的容器已添加默认代理以直接访问 COM 对象 createEmbed(.(clsId,embedObj) = 创建嵌入控件,返回控件容器对象,\n容器对象的 _object 成员是创建的 COM 对象,\n容器对象可通过添加成员函数响应 COM 对象事件,\n容器对象的主要作用是充当访问 COM 对象的中间代理对象,\n@clsId 指定控件 CLSID,\n可选在参数@2中指定 COM 对象绑定的容器对象\n\n此函数失败会抛出异常 createEmbed(.(comObject,embedObj) = 嵌入 COM 控件,返回控件容器对象,\n容器对象的 _object 成员是传入的 COM 对象,\n容器对象可通过添加成员函数响应 COM 对象事件,\n容器对象的主要作用是充当访问 COM 对象的中间代理对象,\n@comObject 指定已创建成功的 COM 对象,\n可选在参数@2中指定 COM 对象绑定的容器对象\n\n此函数失败会抛出异常 createEmbedEx( = 创建嵌入控件,返回控件容器对象,\n容器对象的 _object 成员是创建的 COM 对象,\n容器对象可通过添加成员函数响应 COM 对象事件,\n容器对象的主要作用是充当访问 COM 对象的中间代理对象。\n此函数返回的容器已添加元表并创建代理以直接访问 COM 对象 createEmbedEx(.(clsId,embedObj) = 创建嵌入控件,返回控件容器对象,\n此函数返回的容器已添加元表并创建代理以直接访问 COM 对象,\n@clsId 指定控件 CLSID,如果控件不是自内存加载,\n则可省略 @clsId 并由 firstCoClassId函数自动获,\n可选在参数@2中指定 COM 对象绑定的容器对象\n\n此函数失败会抛出异常 tryCreateEmbed( = 创建嵌入控件,返回控件容器对象,\n容器对象的 _object 成员是创建的 COM 对象,\n容器对象可通过添加成员函数响应 COM 对象事件,\n容器对象的主要作用是充当访问 COM 对象的中间代理对象。\n通常使用 util.metaProperty 为容器对象添加属性元表,\n属性元表可拦截属性、函数调用并调用 _object 对象,\n\ncreateEmbedEx 返回的容器已添加默认代理以直接访问 COM 对象 tryCreateEmbed(.(clsId,embedObj) = 创建嵌入控件,返回控件容器对象,\n容器对象的 _object 成员是创建的 COM 对象,\n容器对象可通过添加成员函数响应 COM 对象事件,\n容器对象的主要作用是充当访问 COM 对象的中间代理对象,\n@clsId 指定控件 CLSID,\n可选在参数@2中指定 COM 对象绑定的容器对象\n\n成功返回容器对象,失败返回false,错误信息 createEmbedEx() = !embedObject. createEmbed() = !embedObject. tryCreateEmbed() = !embedObject. hide = 当前控件窗口是否隐藏。\n仅检查当前窗口的可见性样式(窗口 是否移除了 _WS_VISIBLE 样式)。\n不考虑父窗口是否可见,不考虑是否被其他窗口遮挡。\n如果需要同时判断父窗口的可见性,应改用 win.isVisible 函数。 disabled = 是否禁用 left = 左侧坐标 right = 右侧坐标 top = 顶部坐标 bottom = 底部坐标 width = 宽度 height = 高度 setRedraw(false) = 禁止重绘 setRedraw(true) = 恢复重绘 redraw() = 刷新重绘\n不重绘背景,速度较快 redrawTransparent() = 刷新重绘\n如果控件添加了透明样式 _WS_EX_TRANSPARENT 则重绘窗口背景 predraw() = 刷新位图缓存并准备下次重绘 show(true__) = 显示控件 getRect() = 控件区块位置(::RECT结构体) getRect(true) = 控件屏幕区块位置(::RECT结构体) setRect(rc) = 设置控件区块位置(::RECT结构体) setRect(rc,true) = 设置控件屏幕区块位置(::RECT结构体) getClientRect() = 控件客户区块位置(::RECT结构体)\n!rect. clientWidth = 控件窗口客户区宽度,只读属性。 clientHeight = 控件窗口客户区宽度,只读属性 getFont() = 返回控件 LOGFONT 字体,\n返回对象的 h 值会按控件的 DPI 缩放设置自动还原为缩放前大小。\n!logfont. getFont(true) = 返回控件 LOGFONT 字体,\n返回对象的 h 值为字体实际大小,不会按控件 DPI 设置还原。\n返回字体会设置 noScale 属性为 true,\n使用控件的 setFont 函数或赋值 font 属性时,\nnoScale 属性为 true 的字体同样不会进行自动 DPI 缩放\n!logfont. setFont(__/*指定字体*/) = 指定 LOGFONT 字体对象,或逻辑字体句柄\n如果不指定 point 值并指定 h 值,字体会按控件的 DPI 缩放设置自动缩放。 setFont(混入字体属性) = @.setFont(h=-12;name="Tahoma"); font = 控件字体(LOGFONT 结构体),\n注意获取该属性总是返回新的 LOGFONT 对象,\n修改返回字体并不会更新控件字体,\n除非重新赋值。\n\n建议尽量优先使用 getFont 或 setFont 函数,\n以增强代码可读性\n\n字体会根据控件设置自动处理 DPI 缩放,不需要事先缩放字体大小 iconFont = 图标字体,LOGFONT 结构体。\n获取值时,如果存在 iconStyle.font,直接返回 iconStyle.font。\n对 iconFont 赋值总是会创建新的 LOGFONT 结构并存为 iconStyle.font \n使用 iconFont 赋值时可以传入仅指定 LOGFONT 部分成员的普通表。\n\n修改返回字体的成员不会更新 plus 控件实际使用的 GDI+ 字体。\n只有重新对 iconFont 赋值 ,才会在下次重绘时刷新 GDI+ 字体\n\n图标字体会根据控件设置自动处理 DPI 缩放,不需要事先缩放字体大小\n!logfont. theme = 外观主题,例如\nwinform.button.theme = "Explorer"\nwinform.button.theme = false modifyStyle(.(remove,add,swpFlags) = 修改窗口样式,所有参数都是可选参数,\n@remove 用数值指定要移除的样式,可使用 _WS_ 前缀的常量\n@add 用数值指定要添加的样式,可使用 _WS_ 前缀的常量\n@swpFlags 可选用数值指定调整窗口选项,可使用 _SWP_ 前缀的常量\n如果指定了 @swpFlag ,则使用该参数调用::SetWindowPos\n细节请参考 win.modifyStyle 函数源码 modifyStyleEx(.(remove,add,swpFlags) = 修改窗口扩展样式,所有参数都是可选参数,\n@remove 用数值指定要移除的样式,可使用 _WS_EX_ 前缀的常量\n@add 用数值指定要添加的样式,可使用 _WS_EX_ 前缀的常量\n@swpFlags 可选用数值指定调整窗口选项,可使用 _SWP_ 前缀的常量\n如果指定了 @swpFlag ,则使用该参数调用::SetWindowPos\n细节请参考 win.modifyStyle 函数源码 capture = 是否捕获全局鼠标消息 close() = 关闭控件窗口 invalidate(__/*可选使用::RECT()对象指定客户区*/) = 使窗口绘图区无效 invalidate(__/*可选使用::RECT()对象指定客户区*/,0) = 使窗口绘图区无效\n不刷新背景 update() = 重绘invalidate函数指定的区块 setFocus() = 设置焦点\n可选在参数中指定新的控件文本\n如果启用了编辑模式,此函数将光标移动文本尾部 tabNext(.(移动焦点,是否反向) = 获取下一个支持tab控制焦点的控件\n参数@1为true会自动移动焦点到该控件\n参数@2为true则获取上一个控件,否则获取下一个控件 tabNext() = !static. center(.(目标窗口) = 在目标窗口区域内居中,并调整以保证显示在父窗口或屏幕工作区内。\n\n参数 @1 可指定目标窗口或者目标窗口句柄,设为 0 表示桌面,\n省略目标窗口则默认取父窗口或所有者窗口。 setPos(.(x坐标,y坐标,宽,高,插入位置,参数) = 调整窗口位置或排序,所有参数可选\n同时指定x,y坐标则移动位置\n同时指定宽高则改变大小\n指定插入位置(句柄或_HWND前缀常量)则调整Z序 getPos() = 返回相对父窗口客户区的坐标,宽,高,\n参数为true返回屏幕坐标,宽,高,\nx,y,cx,cy=win.getPos(hwnd) messageOnly() = 将窗口转换为message-only window\n该窗口不可见,仅用于消息分发 setTimeout(.(函数或代码,延时,其他附加参数) = 推迟执行指定的函数或代码\n此函数异步执行参数中指定的函数,不会阻塞当前代码继续执行,\n延时参数是可选参数,以毫秒为单位,默认为0毫秒\n可选用附加参数指定调用延时函数的实参\n返回值为定时器ID setInterval(回调函数,延时毫秒数,->->->) = @.setInterval( \n function(){\n __/*参数@1指定执行函数,参数@2指定执行间隔,\n可选指定一个或多个回调参数,不指定回调参数则默认为:\n hwnd,message,timerId,tick,\n\n如果在定时器中执行了win.delay等继续消息循环的代码,\n在定时器退出前不会再触发同一定时器(重入)。\n\n定时器回调函数返回数值可修改时间间隔,\n返回false取消该定时器*/\n },1000 \n) changeInterval(.(定时器ID,间隔时间,回调函数) = 重新设置间隔时间或回调函数 clearTimeout(.(定时器ID) = 删除定时器。\n参数如果为 null 则忽略不执行,\n否则定时器ID必须是 setInterval 函数或setTimeout函 数的返回值。\n\n请注意如果定时器被删除,ID 可能被重新分配给其他定时器。\n在定时器回调函数中返回 0,false 以删除定时器是更稳妥的方式 clearInterval(.(定时器ID) = 删除定时器。\n参数如果为 null 则忽略不执行,\n否则定时器ID必须是 setInterval 函数或setTimeout函数的返回值。\n\n请注意如果定时器被删除,ID 可能被重新分配给其他定时器。\n在定时器回调函数中返回 0,false 以删除定时器是更稳妥的方式 msgbox(.(text,title,style,timeout) = 弹出对话框\n1. 参数 @text 指定显示的数据,如果指表对象则先序列化为文本。\n参数 @text 是其他类型则调用 tostring 转换为文本。\n2. 可选参数 @title 用于指定信息框标题。\n3. 可选参数 @style 可用字符串或数值指定图标样式(参考 _MB_ 前缀常量值,设为 0 去掉图标与提示音),也可以指定字符串值:\n * "error","stop","hand" 错误图标\n * "question" 询问图标,显示是、否、取消按钮,返回值为 `6/*_IDYES*/,7/*_IDNO*/, 2/*_IDCANCEL*/` 之一。\n * "confirm","test" 询问图标,显示确定与取消按钮,返回值为 `1/*_IDOK*/,2/*_IDCANCEL*/` 之一。\n- "warn" 警告图标\n * "info" 信息图标。\n4. 可选用参数 @timeout 限定显示时间,以毫秒为单位,超时自动关闭。 msgboxErr(.(text,title) = 弹出错误对话框\n参数 @text 指定显示的信息,如果指定表对象先序列化为文本。\n其他对象调用 tostring 转换为文本\n可选参数 @title 用于指定信息框标题。\n\n此函数调用 win.msgbox,并设定所有者窗口为当前窗体。 msgboxTest(.(text,title) = 弹出询问对话框\n参数 @text 指定显示的信息,如果指定表对象先序列化为文本。\n其他对象调用 tostring 转换为文本\n可选参数 @title 用于指定信息框标题。\n\n此函数调用 win.msgbox,并设定所有者窗口为当前窗体。 msgInfo(.(text,timeout) = 显示提示框。\n参数 @text 指定要显示的文本信息。\n可选使用参数 @timeout 指定延时自动关闭提示框的毫秒数。\n请先导入 win.dlg.message 库以安装此函数 msgWarn(.(text,timeout) = 显示警告提示框。\n参数 @text 指定要显示的文本信息。\n可选使用参数 @timeout 指定延时自动关闭提示框的毫秒数。\n请先导入 win.dlg.message 库以安装此函数 msgOk(.(text,timeout) = 显示正确提示框。\n参数 @text 指定要显示的文本信息。\n可选使用参数 @timeout 指定延时自动关闭提示框的毫秒数。\n请先导入 win.dlg.message 库以安装此函数 msgErr(.(text,timeout) = 显示错误提示框。\n参数 @text 指定要显示的文本信息。\n可选使用参数 @timeout 指定延时自动关闭提示框的毫秒数。\n请先导入 win.dlg.message 库以安装此函数 msgGreat(.(text,timeout) = 显示竖大拇指图标提示框。\n参数 @text 指定要显示的文本信息。\n可选使用参数 @timeout 指定延时自动关闭提示框的毫秒数。\n请先导入 win.dlg.message 库以安装此函数 sgSorry(.(text,timeout) = 显示倒竖大拇指图标提示框。\n参数 @text 指定要显示的文本信息。\n可选使用参数 @timeout 指定延时自动关闭提示框的毫秒数。\n请先导入 win.dlg.message 库以安装此函数 msgSmile(.(text,timeout) = 显示微笑图标提示框。\n参数 @text 指定要显示的文本信息。\n可选使用参数 @timeout 指定延时自动关闭提示框的毫秒数。\n请先导入 win.dlg.message 库以安装此函数 msgFrown(.(text,timeout) = 显示皱眉图标提示框。\n参数 @text 指定要显示的文本信息。\n可选用参数 @2 指定延时关闭的毫秒数,\n请先导入 win.dlg.message 库以安装此函数 msgAsk(.(text) = 显示询问提示框。\n参数 @text 指定要显示的文本信息。\n用户按确定或回车返回 true ,其他返回 false 或 null 。\n请先导入 win.dlg.message 库以安装此函数 orphanWindow( = 如果当前是子窗口,\n移除窗口的WS_CHILD样式,使窗口孤立出来悬浮于原位置,\n悬浮窗口如影随形的跟随父窗口移动或改变大小,控件原来的固定边距等参数仍然有效 orphanWindow(.(transparent,hwndBuddy) = 创建悬浮窗口,\n悬浮窗口仍然显示在原来的位置,\n可选参数 @transparent 如果为 true 则转换为分层透明窗口,\n可选利用 @buddy 参数将只有句柄的窗口托管在悬浮窗口之上实现相同的效果,\n伙伴窗口总是会保持在悬浮窗口前面,并保持相同的大小、位置 animationState = 此属性表示动画当前状态值,值null或false表示动画已停止 onAnimation(state,beginning,change,timestamp,duration) = @.onAnimation = function(state,beginning,change,timestamp,duration){ __/*startAnimation 函数启动的动画将定时回调此函数。\n参数 @state 是上次返回的值。\n可以使用 plus 控件的 animationState 属性获取 @state 最新的值。\n参数 @timestamp 为动画已执行的时间\n其他参数为调用 startAnimation 指定的参数,\n返回值恒等于 null 则停止动画,返回其他值继续执行动画。*/ return state; } startAnimation( = 启动动画定时器,立即运行一次动画并且定时继续运行动画。\n此函数负责定时调用 onAnimation 并且定时重绘控件外观。\n可选在控件的 onAnimation 动画事件函数中修改外观,\n或者在控件的 onDrawContent 等绘图事件函数中直接输出动画。 startAnimation(.(interval,beginning,change,duration) = 创建动画,\n定时执行 onAnimation 动画事件回调函数并重绘控件。\n调用此函数后立即运行一次动画,然后定时运行动画。\n参数 @interval 指定动画时间间隔,以毫秒为单位。\n参数 @beginning 指定初始状态值,\n参数 @change 指定动画完成后的状态值。\n参数 @duration 指定动画持续时间\n除参数 @interval 以外的参数会传给 onAnimation 回调函数作为调用参数。 stopAnimation() = 停止动画定时器 startProgress() = 启动进度条动画,并显示进度条,\n可选用参数@1指定间隔毫秒,可选用参数@2指定每次推进的进度。\n必须先调用 setProgressRange 函数事先指定进度范围。\n必须指定前景色、或前景图 stopProgress() = 停止进度条动画,并隐藏进度条 animationId = 动画定时器ID\n不可改动,可用于判断动画是否启动 saveScale() = 根据控件当前位置、缩放比例,更新控件的设计时位置参数。\n以避免下次窗口缩放自适应调整控件当前位置更改被清除,\n控件所有调整位置的属性或成员函数已自动调用此函数。 reloadScale() = 按设计时位置参数、重新调整控件位置以适应窗口当前缩放比例。\n父窗口缩放时会自动执行此操作。\n默认在启动窗口消息循环时会自适应调整所有控件。\n所以在启动消息循环前添加控件不必调用此函数。 threadCallable() = 开启此控件的跨线程调用功能 x = 前景x坐标,仅用于point绘图模式,\n1、0到1之间的小数表示百分比,负数表示右侧反向坐标 y = 前景y坐标,仅用于point绘图模式,\n1、0到1之间的小数表示百分比,负数表示底部反向坐标 measureString() = 返回文本输出后的区块大小,返回值为 RECTF 对象\n可选在参数中指定要输出的文本,不指定则取当前显示文本,\n!rectf. fitContent () = 控件调整大小调整到适应当前显示字数 textPadding = @.textPadding = { left = 0; top = 0; bottom = 0; right = 0;__/*指定文本输出内边距,在前景内边距上叠加,可以使用负数,仅对文本有效*/ } fontCharMap = 指定自定义字符映射表,\n键为字符,值为用于显示字符的gdip.bitmap对象\n如果指定了此属性则忽略字体大小,使用textPadding以及内边距限制输出大小 sendMessage(.(msg,wParam,lParam) = 发送窗口消息\n此函数用法请参考 ::User32.SendMessage postMessage(.(msg,wParam,lParam) = 投递窗口消息到消息队列中\n此函数用法请参考 ::User32.PostMessage publish("__/*发布消息名*/",) = 在窗口所在界面线程发布消息,\n运行界面线程所有所有调用subscribe函数订阅此消息的函数,\n可添加任意个触发参数 disablePaint() = 禁用默认绘图操作 drawToDevice(.(hdc,x,y) = 输出控件图像到hdc参数指定的GDI绘图设备,\nx,y为输出坐标,如果绘图到父窗口,x,y参数可省略 drawToGraphics(.(graphics,x,y) = 输出控件图像到hdc参数指定的GDI+画板,\nx,y为输出坐标,如果绘图到父窗口,x,y参数可省略 directDrawBackgroundOnly() = 允许直接在背景窗口上画图\n并禁止控件在自己的窗口绘图 paddingLeft = 前景左边距\n可限制前景以及文本,文本还可以使用textPadding属性进一步增减边距\n\n滑块模式下,此属性将同时作用于背景色,作不会作用于背景图像 paddingTop = 前景上边距\n可限制前景以及文本,文本还可以使用textPadding属性进一步增减边距\n\n滑块模式下,此属性将同时作用于背景色,作不会作用于背景图像 paddingRight = 前景右边距\n可限制前景以及文本,文本还可以使用textPadding属性进一步增减边距\n\n滑块模式下,此属性将同时作用于背景色,作不会作用于背景图像 paddingBottom = 前景下边距\n可限制前景以及文本,文本还可以使用textPadding属性进一步增减边距\n\n滑块模式下,此属性将同时作用于背景色,作不会作用于背景图像 reduce(array,callback,debounce) = @.reduce(\n [__/*参数 1 @array 指定要循环处理每个元素的数组或表。\n@array 指定为 false 则取消之前创建的防抖单例循环。\n\n参数 2 @callback 指定回调函数。\n\n 回调函数中可返回本次间隔延时,以毫秒为单位。\n 返回 0、null、false、以及不能转换为非 0 数的值中断处理。\n 回调参数为:当前数组元素值,当前索引,数组长度,本轮动画已执行毫秒数,\n 处理到数组尾部时回调参数 @1 为 null,\n 如果此时仍然返回可转换为非 0 数的值,将转到第一个数组元素重复循环。\n\n参数 3 @debounce 指定是否创建为防抖单例循环,默认为 true。*/],\n function(value,index,length,currentTime){\n if(value){\n var duration = 2000;\n var x = currentTime/duration;\n var change = 1+length*(x * x * x * x);\n var delay = (duration / length) / change;\n return delay;\n }\n } \n) imageAttributes = 可选使用一个gdip.imageAttributes对象对前景图像进行自动调色\n如果需要在不同状态下调色,可以在onStateChange事件里动态设置调色矩阵\n!gdip_imgattr. iconText = 指定文本图标\n使用iconStyle指定字体与样式 iconColor = 字体图标颜色,支持半透明。\n支持使用 skin 函数动态切换此样式,\n此颜色值在运行时使用 ARGB 格式,即:0xAARRGGBB,在创建控件的初始化参数中则必须指定 0xBBGGRR 格式 颜色值。\n\n请注意在未指定指属性时,图标字体默认与字体使用相同的颜色 iconStyle = @.iconStyle = { font=LOGFONT(h=-38;name='FontAwesome'); align="left";valign="top";padding={bottom=50}__/*用于指定 iconText 显示样式\n\n如 font 指向控件已使用的 iconStyle.font,则控件不会刷新字体。\nfont 如不是 ::LOGFONT 字体,控件将自动转换为 ::LOGFONT 字体。\n对 iconFont 属性赋值以修改 iconStyle.font 则总是会刷新字体*/ } align = 文本水平对齐,\n左对齐:"left"\n居中:"center"\n右对齐:"right"\n\n图标文本请使用 iconStyle 属性的 align 字段指定水平对齐 valign = 文本垂直对齐,\n顶对齐:"top"\n居中:"center"\n底对齐:"bottom"\n\n图标文本对齐请使用 iconStyle 属性的 align 字段指定垂直对齐 enableDpiScaling(false) = 禁用DPI自动缩放,\n不指定参数启用DPI自动缩放,默认已启用 dpiScaleX = 窗口当前使用的 DPI 横坐标缩放系数,\n该值由界面系统自动维护,任何情况下都不应手动修改,\n\n这是一个以小数表示百分比的数,例如 1.25 表示 125%,\n窗口未使用缩放或未完成缩放初始化时,值可能为 null,\n如果要获取屏幕缩放设置应改用 gdi.getDpiScale 函数 dpiScaleY = 窗口当前使用的 DPI 纵坐标缩放系数,\n该值由界面系统自动维护,任何情况下都不应手动修改,\n\n这是一个以小数表示百分比的数,例如 1.25 表示 125%,\n窗口未使用缩放或未完成缩放初始化时,值可能为 null,\n如果要获取屏幕缩放设置应改用 gdi.getDpiScale 函数 dpiScale(.(x,y) = 将 @x,@y 表示的像素值乘以窗体当前 DPI 缩放倍数并返回,\n省略 @y 参数时仅返回 @x 转换后的值 getRoot() = 获取顶层父窗口,这个函数会查找 orphanWindow 的父窗口 translateCommand() = 允许转发转发子窗口的命令(_WM_COMMAND)与通知(_WM_NOTIFY)消息,\n避免子窗口 oncommand,onnotify 等回调失效。\n同时会处理子窗口的 _WM_CTLCOLORSTATIC 等消息,\n以避免部分外观属性失。\n\n启用嵌入编辑框功能时已自动调用此函数 valid = 窗口是否有效,\n窗口未关闭返回 true ,\n窗口已关闭或正在关闭返回 false addCtrl() = !ui_ctrl_plus. end intellisense***/ /**intellisense() ?win.ui.ctrl.plus = !ui_ctrl_plus. win.ui.ctrl.plus() = 高级图像控件\n!ui_ctrl_plus. win.ui.ctrl.plus = 高级图像控件 win.ui.ctrl.plus.progressColors = 进度条与滑尺的预设配色方案,这是一个 ARGB 格式颜色值数组。 end intellisense**/