//syslink 超链接控件 import win.ui.ctrl.metaProperty; namespace win.ui.ctrl; class syslink{ ctor(parent,tParam){ if(tParam){ if(tParam.transparent) { tParam.style |= 1/*_LWS_TRANSPARENT*/ } if( tParam.align == "right" ){ tParam.style |=0x0020/*_LWS_RIGHT*/; } //_LWS_USEVISUALSTYLE 无用且有 bug,例如远程重连导致控件无法显示 //if( _WIN7_LATER ) tParam.style |= 8/*_LWS_USEVISUALSTYLE*/ } } @_metaProperty; } namespace syslink{ class LITEM { INT mask= 0xF/*_LIF_ITEMINDEX | _LIF_STATE | _LIF_ITEMID | _LIF_URL*/; int iLink; INT state; INT stateMask; WORD id[48]; WORD url[2084]; } _metaProperty = ..win.ui.ctrl.metaProperty( link = { _get = function(){ var i = owner.getItem(); return i?i.url; }; _set = function(url){ var item = LITEM(); item.mask = 1|8; item.url = url; if( ! ::SendMessageByStruct(owner.hwnd,0x702/*_LM_SETITEM*/,0,item) ){ var t = owner.text; owner.text = `` + t + ``; } }; } setItem = function(item){ item.iLink = item.iLink - 1 var r = !! ::SendMessageByStruct(owner.hwnd,0x702/*_LM_SETITEM*/,0,item); item.iLink = item.iLink + 1; return r; } getItem = function(idx){ var item = LITEM(); if(idx) item.iLink = idx-1; if( ::SendMessageByStruct(owner.hwnd,0x703/*_LM_GETITEM*/,0,item) ){ item.iLink = item.iLink + 1; return item; } }; _prenotify = { [0xFFFFFFFC/*_NM_RETURN*/] = function(id,code,ptr,nmhdr){ var nmSysLink = ..raw.convert(ptr,{ struct hdr = ::NMHDR(); struct item = LITEM(); }); var url = nmSysLink.item.url; if( owner.onHyperlinkClick ){ owner.onHyperlinkClick(nmSysLink,url,nmSysLink.item.id,nmSysLink.item.iLink) } elseif(#url){ ..raw.execute(url); } }; [0xFFFFFFFE/*_NM_CLICK*/] = function(id,code,ptr,nmhdr){ var nmSysLink = ..raw.convert(ptr,{ struct hdr = ::NMHDR(); struct item = LITEM(); }); var url = nmSysLink.item.url; if( owner.onHyperlinkClick ){ owner.onHyperlinkClick(nmSysLink,url,nmSysLink.item.id,nmSysLink.item.iLink) } elseif(#url){ ..raw.execute(url); } } }; ) } //@guide [范例](doc://example/Windows/Controls/syslink.html) /***intellisense() !syslink.cls = 设计时类名 !syslink.className = 运行时类名 !syslink.hwnd = 控件句柄 !syslink.id = 控件 ID,注意这个不是指超链接的 ID。 !syslink.text = 控件文本。\n此控件的文本属性支持 HTML 的超链接语法,也就是 a 标签。\n超链接可选使用 href 属性设置超链接,可选使用 id 属性指定链接 ID。\n一个控件可以指定多个普通文本或者超链接,使用超链接索引区分。\n不支持其他 HTML 语法,例如换行应当直接换行而不是使用 `
`换行。\n\n可使用 link 属性获取或设置第一个超链接地址。 !syslink.link = 创建、设置或者获取控件的第一个超链接地址。\n这个参数应当指定一个网址,可使用任意协议。 !syslink._parentForm = 返回创建控件的容器窗口(win.form对象),所有窗口控件都拥有此只读属性。\n对于使用窗体设计器创建的窗口,也就是返回设计时窗体容器。\n\n即使子窗口移除子窗口样式、更改父子关系,或以 orphanWindow显示,\n控件的 _parentForm 始终都不会改变\n!winform. !syslink.getParent() = 返回父窗口\n!syslink. !syslink.setParent(__/*控件对象*/) = 改变父窗口 !syslink.translateAccelerator = @.translateAccelerator = function(msg){ \n __/*返回是否快捷键*/\n} !syslink.adjust = @.adjust = function( cx,cy,wParam ) { \n __ \n}; !syslink.adjust() = 调整窗口 - 自定义事件函数 !syslink.hide = 控件是否隐藏 !syslink.disabled = 是否禁用 !syslink.left = 左侧坐标 !syslink.right = 右侧坐标 !syslink.top = 顶部坐标 !syslink.bottom = 底部坐标 !syslink.width = 宽度 !syslink.height = 高度 !syslink.redraw() = 刷新 !syslink.setRedraw(false) = 禁止重绘 !syslink.setRedraw(true) = 恢复重绘 !syslink.show(true__) = 显示控件 !syslink.getRect() = 控件区块位置(::RECT结构体) !syslink.getRect(true) = 控件屏幕区块位置(::RECT结构体) !syslink.setRect(rc) = 设置控件区块位置(::RECT结构体) !syslink.setRect(rc,true) = 设置控件屏幕区块位置(::RECT结构体) !syslink.getClientRect() = 控件客户区块位置(::RECT结构体)\n!rect. !syslink.getFont() = 控件字体(::LOGFONT结构体)\n!logfont. !syslink.setFont(__/*指定字体*/) = 指定LOGFONT字体对象,或逻辑字体句柄 !syslink.setFont(混入字体属性) = @.setFont(point=10;name="宋体"); !syslink.theme = 外观主题,例如\nwinform.button.theme = "Explorer"\nwinform.button.theme = false !syslink.modifyStyle(.(remove,add,swpFlags) = 修改窗口样式,所有参数都是可选参数,\n@remove 用数值指定要移除的样式,可使用 _WS_ 前缀的常量\n@add 用数值指定要添加的样式,可使用 _WS_ 前缀的常量\n@swpFlags 可选用数值指定调整窗口选项,可使用 _SWP_ 前缀的常量\n如果指定了 @swpFlag ,则使用该参数调用::SetWindowPos\n细节请参考 win.modifyStyle 函数源码 !syslink.modifyStyleEx(.(remove,add,swpFlags) = 修改窗口扩展样式,所有参数都是可选参数,\n@remove 用数值指定要移除的样式,可使用 _WS_EX_ 前缀的常量\n@add 用数值指定要添加的样式,可使用 _WS_EX_ 前缀的常量\n@swpFlags 可选用数值指定调整窗口选项,可使用 _SWP_ 前缀的常量\n如果指定了 @swpFlag ,则使用该参数调用::SetWindowPos\n细节请参考 win.modifyStyle 函数源码 !syslink.capture = 是否捕获全局鼠标消息 !syslink.close() = 关闭控件窗口 !syslink.invalidate(__/*可选使用::RECT()对象指定客户区*/) = 使窗口绘图区无效 !syslink.invalidate(__/*可选使用::RECT()对象指定客户区*/,0) = 使窗口绘图区无效\n不刷新背景 !syslink.update() = 重绘invalidate函数指定的区块 !syslink.setFocus() = 设置焦点 !syslink.setPos(.(x坐标,y坐标,宽,高,插入位置,参数) = 调整窗口位置或排序,所有参数可选\n同时指定x,y坐标则移动位置\n同时指定宽高则改变大小\n指定插入位置(句柄或_HWND前缀常量)则调整Z序 !syslink.getPos() = 返回相对坐标,宽,高\nx,y,cx,cy=win.getPos(hwnd) !syslink.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) !syslink.changeInterval(.(定时器ID,间隔时间,回调函数) = 重新设置间隔时间或回调函数 !syslink.clearInterval(__/*定时器ID*/) = 删除定时器 !syslink.getItem(__/*索引*/) = 返回超链接设置,该值为 LITEM 结构体。\n参数指定获取第几个超链接的设置,默认值为 1。 !syslink.setItem(.(item) = 修改超链接设置,参数为 getItem 函数返回的 LITEM 结构体 !syslink.getItem() = !syslinklitem. !syslink.onHyperlinkClick = @.onHyperlinkClick = function(nmSysLink,url,id,index){ raw.execute(url);__/*点击超链接回调此事件,可使用此代码打开超链接。\n如果不指定回调函数,控件会默认调用 raw.execute 打开链接。\nnmSysLink 为通知消息使用的 LITEM 结构体,一般忽略即可。\nurl 为触发的超链接地址,也就是 href 属性。\nid 为触发的链接 ID,也就是 id 属性。\nindex 为索引,一个控件可以有多个超链接,第一个超链接索引为 1。*/ } !syslinklitem.mask = 有效字段掩码。\n默认已设为 _LIF_ITEMINDEX | _LIF_STATE | _LIF_ITEMID | _LIF_URL !syslinklitem.iLink = 索引。\n一个控件可以有多个超链接,第一个超链接索引为 1。 !syslinklitem.state = 状态,一般用不上。\n可选值为 _LIS_ENABLED, _LIS_FOCUSED, _LIS_VISITED 等 !syslinklitem.stateMask = 有效状态掩码 !syslinklitem.id = 超链接的 ID 属性。 !syslinklitem.url = 超链接的 URL 属性。 ?win.ui.ctrl.syslink = !syslink. win.ui.ctrl.syslink() = 超链接控件。\n!syslink. win.ui.ctrl.syslink = 超链接控件类 end intellisense***/ /**details(用法步骤) 请参考: - [使用自定义控件类指南](doc://library-guide/std/win/ui/ctrl/custom.html#cls) - [syslink 控件使用范例](doc://example/Windows/Controls/syslink.html) atlax 控件用法步骤: 1. 拖一个 custom 控件放到界面上,控件类名改为"atlax" 2. 然后在 atlax 控件的文本属性中指定要创建的 COM 类名,例如 "InkEd.InkEdit" end details**/