//picturebox 图像控件 import win.ui.ctrl.metaProperty;//导入控件属性元表支持 import win.image; import com.picture; namespace win.ui.ctrl; class picturebox{ ctor(parent,tParam){ if(tParam){ tParam.style |= 0xE/*_SS_BITMAP*/; tParam.cls = "static" if(tParam.edge) tParam.exstyle |= 0x20000/*_WS_EX_STATICEDGE*/; if(tParam.transparent)tParam.exstyle |= 0x20/*_WS_EX_TRANSPARENT*/; if(tParam.notify)tParam.style |= 0x100/*_SS_NOTIFY*/ if(!tParam.autosize) tParam.style |= 0x40/*_SS_REALSIZECONTROL*/; if(tParam.center) tParam.style |= 0x200/*_SS_CENTERIMAGE*/ } } @_metaProperty; } picturebox._metaProperty = metaProperty( clear = function(){ var hbmp,hType = owner.getBitmap(); if( hbmp ){ ::User32.SendMessageP(owner.hwnd,0x172/*_STM_SETIMAGE*/,hType,null ); if(hType==1/*_IMAGE_ICON*/) ::DestroyIcon(hbmp); else ::DeleteObject(hbmp); } }; _onDestroy = function(){ owner.clear(); }; image = { _get = function(){ return owner.getBitmap(); } _set = function( v ){ if(type(v)==type.pointer || v[["pBitmap"]]) return owner.setBitmap(v); var img = ..com.picture.load(v) if(!img){ owner.modifyStyle( 0x3/*_SS_ICON*/ | 0xE/*_SS_BITMAP*/); return; } if( img.Type == 3/*_PICTYPE_ICON*/ ) { ..com.Release(img); var x,y,cx,cy = owner.getPos() var hico = ..win.image.createIcon(v,true,..math.min(cx,cy )) if(hico) owner.setIcon(hico); } else{ owner.setBitmap( (img.CopyHandle()) ); ..com.Release(img); } } } setIcon = function(h,delPrev){ if(delPrev!==false) owner.clear(); owner.modifyStyle(0xE/*_SS_BITMAP*/,3/*_SS_ICON*/ ); var retPrev = ::User32.SendMessageP(owner.hwnd,0x172/*_STM_SETIMAGE*/, 1/*_IMAGE_ICON*/,h ); if(delPrev!==false) retPrev = true; owner.saveScale(); return retPrev; } setBitmap = function(h,delPrev){ if(h[["pBitmap"]]){ var h2 = h.copyHandle(); if(!h2) return; var r = owner.setBitmap( h2 ); if(owner.getBitmap()!=h2){ ::DeleteObject(h2) } return r; } if(delPrev!==false) owner.clear(); owner.modifyStyle(3/*_SS_ICON*/,0xE/*_SS_BITMAP*/); /* 注意: 如果位图包含透明通道,控件会使用复制的位图副本。 调用者必须自行释放传入的位图句柄。 可比对 getBitmap 返回的句柄与设置的句柄是否相同以验证此问题。 gdip.bitmap 复制的位图句柄就会有这个问题。 com.picture 加载的 GIF 图像无此问题。 改用 plus 控件可避免这些问题。 */ var retPrev = ::User32.SendMessageP(owner.hwnd,0x172/*_STM_SETIMAGE*/, 0/*_IMAGE_BITMAP*/,h ); if(delPrev!==false) retPrev = true; owner.saveScale(); return retPrev; } getBitmap = function(){ var s = ..win.getStyle(owner.hwnd, 3/*_SS_ICON*/ | 0xE/*_SS_BITMAP*/); var i = (s & 3) ==3; var b = (s & 0xE) == 0xE; if(i || b){ var h = ::User32.SendMessageP(owner.hwnd, b ? 0x173/*_STM_GETIMAGE*/: 0x171/*_STM_GETICON*/,null,null) if(h) return h, !b ? 1/*_IMAGE_ICON*/: 0/*_IMAGE_BITMAP*/; } } autosize = { _get = function(){ return !..win.getStyle(owner.hwnd,0x40/*_SS_REALSIZECONTROL*/); } _set = function( v ){ owner.modifyStyle( 0x40/*_SS_REALSIZECONTROL*/,!v?0x40/*_SS_REALSIZECONTROL*/:0 ) } } center = { _get = function(ownerCall){ if(ownerCall) { return metaProperty._metaPrototype._get.center; } return !!..win.getStyle(owner.hwnd,0x200/*_SS_CENTERIMAGE*/); } _set = function( v ){ owner.modifyStyle( 0x200/*_SS_CENTERIMAGE*/,v?0x200/*_SS_CENTERIMAGE*/:0 ) } } setImage = function(...){ return owner.setBitmap(...);//@Deprecated } ) /***intellisense() !picturebox.cls = 设计时类名 !picturebox.className = 运行时类名 !picturebox.image = 控件图像。\n取值时仅返回位图句柄。\n赋值时可指定图像文件路径、图像数据、位图句柄、gdip.bitmap 对象 之一。\n设为位图句柄时由窗体负责销毁,设为 gdip.bitmap 对象则自动调用 copyHandle 函数获取句柄。 !picturebox.value = 控件图像。image 属性的别名。 !picturebox.setIcon(__/*图标句柄*/) = 设置控件显示的图标,参数 @1 指定图标句柄。\n成功返回 true,自动销毁控件原来的位图或图标。 !picturebox.setBitmap(__/*位图句柄*/) = 设置控件显示的位图。\n参数 @1 可指定位图句柄或 gdip.bitmap 对象。\n成功返回 true,自动销毁控件原来的位图或图标。\n\n注意:\n如果位图包含透明通道,控件会使用复制的位图副本。\n调用者必须自行释放传入的位图句柄。 \n可比对 getBitmap 返回的句柄与设置的句柄验证此问题。\n参数指定 gdip.bitmap 复制的位图句柄就会有这个问题。\ncom.picture 加载的 GIF 图像无此问题。\n直接在参转中传入 gdip.bitmap 对象或改用 plus 控件可避免此问题。 !picturebox.setIcon(__/*图标句柄*/,false) = 设置图标\n如果参数 @2 恒等于 false ,\n则成功返回控件原来的位图或图标句柄 !picturebox.setBitmap(__/*图片句柄*/,false) = 设置图片\n如果参数 @2 恒等于 false ,\n则成功返回控件原来的位图或图标句柄 !picturebox.getBitmap() = 返回位图句柄或图标句柄。\n返回值 1 为图标句柄则返回值 2 为 1/*_IMAGE_ICON*/\n返回值 1 为位图句柄则返回值 2 为 0/*_IMAGE_BITMAP*/ !picturebox.clear() = 清空图像,并释放控件加载的位图或图标句柄。\n控件销毁前会自动调用此函数\n\n注意:\n如果位图包含透明通道,控件会使用复制的位图副本。\n调用者必须自行释放传入的位图句柄。\ngdip.bitmap 复制的位图句柄就会有这个问题。\ncom.picture 加载的 GIF 图像无此问题\n\n改用 plus 控件没有这些麻烦 !picturebox.hwnd = 控件句柄 !picturebox.id = 控件ID !picturebox._parentForm = 返回创建控件的容器窗口(win.form对象),所有窗口控件都拥有此只读属性。\n对于使用窗体设计器创建的窗口,也就是返回设计时窗体容器。\n\n即使子窗口移除子窗口样式、更改父子关系,或以 orphanWindow显示,\n控件的 _parentForm 始终都不会改变\n!winform. !picturebox.getParent() = 返回父窗口\n!static. !picturebox.setParent(__/*控件对象*/) = 改变父窗口 !picturebox.hide = 控件是否隐藏 !picturebox.disabled = 是否禁用 !picturebox.left = 左侧坐标 !picturebox.right = 右侧坐标 !picturebox.top = 顶部坐标 !picturebox.bottom = 底部坐标 !picturebox.width = 宽度 !picturebox.height = 高度 !picturebox.redraw() = 刷新 !picturebox.show(true__) = 显示控件 !picturebox.getRect() = 控件区块位置(::RECT结构体) !picturebox.getRect(true) = 控件屏幕区块位置(::RECT结构体) !picturebox.setRect(rc) = 设置控件区块位置(::RECT结构体) !picturebox.setRect(rc,true) = 设置控件屏幕区块位置(::RECT结构体) !picturebox.getClientRect() = 控件客户区块位置(::RECT结构体)\n!rect. !picturebox.clientRect = 获取控件客户区块位置(::RECT结构体) !picturebox.theme = 外观主题,例如\nwinform.button.theme = "Explorer"\nwinform.button.theme = false !picturebox.modifyStyle(.(remove,add,swpFlags) = 修改窗口样式,所有参数都是可选参数,\n@remove 用数值指定要移除的样式,可使用 _WS_ 前缀的常量\n@add 用数值指定要添加的样式,可使用 _WS_ 前缀的常量\n@swpFlags 可选用数值指定调整窗口选项,可使用 _SWP_ 前缀的常量\n如果指定了 @swpFlag ,则使用该参数调用::SetWindowPos\n细节请参考 win.modifyStyle 函数源码 !picturebox.modifyStyleEx(.(remove,add,swpFlags) = 修改窗口扩展样式,所有参数都是可选参数,\n@remove 用数值指定要移除的样式,可使用 _WS_EX_ 前缀的常量\n@add 用数值指定要添加的样式,可使用 _WS_EX_ 前缀的常量\n@swpFlags 可选用数值指定调整窗口选项,可使用 _SWP_ 前缀的常量\n如果指定了 @swpFlag ,则使用该参数调用::SetWindowPos\n细节请参考 win.modifyStyle 函数源码 !picturebox.capture = 是否捕获全局鼠标消息 !picturebox.close() = 关闭控件 !picturebox.invalidate(__/*可选使用::RECT()对象指定客户区*/) = 使窗口绘图区无效 !picturebox.invalidate(__/*可选使用::RECT()对象指定客户区*/,0) = 使窗口绘图区无效\n不刷新背景 !picturebox.update() = 重绘invalidate函数指定的区块 !picturebox.setFocus() = 设置焦点 !picturebox.autosize = 是否允许控件自适应图片大小\n设置center属性为true时,autosize属性无效 !picturebox.center = center 作为属性访问时:\n图像在控件内是否居中显示(并禁用图象缩放,禁止控件自动调整大小)。 !picturebox.center(.(目标窗口) = center 作为方法调用时:\n在目标窗口区域内居中,并调整以保证显示在父窗口或屏幕工作区内。\n\n参数 @1 可指定目标窗口或者目标窗口句柄,设为 0 表示桌面,\n省略目标窗口则默认取父窗口或所有者窗口。 !picturebox.setPos(.(x坐标,y坐标,宽,高,插入位置,参数) = 调整窗口位置或排序,所有参数可选\n同时指定x,y坐标则移动位置\n同时指定宽高则改变大小\n指定插入位置(句柄或_HWND前缀常量)则调整Z序 !picturebox.getPos() = 返回相对坐标,宽,高\nx,y,cx,cy=win.getPos(hwnd) !picturebox.saveScale(.(scaleX,scaleY,dpiScaleX,dpiScaleY) = 根据控件当前的运行时位置更新设计时大小\如果控件允许自动缩放,窗口缩放时依据设计时大小按比例缩放\n所有参数可省略,并且不建议写参数 !picturebox.orphanWindow(.(transparent,hwndBuddy,borderless) = 创建悬浮窗口。\n悬浮窗口是模仿子窗口外观效果的独立窗口,父窗口可自动调整子窗口到设定位置。\n可选参数 @transparent 为 true 则转换为分层透明窗口。\n可选利用 @hwndBuddy 参数指定外部进程窗口句柄的并附加在内部控件上以实现相同的效果。\n伙伴窗口总是会保持在悬浮窗口前面,并保持相同的大小、位置。\n可重复调用此函数更换伙伴窗口,旧的伙伴窗口必须自行关闭。\n可选指定 @borderless 参数 为 true 以移除 @hwndBuddy 的窗口边框。 !picturebox.sendMessage(.(msg,wParam,lParam) = 发送窗口消息\n此函数用法请参考 ::User32.SendMessage !picturebox.postMessage(.(msg,wParam,lParam) = 投递窗口消息到消息队列中\n此函数用法请参考 ::User32.PostMessage !picturebox.saveScale() = 根据控件当前位置、缩放比例,更新控件的设计时位置参数。\n以避免下次窗口缩放自适应调整控件当前位置更改被清除,\n控件所有调整位置的属性或成员函数已自动调用此函数。 !picturebox.reloadScale() = 按设计时位置参数、重新调整控件位置以适应窗口当前缩放比例。\n父窗口缩放时会自动执行此操作。\n默认在启动窗口消息循环时会自适应调整所有控件。\n所以在启动消息循环前添加控件不必调用此函数。 !picturebox.adjust = @.adjust = function( cx,cy,wParam ) { \n __/*窗口缩放时会自动触发此函数。\ncx 参数为窗口宽度,cy 参数为窗口高度,\nwParam 参数请参考 _WM_SIZE 消息参数说明,一般不用管。\n\n所有 win.form 创建的窗体和控件都支持此事件,\n重复赋值只会追加而不会覆盖此事件。\n一般不建议添加一个 wndproc 仅仅是为了处理 _WM_SIZE 消息,\n定义 adjust 事件是更好的选择。\n\n可主动调用此事件,省略参数时 cx,cy 参数默认设为窗口大小*/ \n}; ?win.ui.ctrl.picturebox =!picturebox. win.ui.ctrl.picturebox() = 图像控件。\n推荐改用功能更强大的高级图像控件(plus 控件)。\n!picturebox. end intellisense***/