//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**/