HTA(HTML Application)是微软提供的一种允许将HTML、脚本语言(VBScript/JScript)和ActiveX组件打包成独立应用程序的技术。本文基于一个经典的HTA五子棋界面实例,拆解其核心实现:如何利用VBScript动态生成19×19棋盘,并实现鼠标悬停预览与点击落子交互。无需任何框架,仅用纯前端脚本即可快速制作一个可用的五子棋界面原型。
一、HTA应用配置
创建文件保存为 .hta 后缀,通过 <HTA:APPLICATION> 标签定义窗口行为,例如:- <HTA:APPLICATION
- ID="MyhyliApp"
- APPLICATIONNAME="五子棋界面 - zh159"
- BORDER="thin"
- BORDERSTYLE=""
- VERSION="1.0"
- SCROLL="no"
- ICON="C:\WINDOWS\System32\wuauclt.exe"
- INNERBORDER="no"
- CONTEXTMENU="no"
- CAPTION="yes"
- MAXIMIZEBUTTON="no"
- MINIMIZEBUTTON="yes"
- SHOWINTASKBAR="yes"
- SINGLEINSTANCE="yes"
- SYSMENU="yes"
- WINDOWSTATE="normal"
- NAVIGABLE="yes"
- />
复制代码 关键参数说明:SCROLL="no" 禁用滚动条;CAPTION="yes" 保留标题栏;MAXIMIZEBUTTON="no" 禁止最大化;SINGLEINSTANCE="yes" 保证只运行一个实例。ICON可以指定任意EXE路径,此处使用了系统自带的wuauclt.exe。
二、动态棋盘生成逻辑
棋盘共19行19列,对应传统五子棋规格。原文使用VBScript循环,借助字符串 "ABCDEFGHIJKLMNOPQRS"(19个字母)标记行列,通过MID函数取出坐标。核心技巧是使用多个条件判断,在边界位置绘制不同的制表符(┌ ┬ ┐ ├ ┼ ┤ └ ┴ ┘),内部格子统一使用“┼”。生成的每个TD都包含一个SPAN元素,初始显示“┼”。- For i = 1 To Len(str)
- with document
- .write "<tr align='center'>"
- For n = 1 To Len(str)
- stri = MID(str,i,1)
- strn = MID(str,n,1)
- tdstr = "<td id='GUI_" & strn & stri & "' class='GUIwh'><span onclick='Test(this)' onMouseOver='innerText=""●"";style.color=""blue""' onMouseOut='innerText=""┼"";style.color=""""'>┼</span></td>"
- s = "┼"
- If (stri = "A" and strn = "A") Then .write Replace(tdstr,s,"┌")
- ' … 其他边界判断省略 …
- Next
- .write "</tr>"
- end with
- Next
复制代码 这种写法虽然繁琐但非常直观:通过行列首尾字母判断所在位置是否在边界,进而替换对应的制表符。对于不需要图形库的环境,这是纯文本绘制棋盘的最简方案。
三、交互事件与落子处理
每个SPAN绑定了三个事件:
onclick 触发 Test 函数(VBScript):- Sub Test(this)
- this.parentNode.style.cursor = "default"
- this.parentNode.innerHtml = "●"
- PC.style.display = "none"
- End Sub
复制代码 点击后将父节点(TD)内容替换为实心圆“●”,并隐藏右侧的“电脑先下”按钮。注意此版本只有界面,未实现AI或胜负判定,因此“电脑先下”按钮仅做展示。
onMouseOver 和 onMouseOut 实现鼠标悬停时显示蓝色圆点预览,移出恢复为“┼”。
四、窗口居中与标题动态更新
在页面底部添加VBScript代码,调整窗口大小并居中:- width = 660
- height = 550
- window.resizeTo width, height
- ileft=(window.screen.width-width)/2
- itop=(window.screen.height-height)/2
- window.moveTo ileft,itop
复制代码 同时通过 setInterval 每秒更新一次文档标题,显示当前日期和星期:- Sub Title
- Document.title = "五子棋 - zh159 - " & FormatDateTime(Now, 1) & " " & WeekdayName(WeekDay(now)) & " " & FormatDateTime(Now, 3)
- End Sub
- Title:setInterval "Title()",500
复制代码 这一细节体现了HTA对系统时间与脚本的灵活调用能力。
五、适用场景与扩展建议
本示例适合作为HTA入门教学、VBScript动态生成表格的演示,或者快速搭建一个带棋盘的交互原型。如需完善为完整五子棋游戏,可在此基础上添加:
- 二维数组记录落子状态
- 胜负判定算法(连五检测)
- 简单AI(如评分法)
- 悔棋与重启功能
注意:HTA只能运行在Windows系统,且现代浏览器已不再支持ActiveX,因此仅适用于企业内部工具或旧系统维护场景。对于Web应用,建议改用Canvas+JavaScript实现。
附完整代码(保存为 .hta 运行):- <html>
- <title>五子棋界面 - zh159</title>
- <hrad>
- <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
- <HTA:APPLICATION
- ID="MyhyliApp"
- APPLICATIONNAME="五子棋界面 - zh159"
- BORDER="thin"
- BORDERSTYLE=""
- VERSION="1.0"
- SCROLL="no"
- ICON="C:\WINDOWS\System32\wuauclt.exe"
- INNERBORDER="no"
- CONTEXTMENU="no"
- CAPTION="yes"
- MAXIMIZEBUTTON="no"
- MINIMIZEBUTTON="yes"
- SHOWINTASKBAR="yes"
- SINGLEINSTANCE="yes"
- SYSMENU="yes"
- WINDOWSTATE="normal"
- NAVIGABLE="yes"
- />
- </hrad>
- <script language="javascript"></script>
- <script language="VBScript"></script>
- <style>
- .GUIwh {width:24;height:24;cursor:hand;}
- </style>
- <body background="bg.gif" scroll="no" style="background: SteelBlue ;color:#ffffff;">
- <table align="center" width="630" border="1" cellspacing="0" cellpadding="10" borderColor="#ffffff" style="font: 13px 宋体;border-collapse:collapse;">
- <tr align="center">
- <td width="450" height="450">
- <table border="0" cellspacing="0" cellpadding="0" borderColor="#ffffff" style="font: 21px 宋体;border:2px solid #ffffff;">
- <script language="VBScript">
- str = "ABCDEFGHIJKLMNOPQRS"
- For i = 1 To Len(str)
- with document
- .write "<tr align='center'>"
- For n = 1 To Len(str)
- stri = MID(str,i,1)
- strn = MID(str,n,1)
- tdstr = "<td id='GUI_" & strn & stri & "' class='GUIwh'><span onclick='Test(this)' onMouseOver='innerText=""●"";style.color=""blue""' onMouseOut='innerText=""┼"";style.color=""""'>┼</span></td>"
- s = "┼"
- If (stri = "A" and strn = "A") Then .write Replace(tdstr,s,"┌")
- If stri = "A" Then If not (strn = "A" or strn = "S") Then .write Replace(tdstr,s,"┬")
- If (stri = "A" and strn = "S") Then .write Replace(tdstr,s,"┐")
- If not (stri = "A" or stri = "S") Then If strn = "A" Then .write Replace(tdstr,s,"├")
- If not (stri = "A" or stri = "S" or strn = "A" or strn = "S") Then .write tdstr
- If not (stri = "A" or stri = "S") Then If strn = "S" Then .write Replace(tdstr,s,"┤")
- If (stri = "S" and strn = "A") Then .write Replace(tdstr,s,"└")
- If stri = "S" Then If not (strn = "A" or strn = "S") Then .write Replace(tdstr,s,"┴")
- If (stri = "S" and strn = "S") Then .write Replace(tdstr,s,"┘")
- Next
- .write "</tr>"
- end with
- Next
- </script>
- </table>
- </td>
- <td>
- <span id="PC"><button>电脑先下</button><br><br>直接点击为玩家先下</span>
- </td>
- </tr>
- </table>
- </body>
- <script language="VBScript">
- width = 660
- height = 550
- window.resizeTo width, height
- ileft=(window.screen.width-width)/2
- itop=(window.screen.height-height)/2
- window.moveTo ileft,itop
- Sub Test(this)
- this.parentNode.style.cursor = "default"
- this.parentNode.innerHtml = "●"
- PC.style.display = "none"
- End Sub
- Sub Title
- Document.title = "五子棋 - zh159 - " & FormatDateTime(Now, 1) & " " & WeekdayName(WeekDay(now)) & " " & FormatDateTime(Now, 3)
- End Sub
- Title:setInterval "Title()",500
- </script>
- </html>
复制代码 |