//tracker 输入跟踪器 namespace win.ui; class tracker{ ctor( ctrl,hoverTime=0xFFFFFFFF/*_HOVER_DEFAULT*/ ){ if( !ctrl[["hwnd"]] ) error("参数必须是窗口对象",2); if( ctrl[["_tracker"]] ) return ctrl[["_tracker"]]; ctrl[["_tracker"]] = ctrl; this = ctrl; var state = {}; this.state = state; state.disabled = ctrl.disabled; if(! this._onStateChange ){ this._onStateChange = function(){ if(this.onStateChange) this.onStateChange(); } } this.radioClick = __radioClick__; this.radioValue = __radioValue__; this.wndproc = { [0x200/*_WM_MOUSEMOVE*/] = function(hwnd,message,wParam,lParam){ if(!state.hover){ state.hover = trackMouseEvent({ INT cbSize = 16; INT dwFlags = 2/*_TME_LEAVE*/ | 0x1/*_TME_HOVER*/; int hwndTrack = this[["hwnd"]]; INT dwHoverTime = hoverTime; } ) if( (wParam & 0x1/*_MK_LBUTTON*/) && ( state.dragging ) ) state.active = true; if( this.onMouseEnter ){ this.onMouseEnter(wParam,lParam); } if(this._onStateChange) this._onStateChange(state); } else{ if(( wParam & 0x1/*_MK_LBUTTON*/) && this.onMouseDrag && state.dragging ) this.onMouseDrag(wParam,lParam); if(this.onMouseMove) this.onMouseMove(wParam,lParam); } } [0x02A3/*_WM_MOUSELEAVE*/] = function(hwnd,message,wParam,lParam){ state.hover = false; state.dragging = state.active; state.active = false; if(this.onMouseLeave) this.onMouseLeave(wParam,lParam); if(this._onStateChange) this._onStateChange(state); } [0x2A1/*_WM_MOUSEHOVER*/] = function(hwnd,message,wParam,lParam){ if(this.onMouseHover) this.onMouseHover(wParam,lParam); } [0x201/*_WM_LBUTTONDOWN*/] = function(hwnd,message,wParam,lParam){ state.active = true; if(this.onMouseDown) this.onMouseDown(wParam,lParam); if(this.radioGroup && this.radioGroup[1]=='#'#){ this.radioClick(); } elseif(this._onStateChange) this._onStateChange(state); if(this.onMouseDrag){ this.capture = true; } state.dragging = true; } [0x202/*_WM_LBUTTONUP*/] = function(hwnd,message,wParam,lParam){ state.dragging = null; if(state.active ){ state.active = false; if(this.onMouseDrag){ this.capture = false; } var rc = ::RECT(); ::User32.GetClientRect(hwnd,rc); var pt = ..raw.convert( {INT lParam=lParam},{word x;word y} ) if(::PtInRect(rc,pt.x,pt.y) ){ if( this.focusOnClick !== false ) ..win.setFocus(this.hwnd) if( ! this.radioGroup ){ state.checked = !state.checked; if(this._onStateChange) this._onStateChange(state); } elseif(this.radioGroup[1]!='#'#) { this.radioClick(); } if(this.onMouseUp){ this.onMouseUp(wParam,lParam) } if(this.oncommand) this.oncommand(this.id,0); if(this.onMouseClick) this.onMouseClick(wParam,lParam); return; } } if(this.onMouseUp){ this.onMouseUp(wParam,lParam) }; if(this._onStateChange) this._onStateChange(state); } [0x203/*_WM_LBUTTONDBLCLK*/] = function(hwnd,message,wParam,lParam){ var cb = this.onMouseDoubleClick || this.onMouseDoubuleClick; if(cb) invoke(cb,this,wParam,lParam); } [0x21/*_WM_MOUSEACTIVATE*/] = function(hwnd,message, wParam,lParam){ if( this.onMouseActivate ) { return this.onMouseActivate(wParam,::LOWORD(lParam),::HIWORD(lParam)) } } [0xA/*_WM_ENABLE*/] = function(hwnd,message,wParam,lParam){ state.disabled = !wParam; if(this._onStateChange) this._onStateChange(state); } [0x7/*_WM_SETFOCUS*/] = function(hwnd,message,wParam,lParam){ state.focus = true; if(this._onStateChange) this._onStateChange(state); if(this.onFocusGot) { var r = this.onFocusGot(wParam,lParam); if( r!==null) return r; } if(this.editable && this.editBox )this.editBox.setFocus(); } [0x8/*_WM_KILLFOCUS*/] = function(hwnd,message,wParam,lParam){ state.focus = false; if(this._onStateChange) this._onStateChange(state); if(this.onFocusLost) this.onFocusLost(wParam,lParam); } [0x100/*_WM_KEYDOWN*/] = function(hwnd,message,wParam,lParam){ var repeat = lParam & 1<<30; if( !repeat && ( wParam == 0x20/*_VK_SPACE*/ || wParam == 0xD/*_VK_ENTER*/ ) ){ state.active = true; if(this._onStateChange) this._onStateChange(state); if(this.oncommand) this.oncommand(this.id,0); } if(this.onKeyDown) this.onKeyDown(wParam,lParam,repeat?lParam&0xFFFF); } [0x101/*_WM_KEYUP*/] = function(hwnd,message,wParam,lParam){ if( ( wParam == 0x20/*_VK_SPACE*/ || wParam == 0xD/*_VK_ENTER*/ ) ){ if( ! this.radioGroup ){ state.checked = !state.checked; } else { this.radioClick(); } state.active = false; if(this._onStateChange) this._onStateChange(state); } if(this.onKeyUp) this.onKeyUp(wParam,lParam); } [0x104/*_WM_SYSKEYDOWN*/] = function(hwnd,message,wParam,lParam){ if(this.onSysKeyDown) this.onSysKeyDown(wParam,lParam,repeat?lParam&0xFFFF); } [0x105/*_WM_SYSKEYUP*/] = function(hwnd,message,wParam,lParam){ if(this.onSysKeyUp) this.onSysKeyUp(wParam,lParam); } [0x204/*_WM_RBUTTONDOWN*/] = function(hwnd,message,wParam,lParam){ if(this.onRightMouseDown) this.onRightMouseDown(wParam,lParam); } [0x205/*_WM_RBUTTONUP*/] = function(hwnd,message,wParam,lParam){ if(this.onRightMouseUp) this.onRightMouseUp(wParam,lParam); } [0x20A/*_WM_MOUSEWHEEL*/] = function(hwnd,message,wParam,lParam){ if(this.onMouseWheel) this.onMouseWheel(wParam&0xffff,wParam >> 16,lParam); } [0x20E/*_WM_MOUSEHWHEEL*/] = function(hwnd,message,wParam,lParam){ if(this.onMouseHWheel) this.onMouseHWheel(wParam&0xffff,wParam >> 16,lParam); } } ..win._form._metaProperty.trackerGroup = lambda(){}; }; } namespace tracker{ trackMouseEvent = ::User32.api("TrackMouseEvent", "bool(struct& lpEventTrack)"); __radioValue__ = function(){ var chk = owner.getForm()[["__uiTrackerRadioGroups__"]][[owner.radioGroup]]; if( chk ) return chk.text; }; __radioClick__ = function(){ var form = owner.getForm(); if(!form) return; var g = form.__uiTrackerRadioGroups__; if( !g ) { g = { @{ _weak = "v" } }; form.__uiTrackerRadioGroups__ = g; form.trackerGroup = function(name){ return g[name]; } }; var prev = g[owner.radioGroup]; owner.state.checked = true; if(owner._onStateChange) owner._onStateChange(state); g[owner.radioGroup] = owner; if( prev ? prev != owner ) { prev.state.checked = false; if(prev._onStateChange) prev._onStateChange(prev.state); } if(owner.onSelect) owner.onSelect(prev,owner);// @Deprecated if(owner.onSelectChange) owner.onSelectChange(prev,owner); } } /**intellisense() win.ui.tracker = 创建鼠标跟踪器, win.ui.tracker(.(控件对象) = 参数为控件或窗口对象\n返回鼠标跟踪器 - 实际上就是返回控件对象自身,\n如果已经调用此函数创建过鼠标跟踪器,则直接返回参数 win.ui.tracker() = !winUiTracker. !winUiTracker.radioValue() = 单选模式下选中控件的文本 !winUiTracker.radioClick() = 单选模式下选中控件 !winUiTracker.state.hover = 鼠标是否在控件上方\n悬停超过预设时间后触发onMouseHover事件 !winUiTracker.state.focus = 是否已得到焦点 !winUiTracker.state.active = 鼠标或键盘键按下状态 !winUiTracker.state.disabled = 已禁用 !winUiTracker.state.checked = 是否选中状态 !winUiTracker.state.dragging = 是否按下鼠标且正在拖动 !winUiTracker.focusOnClick = 设为false时禁止在单击控件时设置此控件为焦点控件 !winUiTracker.onMouseEnter = @.onMouseEnter = function(wParam,lParam){ __/*鼠标移入*/ } !winUiTracker.onMouseLeave = @.onMouseLeave = function(wParam,lParam){ __/*鼠标移出*/ } !winUiTracker.onMouseHover = @.onMouseHover = function(wParam,lParam){ __/*鼠标悬停*/ } !winUiTracker.onMouseMove = @.onMouseMove = function(wParam,lParam){ if( wParam & 0x1/*_MK_LBUTTON*/ ){ var x,y = win.getMessagePos(lParam); __/*鼠标移动*/ } } !winUiTracker.onMouseDrag = @.onMouseDrag = function(wParam,lParam){ var x,y = win.getMessagePos(lParam); __/*鼠标左键按下拖动,\n自动捕获鼠标,允许拖出控件范围*/ } !winUiTracker.onMouseDown = @.onMouseDown = function(wParam,lParam){ var x,y = win.getMessagePos(lParam); __/*鼠标左键按下,\norphanWindow模式下如果阻止控件得到焦点,此事件不会被触发*/ } !winUiTracker.onMouseClick = @.onMouseClick = function(wParam,lParam){ var x,y = win.getMessagePos(lParam); __/*鼠标左键在控件上单击,\norphanWindow模式下如果阻止控件得到焦点,此事件不会被触发*/ } !winUiTracker.onMouseUp = @.onMouseUp = function(wParam,lParam){ var x,y = win.getMessagePos(lParam); __/*鼠标左键弹起*/ } !winUiTracker.onRightMouseDown = @.onRightMouseDown = function(wParam,lParam){ var x,y = win.getMessagePos(lParam); __/*鼠标右键按下*/ } !winUiTracker.onRightMouseUp = @.onRightMouseUp = function(wParam,lParam){ var x,y = win.getMessagePos(lParam); __/*鼠标右键弹起*/ } !winUiTracker.onMouseWheel = @.onMouseWheel = function(flags,delta,lParam){ delta = delta/(120/3); __/*滚动鼠标滚轮,flags 参数以 _MK_CONTROL 等常量表示按键*/ } !winUiTracker.onMouseHWheel = @.onMouseHWheel = function(flags,delta,lParam){ delta = -delta/(120/3); __/*水平滚动鼠标滚轮,flags 参数以 _MK_CONTROL 等常量表示按键*/ } !winUiTracker.onMouseDoubleClick = @.onMouseDoubleClick = function(wParam,lParam){ var x,y = win.getMessagePos(lParam); __/*鼠标双击*/ } !winUiTracker.onKeyDown = @.onKeyDown = function(keyCode,lParam,repeat){ __/*按下键盘键*/ } !winUiTracker.onKeyUp = @.onKeyUp = function(keyCode,lParam){ __/*放开键盘键*/ } !winUiTracker.onSysKeyDown = @.onSysKeyDown = function(keyCode,lParam,repeat){ if(keyCode!=0x12/*_VK_ALT*/){ __/*按下键盘ALT组合键*/ } } !winUiTracker.onSysKeyUp = @.onSysKeyUp = function(keyCode,lParam){ __/*放开键盘键*/ } !winUiTracker.onFocusGot(hLostFocus) = @.onFocusGot = function(hLostFocus){ ..win.setFocus(hLostFocus);__/*得到焦点触发此事件,hLostFocus为失去焦点的窗口句柄,\n如果在这里将hLostFocus恢复焦点,则阻止当前窗口得到焦点*/ } !winUiTracker.onFocusLost(hFocus) = @.onFocusLost = function(hFocus){ __/*失去焦点触发此事件,hFocus为得到焦点的窗口句柄*/ } !winUiTracker.onStateChange = @.onStateChange = function(){ __/*状态已改变*/ } !winUiTracker.onSelectChange = @.onSelectChange = function(prev,current){ __/*单选模式下已选中当前控件,prev 为同一分组之前选中的控件。\n同一分组之前没有选中控件时 prev 为 null。\ncurrent 为当前选中控件。*/ } !winUiTracker.onMouseActivate = @.onMouseActivate = function(hwndTop,hitTest,message){\n return _MA___/*鼠标点击并且将要激活窗口时触发此事件\nhwndTop表示被激活的顶层窗口,\nhitTest参数请参考WM_NCHITTEST消息\nmessage为鼠标消息ID\n返回值的作用请参数MSDN*/\n} end intellisense**/