# win.ui.ctrl.canvas 库模块帮助文档

[ ▶ canvas 动效画布使用指南](https://www.aardio.com/zh-cn/docs/library-guide/std/win/ui/ctrl/canvas.html)

## win.ui.ctrl 成员列表 <a id="win.ui.ctrl" href="#win.ui.ctrl">&#x23;</a>

### win.ui.ctrl.canvas <a id="win.ui.ctrl.canvas" href="#win.ui.ctrl.canvas">&#x23;</a>
动效画布控件，用于游戏、动画与自绘界面。  
在 winform.add 的参数表中指定 cls="canvas" 创建。  

自绘事件与动画接口与 plus 控件相同（onDrawBackground,onDrawForeground,onDrawComplete,startAnimation,onAnimation），  
但画布是常驻的 PARGB 内存位图（GDI+ 最快的格式），不做伽马校正合成，  
动画跟随显示器刷新（不用窗口定时器），比 plus 快数倍且帧间隔稳定。  

画布总是不透明，没有文本、图标、皮肤、圆角、边框等 plus 功能；  
调用 orphanWindow(true) 可转为透明分层窗口，盖在其他控件上面显示特效

### win.ui.ctrl.canvas() <a id="win.ui.ctrl.canvas" href="#win.ui.ctrl.canvas">&#x23;</a>
动效画布控件  

[返回对象:uiCtrlCanvasObject](#uiCtrlCanvasObject)

## uiCtrlCanvasObject 成员列表 <a id="uiCtrlCanvasObject" href="#uiCtrlCanvasObject">&#x23;</a>

### uiCtrlCanvasObject._parentForm <a id="uiCtrlCanvasObject._parentForm" href="#uiCtrlCanvasObject._parentForm">&#x23;</a>
返回创建控件的容器窗口（win.form对象），所有窗口控件都拥有此只读属性。  
对于使用窗体设计器创建的窗口，也就是返回设计时窗体容器。  

即使子窗口移除子窗口样式、更改父子关系，或以 orphanWindow显示，  
控件的 _parentForm 始终都不会改变  

[返回对象:winform](https://www.aardio.com/zh-cn/docs/library-reference/win/ui/_.html#winform)

### uiCtrlCanvasObject.adjust <a id="uiCtrlCanvasObject.adjust" href="#uiCtrlCanvasObject.adjust">&#x23;</a>

```aardio
uiCtrlCanvasObject.adjust = function( cx,cy,wParam ) {	   
	/*父窗口改变大小后会自动触发此事件函数。  
注意 onSize 是 adjust 事件的别名，作用相同。  
所有 win.form 创建的窗体和控件都支持 adjust 事件,  
重复赋值 adjust 会追加事件触发器而非替换原来的值。  

cx 参数为窗口客户区宽度,cy 参数为窗口客户区高度,  
wParam 参数来自 _WM_SIZE 消息的 wParam 参数，一般不用管。  
一般不建议添加一个 wndproc 仅仅是为了处理  _WM_SIZE 消息，  
定义 adjust 事件是更好的选择。  

如果主动调用此函数，则检查并执行所有之前添加的 adjust 事件函数。  
省略调用参数时 cx,cy 参数默认设为窗口大小*/    
};
```

### uiCtrlCanvasObject.afterDpiChanged <a id="uiCtrlCanvasObject.afterDpiChanged" href="#uiCtrlCanvasObject.afterDpiChanged">&#x23;</a>

```aardio
uiCtrlCanvasObject.afterDpiChanged = function(scaleX,scaleY,origScaleX,origScaleY){  
    /*DPI 缩放后回调此函数。  
scaleX,scaleY 为 DPI 缩放倍数（例如 2 表示 200% 缩放）。  
origScaleX,origScaleY 为缩放前的倍数。*/  
}
```

### uiCtrlCanvasObject.animationId <a id="uiCtrlCanvasObject.animationId" href="#uiCtrlCanvasObject.animationId">&#x23;</a>
动画运行中为 true，停止后为 null

### uiCtrlCanvasObject.animationState <a id="uiCtrlCanvasObject.animationState" href="#uiCtrlCanvasObject.animationState">&#x23;</a>
onAnimation 上次返回的状态值，动画停止后为 null

### uiCtrlCanvasObject.argbColor <a id="uiCtrlCanvasObject.argbColor" href="#uiCtrlCanvasObject.argbColor">&#x23;</a>
文本颜色（0xAARRGGBB 格式），仅原样传给绘图事件

### uiCtrlCanvasObject.autoResize <a id="uiCtrlCanvasObject.autoResize" href="#uiCtrlCanvasObject.autoResize">&#x23;</a>
是否允许跟随父窗体自动缩放

### uiCtrlCanvasObject.backgroundColor <a id="uiCtrlCanvasObject.backgroundColor" href="#uiCtrlCanvasObject.backgroundColor">&#x23;</a>
背景色（0xAARRGGBB 格式），每帧用它清空画布。  
为 null 时：子窗口使用父窗口背景色，分层窗口为全透明。  
子窗口画布总是不透明（忽略透明分量）

### uiCtrlCanvasObject.bgcolor <a id="uiCtrlCanvasObject.bgcolor" href="#uiCtrlCanvasObject.bgcolor">&#x23;</a>
背景色（0xBBGGRR 格式，也可以指定 0xAARRGGBB 格式），修改后立即重绘

### uiCtrlCanvasObject.bitmap <a id="uiCtrlCanvasObject.bitmap" href="#uiCtrlCanvasObject.bitmap">&#x23;</a>
画布的内存位图（PARGB 格式 gdip.bitmap 对象，与 GDI 位图共用同一块内存）。  
尺寸改变时会重建，不要长期保存此对象，也不要删除它。  
尚未绘制过时为 null  

[返回对象:gdipbitmapObject](https://www.aardio.com/zh-cn/docs/library-reference/gdip/bitmap.html#gdipbitmapObject)

### uiCtrlCanvasObject.bottom <a id="uiCtrlCanvasObject.bottom" href="#uiCtrlCanvasObject.bottom">&#x23;</a>
底部坐标

### uiCtrlCanvasObject.capture <a id="uiCtrlCanvasObject.capture" href="#uiCtrlCanvasObject.capture">&#x23;</a>
是否捕获全局鼠标消息

### uiCtrlCanvasObject.center(目标窗口) <a id="uiCtrlCanvasObject.center" href="#uiCtrlCanvasObject.center">&#x23;</a>
在目标窗口区域内居中，并调整以保证显示在父窗口或屏幕工作区内。  

参数 @1 可指定目标窗口或者目标窗口句柄，设为 0 表示桌面，  
省略目标窗口则默认取父窗口或所有者窗口。

### uiCtrlCanvasObject.changeInterval(定时器ID,间隔时间,回调函数) <a id="uiCtrlCanvasObject.changeInterval" href="#uiCtrlCanvasObject.changeInterval">&#x23;</a>
重新设置间隔时间或回调函数

### uiCtrlCanvasObject.className <a id="uiCtrlCanvasObject.className" href="#uiCtrlCanvasObject.className">&#x23;</a>
运行时类名

### uiCtrlCanvasObject.clearInterval(定时器ID) <a id="uiCtrlCanvasObject.clearInterval" href="#uiCtrlCanvasObject.clearInterval">&#x23;</a>
删除定时器。  
参数如果为 null 则忽略不执行，  
否则定时器ID必须是 setInterval 函数或setTimeout函数的返回值。  

请注意如果定时器被删除，ID 可能被重新分配给其他定时器。  
在定时器回调函数中返回 0,false 以删除定时器是更稳妥的方式

### uiCtrlCanvasObject.clearTimeout(定时器ID) <a id="uiCtrlCanvasObject.clearTimeout" href="#uiCtrlCanvasObject.clearTimeout">&#x23;</a>
删除定时器。  
参数如果为 null 则忽略不执行，  
否则定时器ID必须是 setInterval 函数或setTimeout函 数的返回值。  

请注意如果定时器被删除，ID 可能被重新分配给其他定时器。  
在定时器回调函数中返回 0,false 以删除定时器是更稳妥的方式

### uiCtrlCanvasObject.clientHeight <a id="uiCtrlCanvasObject.clientHeight" href="#uiCtrlCanvasObject.clientHeight">&#x23;</a>
控件窗口客户区宽度，只读属性

### uiCtrlCanvasObject.clientWidth <a id="uiCtrlCanvasObject.clientWidth" href="#uiCtrlCanvasObject.clientWidth">&#x23;</a>
控件窗口客户区宽度，只读属性。

### uiCtrlCanvasObject.close() <a id="uiCtrlCanvasObject.close" href="#uiCtrlCanvasObject.close">&#x23;</a>
关闭控件窗口

### uiCtrlCanvasObject.cls <a id="uiCtrlCanvasObject.cls" href="#uiCtrlCanvasObject.cls">&#x23;</a>
设计时类名

### uiCtrlCanvasObject.cursor <a id="uiCtrlCanvasObject.cursor" href="#uiCtrlCanvasObject.cursor">&#x23;</a>
鼠标指针，可指定 gdi.loadCursor 支持的名字，例如 "hand"，也可以指定光标句柄

### uiCtrlCanvasObject.disabled <a id="uiCtrlCanvasObject.disabled" href="#uiCtrlCanvasObject.disabled">&#x23;</a>
是否禁用

### uiCtrlCanvasObject.dlgCode <a id="uiCtrlCanvasObject.dlgCode" href="#uiCtrlCanvasObject.dlgCode">&#x23;</a>
响应 WM_GETDLGCODE 的返回值。  
默认为 0x81/*_DLGC_WANTARROWS | _DLGC_WANTCHARS*/，方向键与字符键都交给画布。  
设为 4/*_DLGC_WANTALLKEYS*/ 可接收全部按键（包括回车、Tab、Esc）

### uiCtrlCanvasObject.dpiScale(x,y) <a id="uiCtrlCanvasObject.dpiScale" href="#uiCtrlCanvasObject.dpiScale">&#x23;</a>
将 @x,@y 表示的像素值乘以窗体当前 DPI 缩放倍数并返回,  
省略 @y 参数时仅返回 @x 转换后的值

### uiCtrlCanvasObject.dpiScaleX <a id="uiCtrlCanvasObject.dpiScaleX" href="#uiCtrlCanvasObject.dpiScaleX">&#x23;</a>
窗口当前使用的 DPI 横坐标缩放系数,  
该值由界面系统自动维护，任何情况下都不应手动修改,  

这是一个以小数表示百分比的数，例如 1.25 表示 125%,  
窗口未使用缩放或未完成缩放初始化时，值可能为 null，  
如果要获取屏幕缩放设置应改用 gdi.getDpiScale 函数

### uiCtrlCanvasObject.dpiScaleY <a id="uiCtrlCanvasObject.dpiScaleY" href="#uiCtrlCanvasObject.dpiScaleY">&#x23;</a>
窗口当前使用的 DPI 纵坐标缩放系数,  
该值由界面系统自动维护，任何情况下都不应手动修改,  

这是一个以小数表示百分比的数，例如 1.25 表示 125%,  
窗口未使用缩放或未完成缩放初始化时，值可能为 null，  
如果要获取屏幕缩放设置应改用 gdi.getDpiScale 函数

### uiCtrlCanvasObject.enableDpiScaling(false) <a id="uiCtrlCanvasObject.enableDpiScaling" href="#uiCtrlCanvasObject.enableDpiScaling">&#x23;</a>
禁用 DPI 自动缩放,  
不指定参数启用 DPI 自动缩放,默认已启用

### uiCtrlCanvasObject.foregroundColor <a id="uiCtrlCanvasObject.foregroundColor" href="#uiCtrlCanvasObject.foregroundColor">&#x23;</a>
前景色（0xAARRGGBB 格式），仅原样传给 onDrawForeground

### uiCtrlCanvasObject.getClientRect() <a id="uiCtrlCanvasObject.getClientRect" href="#uiCtrlCanvasObject.getClientRect">&#x23;</a>
控件客户区块位置(::RECT结构体)  

[返回对象:rectObject](https://www.aardio.com/zh-cn/docs/library-reference/global/_.html#rectObject)

### uiCtrlCanvasObject.getFontEx() <a id="uiCtrlCanvasObject.getFontEx" href="#uiCtrlCanvasObject.getFontEx">&#x23;</a>
返回gdip.font字体  
注意字体生命期由控件管理  

[返回对象:gdipfontObject](https://www.aardio.com/zh-cn/docs/library-reference/gdip/font.html#gdipfontObject)

### uiCtrlCanvasObject.getForm() <a id="uiCtrlCanvasObject.getForm" href="#uiCtrlCanvasObject.getForm">&#x23;</a>
标准库 win.ui 创建的所有窗体与控件对象都拥有此属性。  
win.form 创建的窗体对象返回自身，其他控件对象返回创建控件的容器窗口（ _parentForm 属性 ）

### uiCtrlCanvasObject.getParent() <a id="uiCtrlCanvasObject.getParent" href="#uiCtrlCanvasObject.getParent">&#x23;</a>
返回父窗口

### uiCtrlCanvasObject.getPos() <a id="uiCtrlCanvasObject.getPos" href="#uiCtrlCanvasObject.getPos">&#x23;</a>
返回相对父窗口客户区的坐标,宽,高,  
参数为true返回屏幕坐标,宽,高,  
x,y,cx,cy=win.getPos(hwnd)

### uiCtrlCanvasObject.getRect() <a id="uiCtrlCanvasObject.getRect" href="#uiCtrlCanvasObject.getRect">&#x23;</a>
控件区块位置(::RECT结构体)

### uiCtrlCanvasObject.getRect(true) <a id="uiCtrlCanvasObject.getRect" href="#uiCtrlCanvasObject.getRect">&#x23;</a>
控件屏幕区块位置(::RECT结构体)

### uiCtrlCanvasObject.getRoot() <a id="uiCtrlCanvasObject.getRoot" href="#uiCtrlCanvasObject.getRoot">&#x23;</a>
获取顶层父窗口，这个函数会查找 orphanWindow 的父窗口

### uiCtrlCanvasObject.getScale() <a id="uiCtrlCanvasObject.getScale" href="#uiCtrlCanvasObject.getScale">&#x23;</a>
返回 X 轴、Y 轴方向缩放比例，DPI 缩放比例共 4 个返回值,  
scaleX,scaleY,dpiScaleX,dpiScale 。  
win.ui 创建的所有窗体与控件对象都提供此方法。

### uiCtrlCanvasObject.height <a id="uiCtrlCanvasObject.height" href="#uiCtrlCanvasObject.height">&#x23;</a>
高度

### uiCtrlCanvasObject.hwnd <a id="uiCtrlCanvasObject.hwnd" href="#uiCtrlCanvasObject.hwnd">&#x23;</a>
控件句柄

### uiCtrlCanvasObject.id <a id="uiCtrlCanvasObject.id" href="#uiCtrlCanvasObject.id">&#x23;</a>
控件ID

### uiCtrlCanvasObject.interpolationMode <a id="uiCtrlCanvasObject.interpolationMode" href="#uiCtrlCanvasObject.interpolationMode">&#x23;</a>
画板默认图像插值模式，默认为 null（使用 GDI+ 默认的双线性插值，贴图快）。  
需要高质量缩放时可指定 7/*_InterpolationModeHighQualityBicubic*/

### uiCtrlCanvasObject.invalidate(/*可选使用::RECT()对象指定客户区*/) <a id="uiCtrlCanvasObject.invalidate(/*可选使用::RECT" href="#uiCtrlCanvasObject.invalidate(/*可选使用::RECT">&#x23;</a>
使窗口绘图区无效

### uiCtrlCanvasObject.invalidate(/*可选使用::RECT()对象指定客户区*/,0) <a id="uiCtrlCanvasObject.invalidate(/*可选使用::RECT" href="#uiCtrlCanvasObject.invalidate(/*可选使用::RECT">&#x23;</a>
使窗口绘图区无效  
不刷新背景

### uiCtrlCanvasObject.invoke(threadFunction,...) <a id="uiCtrlCanvasObject.invoke" href="#uiCtrlCanvasObject.invoke">&#x23;</a>

```aardio
uiCtrlCanvasObject.invoke(threadFunction,...invoke(  
	function(...){  
		/*  
		在创建当前控件的线程执行回调函数（等待并获取函数返回值）。  
		owner 参数指向当前控件（真实对象而非线程代理），其他附加参数转发为回调参数。  

		工作线程本就可以直接调此对象的属性或方法（在界面线程内执行）。  
		但 invoke 方法适合在界面线程批量执行连续的代码，并创建安全的闭包上下文。  

		此函数属于线程回调函数，应遵守线程规则，所有数据自参数与返回值交换。  
		不可直接访问线程函数外部的对象（不同线程拥有隔离的上下文）。  

		此函数主要用于跨线程调用界面线程的对象。  
		*/	  
	}  
)
```

### uiCtrlCanvasObject.isDialogMessage <a id="uiCtrlCanvasObject.isDialogMessage" href="#uiCtrlCanvasObject.isDialogMessage">&#x23;</a>

```aardio
uiCtrlCanvasObject.isDialogMessage = function(hParent,msg){/*在控件范围内替代父窗口的 isDialogMessage，  
可用于在控件范围内屏蔽对话框快捷键*/}
```

### uiCtrlCanvasObject.isForm <a id="uiCtrlCanvasObject.isForm" href="#uiCtrlCanvasObject.isForm">&#x23;</a>
标准库 win.ui 创建的所有窗体与控件对象都拥有此属性。  
win.form 创建的窗体对象返回 true,其他控件对象返回 false 。

### uiCtrlCanvasObject.left <a id="uiCtrlCanvasObject.left" href="#uiCtrlCanvasObject.left">&#x23;</a>
左侧坐标

### uiCtrlCanvasObject.modifyStyle(remove,add,swpFlags) <a id="uiCtrlCanvasObject.modifyStyle" href="#uiCtrlCanvasObject.modifyStyle">&#x23;</a>
修改窗口样式,所有参数都是可选参数,  
@remove 用数值指定要移除的样式,可使用 _WS_ 前缀的常量  
@add 用数值指定要添加的样式,可使用 _WS_ 前缀的常量  
@swpFlags 可选用数值指定调整窗口选项,可使用 _SWP_ 前缀的常量  
如果指定了 @swpFlag ,则使用该参数调用::SetWindowPos  
细节请参考 win.modifyStyle 函数源码

### uiCtrlCanvasObject.modifyStyleEx(remove,add,swpFlags) <a id="uiCtrlCanvasObject.modifyStyleEx" href="#uiCtrlCanvasObject.modifyStyleEx">&#x23;</a>
修改窗口扩展样式,所有参数都是可选参数,  
@remove 用数值指定要移除的样式,可使用 _WS_EX_ 前缀的常量  
@add 用数值指定要添加的样式,可使用 _WS_EX_ 前缀的常量  
@swpFlags 可选用数值指定调整窗口选项,可使用 _SWP_ 前缀的常量  
如果指定了 @swpFlag ,则使用该参数调用::SetWindowPos  
细节请参考 win.modifyStyle 函数源码

### uiCtrlCanvasObject.notify <a id="uiCtrlCanvasObject.notify" href="#uiCtrlCanvasObject.notify">&#x23;</a>
是否响应鼠标，默认为 true（不指定即为 true）。  
设为 false 时鼠标穿透到下层窗口（例如父窗体），适合纯装饰的背景动画。  
运行时也可以修改

### uiCtrlCanvasObject.orphanWindow <a id="uiCtrlCanvasObject.orphanWindow" href="#uiCtrlCanvasObject.orphanWindow">&#x23;</a>
如果当前是子窗口,  
移除窗口的WS_CHILD样式，使窗口孤立出来悬浮于原位置,  
悬浮窗口如影随形的跟随父窗口移动或改变大小,控件原来的固定边距等参数仍然有效

### uiCtrlCanvasObject.orphanWindow(transparent,hwndBuddy) <a id="uiCtrlCanvasObject.orphanWindow" href="#uiCtrlCanvasObject.orphanWindow">&#x23;</a>
创建悬浮窗口,  
悬浮窗口仍然显示在原来的位置,  
可选参数 @transparent 如果为 true 则转换为分层透明窗口,  
可选利用 @buddy 参数将只有句柄的窗口托管在悬浮窗口之上实现相同的效果,  
伙伴窗口总是会保持在悬浮窗口前面，并保持相同的大小、位置

### uiCtrlCanvasObject.postMessage(msg,wParam,lParam) <a id="uiCtrlCanvasObject.postMessage" href="#uiCtrlCanvasObject.postMessage">&#x23;</a>
投递窗口消息到消息队列中  
此函数用法请参考 ::User32.PostMessage

### uiCtrlCanvasObject.preadjust <a id="uiCtrlCanvasObject.preadjust" href="#uiCtrlCanvasObject.preadjust">&#x23;</a>

```aardio
uiCtrlCanvasObject.preadjust = function( cx,cy,wParam ) {	   
	/*窗口缩放后重绘前、触发 adjust 事件之前触发此事件。  
所有 win.form 创建的窗体和控件都支持此事件,  
与 adjust 事件不同，对 preadjust 重复赋值则覆盖而不是追加事件。   

cx 参数为窗口宽度,cy 参数为窗口高度,  
wParam 为 _WM_SIZE 消息参数。*/    
};
```

### uiCtrlCanvasObject.publish("字符串参数",) <a id="uiCtrlCanvasObject.publish" href="#uiCtrlCanvasObject.publish">&#x23;</a>
在窗口所在界面线程发布消息,  
运行界面线程所有所有调用subscribe函数订阅此消息的函数,  
可添加任意个触发参数

### uiCtrlCanvasObject.redraw() <a id="uiCtrlCanvasObject.redraw" href="#uiCtrlCanvasObject.redraw">&#x23;</a>
立即重绘：依次回调绘图事件，然后显示到屏幕。  
分层窗口模式下调用 updateLayered

刷新重绘，默认不重绘背景。  
如果控件未指定 background 或 backgroundColor 属性但启用了“剪切背景”属性（默认设置）仍然会重绘背景。

### uiCtrlCanvasObject.redrawTransparent() <a id="uiCtrlCanvasObject.redrawTransparent" href="#uiCtrlCanvasObject.redrawTransparent">&#x23;</a>
刷新重绘  
如果控件添加了透明样式 _WS_EX_TRANSPARENT 则重绘窗口背景

### uiCtrlCanvasObject.reduce(array,callback,debounce) <a id="uiCtrlCanvasObject.reduce" href="#uiCtrlCanvasObject.reduce">&#x23;</a>

```aardio
uiCtrlCanvasObject.reduce(  
	[/*参数 1 @array 指定要循环处理每个元素的数组或表。  
@array 指定为 false 则取消之前创建的防抖单例循环。  

参数 2 @callback 指定回调函数。  

    回调函数中可返回本次间隔延时，以毫秒为单位。  
    返回 0、null、false、以及不能转换为非 0 数的值中断处理。  
    回调参数为：当前数组元素值,当前索引,数组长度,本轮动画已执行毫秒数,  
    处理到数组尾部时回调参数 @1 为 null,  
    如果此时仍然返回可转换为非 0 数的值,将转到第一个数组元素重复循环。  

参数 3 @debounce 指定是否创建为防抖单例循环，默认为 true。*/],  
	function(value,index,length,currentTime){  
		if(value){  
			var duration = 2000;  
			var x = currentTime/duration;  
			var change = 1+length*(x * x * x * x);  
			var delay = (duration / length) / change;  
			return delay;  
		}  
	}   
)
```

### uiCtrlCanvasObject.reloadScale() <a id="uiCtrlCanvasObject.reloadScale" href="#uiCtrlCanvasObject.reloadScale">&#x23;</a>
按设计时位置参数、重新调整控件位置以适应窗口当前缩放比例。  
父窗口缩放时会自动执行此操作。  
默认在启动窗口消息循环时会自适应调整所有控件。  
所以在启动消息循环前添加控件不必调用此函数。

### uiCtrlCanvasObject.resize(宽度,高度) <a id="uiCtrlCanvasObject.resize" href="#uiCtrlCanvasObject.resize">&#x23;</a>
如果指定了参数则调整窗口大小,  
无论是否实际调整窗口大小,发送 _WM_SIZE 消息给窗口

### uiCtrlCanvasObject.right <a id="uiCtrlCanvasObject.right" href="#uiCtrlCanvasObject.right">&#x23;</a>
右侧坐标

### uiCtrlCanvasObject.saveScale() <a id="uiCtrlCanvasObject.saveScale" href="#uiCtrlCanvasObject.saveScale">&#x23;</a>
根据控件当前位置、缩放比例，更新控件的设计时位置参数。  
以避免下次窗口缩放自适应调整控件当前位置更改被清除，  
控件所有调整位置的属性或成员函数已自动调用此函数。

### uiCtrlCanvasObject.sendMessage(msg,wParam,lParam) <a id="uiCtrlCanvasObject.sendMessage" href="#uiCtrlCanvasObject.sendMessage">&#x23;</a>
发送窗口消息  
此函数用法请参考 ::User32.SendMessage

### uiCtrlCanvasObject.setFocus() <a id="uiCtrlCanvasObject.setFocus" href="#uiCtrlCanvasObject.setFocus">&#x23;</a>
设置焦点  
可选在参数中指定新的控件文本  
如果启用了编辑模式,此函数将光标移动文本尾部

### uiCtrlCanvasObject.setFontEx(字体) <a id="uiCtrlCanvasObject.setFontEx" href="#uiCtrlCanvasObject.setFontEx">&#x23;</a>
设置 gdip.font 字体  
字体由控件接管并负责释放

### uiCtrlCanvasObject.setInterval(回调函数,延时毫秒数,...) <a id="uiCtrlCanvasObject.setInterval" href="#uiCtrlCanvasObject.setInterval">&#x23;</a>

```aardio
uiCtrlCanvasObject.setInterval(回调函数,延时毫秒数,...setInterval(   
	function(){  
		/*参数@1指定执行函数,参数@2指定执行间隔，  
可选指定一个或多个回调参数，不指定回调参数则默认为:  
 hwnd,message,timerId,tick,  

如果在定时器中执行了win.delay等继续消息循环的代码，  
在定时器退出前不会再触发同一定时器（重入）。  

定时器回调函数返回数值可修改时间间隔,  
返回false取消该定时器*/  
	},1000   
)
```

### uiCtrlCanvasObject.setParent(控件对象) <a id="uiCtrlCanvasObject.setParent" href="#uiCtrlCanvasObject.setParent">&#x23;</a>
改变父窗口

### uiCtrlCanvasObject.setPos(x坐标,y坐标,宽,高,插入位置,参数) <a id="uiCtrlCanvasObject.setPos" href="#uiCtrlCanvasObject.setPos">&#x23;</a>
调整窗口位置或排序,所有参数可选  
同时指定x,y坐标则移动位置  
同时指定宽高则改变大小  
指定插入位置(句柄或_HWND前缀常量)则调整Z序

### uiCtrlCanvasObject.setRect(rc) <a id="uiCtrlCanvasObject.setRect" href="#uiCtrlCanvasObject.setRect">&#x23;</a>
设置控件区块位置(::RECT结构体)

### uiCtrlCanvasObject.setRect(rc,true) <a id="uiCtrlCanvasObject.setRect" href="#uiCtrlCanvasObject.setRect">&#x23;</a>
设置控件屏幕区块位置(::RECT结构体)

### uiCtrlCanvasObject.setRedraw(false) <a id="uiCtrlCanvasObject.setRedraw" href="#uiCtrlCanvasObject.setRedraw">&#x23;</a>
禁止重绘

### uiCtrlCanvasObject.setRedraw(true) <a id="uiCtrlCanvasObject.setRedraw" href="#uiCtrlCanvasObject.setRedraw">&#x23;</a>
恢复重绘

### uiCtrlCanvasObject.setTimeout(函数或代码,延时,其他附加参数) <a id="uiCtrlCanvasObject.setTimeout" href="#uiCtrlCanvasObject.setTimeout">&#x23;</a>
推迟执行指定的函数或代码  
此函数异步执行参数中指定的函数，不会阻塞当前代码继续执行，  
延时参数是可选参数，以毫秒为单位，默认为0毫秒  
可选用附加参数指定调用延时函数的实参  
返回值为定时器ID

### uiCtrlCanvasObject.show(true) <a id="uiCtrlCanvasObject.show" href="#uiCtrlCanvasObject.show">&#x23;</a>
显示控件

### uiCtrlCanvasObject.smoothingMode <a id="uiCtrlCanvasObject.smoothingMode" href="#uiCtrlCanvasObject.smoothingMode">&#x23;</a>
画板默认抗锯齿模式，默认为 4/*_GdipSmoothingModeAntiAlias*/

### uiCtrlCanvasObject.snap() <a id="uiCtrlCanvasObject.snap" href="#uiCtrlCanvasObject.snap">&#x23;</a>
立即重绘一帧并返回整帧的副本（PARGB 格式 gdip.bitmap 对象）。  
不依赖窗口显示，隐藏的窗口也可以截图，适合无界面测试。  
调用者负责释放返回的位图  

[返回对象:gdipbitmapObject](https://www.aardio.com/zh-cn/docs/library-reference/gdip/bitmap.html#gdipbitmapObject)

### uiCtrlCanvasObject.startAnimation <a id="uiCtrlCanvasObject.startAnimation" href="#uiCtrlCanvasObject.startAnimation">&#x23;</a>
启动动画：立即回调一次 onAnimation 并重绘，之后跟随显示器刷新每帧回调。  
动画由后台线程等待系统合成器刷新后通知界面线程，不使用窗口定时器，帧间隔稳定。

### uiCtrlCanvasObject.startAnimation(interval,beginning,change,duration) <a id="uiCtrlCanvasObject.startAnimation" href="#uiCtrlCanvasObject.startAnimation">&#x23;</a>
参数都可以省略。  
参数 @interval 省略或小于 25 毫秒时每帧回调；  
大于等于 25 毫秒时按刷新周期的整数倍降频，例如 50 在 60Hz 屏幕上为每 3 帧回调一次。  
参数 @beginning 指定初始状态值，默认为 0；  
@change,@duration 原样传给 onAnimation。  
动画运行中再次调用会重新计时

### uiCtrlCanvasObject.state <a id="uiCtrlCanvasObject.state" href="#uiCtrlCanvasObject.state">&#x23;</a>
交互状态表（由 win.ui.tracker 维护），包含 hover,active,focus,disabled 等字段

### uiCtrlCanvasObject.stopAnimation() <a id="uiCtrlCanvasObject.stopAnimation" href="#uiCtrlCanvasObject.stopAnimation">&#x23;</a>
停止动画并重绘一次

### uiCtrlCanvasObject.tabNext() <a id="uiCtrlCanvasObject.tabNext" href="#uiCtrlCanvasObject.tabNext">&#x23;</a>
[返回对象:staticObject](https://www.aardio.com/zh-cn/docs/library-reference/win/ui/ctrl/static.html#staticObject)

### uiCtrlCanvasObject.tabNext(移动焦点,是否反向) <a id="uiCtrlCanvasObject.tabNext" href="#uiCtrlCanvasObject.tabNext">&#x23;</a>
获取下一个支持tab控制焦点的控件  
参数@1为true会自动移动焦点到该控件  
参数@2为true则获取上一个控件,否则获取下一个控件

### uiCtrlCanvasObject.textRenderingHint <a id="uiCtrlCanvasObject.textRenderingHint" href="#uiCtrlCanvasObject.textRenderingHint">&#x23;</a>

```aardio
uiCtrlCanvasObject.textRenderingHint = _GdipTextRenderingHint/*画板默认文本渲染模式，默认为 4（抗锯齿，不对齐像素，移动的文字不抖动）*/
```

### uiCtrlCanvasObject.toClient(x,y) <a id="uiCtrlCanvasObject.toClient" href="#uiCtrlCanvasObject.toClient">&#x23;</a>
将参数 x,y 指定的屏幕坐标转换为当前控件客户区坐标。  
返回 2 个值：x,y

### uiCtrlCanvasObject.toScreen(x,y) <a id="uiCtrlCanvasObject.toScreen" href="#uiCtrlCanvasObject.toScreen">&#x23;</a>
将参数 x,y 指定的当前控件客户区坐标转换为屏幕坐标。  
返回 2 个值：x,y

### uiCtrlCanvasObject.top <a id="uiCtrlCanvasObject.top" href="#uiCtrlCanvasObject.top">&#x23;</a>
顶部坐标

### uiCtrlCanvasObject.translateAccelerator <a id="uiCtrlCanvasObject.translateAccelerator" href="#uiCtrlCanvasObject.translateAccelerator">&#x23;</a>

```aardio
uiCtrlCanvasObject.translateAccelerator = function(msg){   
	/*返回是否快捷键*/  
}
```

### uiCtrlCanvasObject.update() <a id="uiCtrlCanvasObject.update" href="#uiCtrlCanvasObject.update">&#x23;</a>
重绘invalidate函数指定的区块

### uiCtrlCanvasObject.updateLayered() <a id="uiCtrlCanvasObject.updateLayered" href="#uiCtrlCanvasObject.updateLayered">&#x23;</a>
分层窗口模式下重绘并更新到屏幕，一般不需要直接调用。  
画布调用 orphanWindow(true) 后转为透明分层窗口，背景默认透明，  
可盖在其他控件上面显示粒子等特效

### uiCtrlCanvasObject.valid <a id="uiCtrlCanvasObject.valid" href="#uiCtrlCanvasObject.valid">&#x23;</a>
窗口是否有效，  
窗口未关闭返回 true ，  
窗口已关闭或正在关闭返回 false

### uiCtrlCanvasObject.visible <a id="uiCtrlCanvasObject.visible" href="#uiCtrlCanvasObject.visible">&#x23;</a>
当前控件窗口是否显示。  
仅检查当前窗口的可见性样式（窗口 是否具有 _WS_VISIBLE 样式）。  
不考虑父窗口是否可见，不考虑是否被其他窗口遮挡。  
如果需要同时判断父窗口的可见性，应改用 win.isVisible 函数。

### uiCtrlCanvasObject.wait(等待函数,超时,延时间隔) <a id="uiCtrlCanvasObject.wait" href="#uiCtrlCanvasObject.wait">&#x23;</a>
循环执行等待函数，并等待非 null 返回值。  
当等待函数的第 1,第 2 个返回值不全等于 null 值，或当前控件窗口关闭都会停止等待。  
等待函数返回的值也就是 wait 函数的返回值（最多转发 3 个返回值）。  
如果指定超时，超过指定毫秒时返回 null 。  
除等待函数以外，所有参数可选

### uiCtrlCanvasObject.waitUntil(等待函数,超时,延时间隔) <a id="uiCtrlCanvasObject.waitUntil" href="#uiCtrlCanvasObject.waitUntil">&#x23;</a>
循环执行等待函数，并等待返回真值（Truthy）。  
当等待函数的首个返回值为真值（Truthy） ，或当前控件窗口关闭都会停止等待。  
等待函数首个返回值也就是 waitUntil 函数的返回值（仅返回单个值）。  
如果指定超时，超过指定毫秒时返回 null 。  
除等待函数以外，所有参数可选

### uiCtrlCanvasObject.width <a id="uiCtrlCanvasObject.width" href="#uiCtrlCanvasObject.width">&#x23;</a>
宽度

## uiCtrlCanvasObject 事件列表 <a id="uiCtrlCanvasObjectEvent" href="#uiCtrlCanvasObjectEvent">&#x23;</a>

### uiCtrlCanvasObject.onAnimation <a id="uiCtrlCanvasObject.onAnimation" href="#uiCtrlCanvasObject.onAnimation">&#x23;</a>

```aardio
uiCtrlCanvasObject.onAnimation = function(prevState,beginning,change,timestamp,duration,deltaMs){
	/*startAnimation 启动的动画每帧回调此函数，回调后自动重绘。  
跟随显示器刷新（60Hz 屏幕约 16.7 毫秒一帧，高刷屏更快），按 timestamp 或 deltaMs 推进动画，不要按帧计数。  
参数 @timestamp 为动画已运行的毫秒数（高精度小数），@deltaMs 为距上一帧的毫秒数，首次回调都为 0。  
窗口隐藏或最小化时暂停回调，恢复后的 deltaMs 包含暂停时长（游戏应限制单帧最大步长）。  
其他参数为 startAnimation 的参数，@prevState 为上次的返回值。  
返回值全等于 null 停止动画（返回 false 不会停止）*/
	return true;
}
```

### uiCtrlCanvasObject.onDrawBackground <a id="uiCtrlCanvasObject.onDrawBackground" href="#uiCtrlCanvasObject.onDrawBackground">&#x23;</a>

```aardio
uiCtrlCanvasObject.onDrawBackground = function(graphics,rc,backgroundColor,color){
	/*自绘背景。每帧先用背景色铺底，然后回调此函数。  
底色为 bgcolor，未指定时为父窗口背景色，透明分层窗口为全透明。  
graphics 为 GDI+ 画板（gdip.graphics 对象），画在常驻的 PARGB 内存位图上。  
rc 为画布区块（::RECT 结构体，设备像素），就地修改不影响上游。  
backgroundColor 为背景色（0xAARRGGBB），可能为 null。  
返回值不影响绘图*/
}
```

### uiCtrlCanvasObject.onDrawComplete <a id="uiCtrlCanvasObject.onDrawComplete" href="#uiCtrlCanvasObject.onDrawComplete">&#x23;</a>

```aardio
uiCtrlCanvasObject.onDrawComplete = function(graphics,rc,hMemBitmap){
	/*一帧绘制完成，显示到屏幕之前回调此函数。  
可用 owner.bitmap 访问整帧（PARGB 格式 gdip.bitmap），  
例如传给 sys.mediaFoundation 的 writeFrame 录制视频。  
hMemBitmap 为画布的 GDI 位图句柄（不要释放或存储此句柄）*/
}
```

### uiCtrlCanvasObject.onDrawForeground <a id="uiCtrlCanvasObject.onDrawForeground" href="#uiCtrlCanvasObject.onDrawForeground">&#x23;</a>

```aardio
uiCtrlCanvasObject.onDrawForeground = function(graphics,rc){
	/*自绘内容，在 onDrawBackground 之后回调。  
graphics 为 GDI+ 画板（gdip.graphics 对象），  
rc 为画布区块（::RECT 结构体，设备像素），就地修改不影响上游*/
}
```

### uiCtrlCanvasObject.onDropFiles <a id="uiCtrlCanvasObject.onDropFiles" href="#uiCtrlCanvasObject.onDropFiles">&#x23;</a>

```aardio
uiCtrlCanvasObject.onDropFiles = function(files){  
	/*接受系统拖放,files是拖放的所有文件路径名数组,嵌入编辑框必须是edit控件,richedit*/  
}
```

### uiCtrlCanvasObject.onFocusGot <a id="uiCtrlCanvasObject.onFocusGot" href="#uiCtrlCanvasObject.onFocusGot">&#x23;</a>

```aardio
uiCtrlCanvasObject.onFocusGot = function(){
	/*获得键盘焦点*/
}
```

### uiCtrlCanvasObject.onFocusLost <a id="uiCtrlCanvasObject.onFocusLost" href="#uiCtrlCanvasObject.onFocusLost">&#x23;</a>

```aardio
uiCtrlCanvasObject.onFocusLost = function(){
	/*失去键盘焦点，游戏可在这里自动暂停*/
}
```

### uiCtrlCanvasObject.onKeyDown <a id="uiCtrlCanvasObject.onKeyDown" href="#uiCtrlCanvasObject.onKeyDown">&#x23;</a>

```aardio
uiCtrlCanvasObject.onKeyDown = function(keyCode,lParam,repeat){
	/*按键按下，按住不放自动重复时 repeat 为重复次数，首次按下为 0。  
点击画布会自动获得键盘焦点*/
}
```

### uiCtrlCanvasObject.onKeyUp <a id="uiCtrlCanvasObject.onKeyUp" href="#uiCtrlCanvasObject.onKeyUp">&#x23;</a>

```aardio
uiCtrlCanvasObject.onKeyUp = function(keyCode,lParam){
	/*按键弹起*/
}
```

### uiCtrlCanvasObject.onMouseActivate <a id="uiCtrlCanvasObject.onMouseActivate" href="#uiCtrlCanvasObject.onMouseActivate">&#x23;</a>

```aardio
uiCtrlCanvasObject.onMouseActivate = function(hwndTop,hitTest,message){  
	return _MA_/*鼠标点击并且将要激活窗口时触发此事件  
hwndTop表示被激活的顶层窗口,  
hitTest参数请参考WM_NCHITTEST消息  
message为鼠标消息ID  
返回值的作用请参数MSDN*/  
}
```

### uiCtrlCanvasObject.onMouseClick <a id="uiCtrlCanvasObject.onMouseClick" href="#uiCtrlCanvasObject.onMouseClick">&#x23;</a>

```aardio
uiCtrlCanvasObject.onMouseClick = function(wParam,lParam){
	var x,y = win.getMessagePos(lParam);
	/*鼠标左键在画布上单击*/
}
```

### uiCtrlCanvasObject.onMouseDown <a id="uiCtrlCanvasObject.onMouseDown" href="#uiCtrlCanvasObject.onMouseDown">&#x23;</a>

```aardio
uiCtrlCanvasObject.onMouseDown = function(wParam,lParam){
	var x,y = win.getMessagePos(lParam);
	/*鼠标左键按下，x,y 为画布客户区坐标（设备像素）*/
}
```

### uiCtrlCanvasObject.onMouseDrag <a id="uiCtrlCanvasObject.onMouseDrag" href="#uiCtrlCanvasObject.onMouseDrag">&#x23;</a>

```aardio
uiCtrlCanvasObject.onMouseDrag = function(wParam,lParam){
	var x,y = win.getMessagePos(lParam);
	/*鼠标左键按下拖动，自动捕获鼠标，允许拖出画布范围*/
}
```

### uiCtrlCanvasObject.onMouseEnter <a id="uiCtrlCanvasObject.onMouseEnter" href="#uiCtrlCanvasObject.onMouseEnter">&#x23;</a>

```aardio
uiCtrlCanvasObject.onMouseEnter = function(wParam,lParam){
	/*鼠标移入*/
}
```

### uiCtrlCanvasObject.onMouseLeave <a id="uiCtrlCanvasObject.onMouseLeave" href="#uiCtrlCanvasObject.onMouseLeave">&#x23;</a>

```aardio
uiCtrlCanvasObject.onMouseLeave = function(wParam,lParam){
	/*鼠标移出*/
}
```

### uiCtrlCanvasObject.onMouseMove <a id="uiCtrlCanvasObject.onMouseMove" href="#uiCtrlCanvasObject.onMouseMove">&#x23;</a>

```aardio
uiCtrlCanvasObject.onMouseMove = function(wParam,lParam){
	var x,y = win.getMessagePos(lParam);
	/*鼠标移动*/
}
```

### uiCtrlCanvasObject.onMouseUp <a id="uiCtrlCanvasObject.onMouseUp" href="#uiCtrlCanvasObject.onMouseUp">&#x23;</a>

```aardio
uiCtrlCanvasObject.onMouseUp = function(wParam,lParam){
	var x,y = win.getMessagePos(lParam);
	/*鼠标左键弹起*/
}
```

### uiCtrlCanvasObject.onMouseWheel <a id="uiCtrlCanvasObject.onMouseWheel" href="#uiCtrlCanvasObject.onMouseWheel">&#x23;</a>

```aardio
uiCtrlCanvasObject.onMouseWheel = function(flags,delta,lParam){
	/*滚动鼠标滚轮，delta 为滚动量（向上为正，一格为 120）*/
}
```

### uiCtrlCanvasObject.onRightMouseDown <a id="uiCtrlCanvasObject.onRightMouseDown" href="#uiCtrlCanvasObject.onRightMouseDown">&#x23;</a>

```aardio
uiCtrlCanvasObject.onRightMouseDown = function(wParam,lParam){
	var x,y = win.getMessagePos(lParam);
	/*鼠标右键按下*/
}
```

### uiCtrlCanvasObject.onSize <a id="uiCtrlCanvasObject.onSize" href="#uiCtrlCanvasObject.onSize">&#x23;</a>

```aardio
uiCtrlCanvasObject.onSize = function( width,height,wParam ) {	   
	/*父窗口改变大小后会自动触发此事件函数。  
注意 onSize 是 adjust 事件的别名，作用相同  
所有 win.form 创建的窗体和控件都支持 onSize（或 adjust）事件,  
重复赋值 onSize（或 adjust）会追加事件触发器而非替换原来的值。  

width 参数为窗口客户区宽度,height 参数为窗口客户区高度,  
wParam 参数来自 _WM_SIZE 消息的 wParam 参数，一般不用管。  
一般不建议添加一个 wndproc 仅仅是为了处理  _WM_SIZE 消息，  
定义 onSize 事件是更好的选择。  

};*/
```

