这是用 GDI+ 完全重写的 ToolTip 。
BeautifulToolTip ,以下简称 BTT 。
为什么要重写一个 ToolTip 呢,因为下面4个问题真的很烦人。
- 闪烁
- 坐标乱飘
- 文本难以对齐
- 难以在显示前预知大小
BTT 被设计为可以完全取代 ToolTip ,所以它完全兼容 ToolTip 的语法及设置。
- 显示一个内容
btt("This is BeautifulToolTip")
- 清空一个内容
btt()
- 指定 x,y 及 WhichToolTip
btt("This is BeautifulToolTip`n`nWhichToolTip = 2",500,500,2) Sleep, 5000 btt(,,,2)
- CoordMode 命令也对 BTT 生效
CoordMode, ToolTip, Screen btt("This is BeautifulToolTip") Sleep, 5000 btt()
除了上面基本用法, BTT 还拥有多个内置样式,使用依然简单。
- 使用内置样式“Style1”
btt("This is BeautifulToolTip",,,, "Style1")
- 更多内置样式的效果
- 自定义样式也非常简单,只需更改模板参数!
#SingleInstance Force SetBatchLines, -1 Text= ( 使用模板可以轻松创建自己的风格。 欢迎分享,带张截图!!! Use template to easily create your own style. Please share your custom style and include a screenshot. It will help a lot of people. ) ; 照着模板改参数就可以创建自己的风格了。建好后可以添加到 btt() 函数里,就可以变内置风格了。 Template := {Border:20 ; If omitted, 1 will be used. Range 0-20. , Rounded:30 ; If omitted, 3 will be used. Range 0-30. , Margin:30 ; If omitted, 5 will be used. Range 0-30. , TabStops:[50, 80, 100] ; If omitted, [50] will be used. This value must be an array. , BorderColor:0xffaabbcc ; ARGB , BorderColorLinearGradientStart:0xff16a085 ; ARGB , BorderColorLinearGradientEnd:0xfff4d03f ; ARGB , BorderColorLinearGradientAngle:45 ; Mode=8 Angle 0(L to R) 90(U to D) 180(R to L) 270(D to U) , BorderColorLinearGradientMode:1 ; Mode=4 Angle 0(L to R) 90(D to U), Range 1-8. , TextColor:0xff112233 ; ARGB , TextColorLinearGradientStart:0xff00416a ; ARGB , TextColorLinearGradientEnd:0xffe4e5e6 ; ARGB , TextColorLinearGradientAngle:90 ; Mode=8 Angle 0(L to R) 90(U to D) 180(R to L) 270(D to U) , TextColorLinearGradientMode:1 ; Mode=4 Angle 0(L to R) 90(D to U), Range 1-8. , BackgroundColor:0xff778899 ; ARGB , BackgroundColorLinearGradientStart:0xff8DA5D3 ; ARGB , BackgroundColorLinearGradientEnd:0xffF4CFC9 ; ARGB , BackgroundColorLinearGradientAngle:135 ; Mode=8 Angle 0(L to R) 90(U to D) 180(R to L) 270(D to U) , BackgroundColorLinearGradientMode:1 ; Mode=4 Angle 0(L to R) 90(D to U), Range 1-8. , Font:"Font Name" ; If omitted, ToolTip's Font will be used. Can specify the font file. , FontSize:20 ; If omitted, 12 will be used. , FontRender:5 ; If omitted, 5 will be used. Range 0-5. , FontStyle:"Regular Bold Italic BoldItalic Underline Strikeout"} ; Same as Style7 OwnStyle1 := {Border:20 , Rounded:30 , Margin:30 , BorderColor:0xffaabbcc , TextColor:0xff112233 , BackgroundColorLinearGradientStart:0xffF4CFC9 , BackgroundColorLinearGradientEnd:0xff8DA5D3 , BackgroundColorLinearGradientAngle:0 , BackgroundColorLinearGradientMode:8 , FontStyle:"BoldItalic Underline"} btt(Text,,,,OwnStyle1) Sleep, 10000 ExitApp
通过更改 BTT 的 Options 参数,可以很容易的实现一些特效。
- 淡入
for k, v in [15,35,55,75,95,115,135,155,175,195,215,235,255]
{
btt(Text,,,,"Style7",{Transparent:v})
Sleep, 30
}
- 淡出
for k, v in [240,220,200,180,160,140,120,100,80,60,40,20,0]
{
btt(Text,,,,"Style7",{Transparent:v})
Sleep, 30
}
- 改变“渐变角度”参数实现动画效果
- 窗口跟随
btt(Text,800-1,600-1,,"Style1",{TargetHWND:target})
- 计算最终显示大小
ret := btt("test",,,,,{JustCalculateSize:1})
MsgBox, % "宽:" ret.w " 高:" ret.h
除了以上这些 BTT 还实现了
- 多显示器支持
- 多DPI支持
但这里就不再演示了,自己看打包的示例或者源码中的说明。
最后,在即没有原版那些烦人问题,又拥有诸多新特性的同时。
BTT 的性能 —— 比原版快 2-1000 倍!!!!!!
- 原版 CPU 占用率
- BTT CPU 占用率
- 耗时对比
强烈建议你把 BTT库 及 引用库 放 AHK 公用 Lib 目录里。
也就是说,把 BTT.ahk 、 Gdip_All.ahk 、 NonNull.ahk 放下面目录里(没有就手动新建)
C:\我的电脑\Documents\AutoHotkey\Lib
这样你在每次使用的时候,就不需要再 #Include BTT.ahk 了。
好了,快抛弃 ToolTip 拥抱 BTT 吧!!!秀出你自定义的style!!!
下载地址:
https://github.com/telppa/BeautifulToolTip/releases
更新日志:
- 2021.10.03
改变 Include 方式,降低库冲突的可能性。
- 2021.09.29
支持设置 TabStops 。
除 GDIP 库外所有函数内置到 Class 中,降低库冲突的可能性。
- 2021.04.30
修复 Win7 下不能运行的 bug 。(2021.04.20 引起)
- 2021.04.20
支持根据显示器 DPI 缩放比例自动缩放,与 ToolTip 特性保持一致。
支持直接使用未安装的本地字体。
Options 增加 JustCalculateSize 参数,可在不绘制内容的前提下直接返回尺寸。
- 2021.03.07
增加 4 种渐变模式。 - 2021.03.05
删除渐变方向参数。
增加渐变角度参数,支持 360° 渐变。
增加渐变模式参数,支持 4 种模式。
- 2021.03.03
文本色支持渐变。
增加 Style8 。
增加3个渐变方向。 - 2021.03.02
细边框色支持渐变。
增加 Style7 。
增加2个渐变方向。 - 2021.03.01
BTT 的总在最上级别现在跟 ToolTip 一样高了。
解决 BTT 被不明原因置底导致误以为没显示的问题。
增加 Style6 。
文字显示更加居中。 - 2021.02.22
增加返回值与 Transparent 参数。
下载链接呢,着急变成生产力
刚才搞排版呢,太难了。
地址给出来了。
哪里不舒服 跟我说 我反馈给模板作者
说实话,就没一样舒服的,简直就是折磨…… 比如,我添加了那个行最前面的小圆点,之后要加一个空白行出来,简直就太难,还不如直接编辑html简单。
具体点,老哥,比如哪个地方 怎么不舒服,这个很需要
牛逼牛逼.
这是我在本论坛看过最工整漂亮的一个帖子,感谢!!!???
搞了1小时多呢,能不工整吗?
感谢提供!
不能加上一个鼠标拖放的功能 .这样用起来就更加爽了.
就是可以把显示的窗口随意拖放位置.
设计是替代 tooltip 的,所以这种功能我就不提供了,你可以自己包装一层实现一下,btt 提供了句柄返回值的。
测试如下代码,按ESC退出脚本的时候经常出现AutoHotkey停止工作的情况。怀疑Show label中,如果里面的命令比较多的话,执行时间长,容易出问题。
测试方法: 运行脚本1秒钟之后,按ESC退出脚本,反复测试几次,很容易出现AutoHotkey停止工作的错误.
#SingleInstance Force
SetBatchLines, -1
CoordMode, ToolTip, Screen
DetectHiddenWindows, Off
SetTimer,Show, 10
Show:
f1()
f1()
f1()
f1()
Text := “hello world”
btt(Text,,300,,”Style2″)
return
f1()
{
CoordMode, Mouse, Screen
CoordMode, Pixel, Screen
MouseGetPos, mX, mY, Win_Id,Ctrl_ClassNN
CoordMode, Mouse, Window
MouseGetPos, mX_w, mY_w
PixelGetColor, colr1, %mX%, %mY%, RGB
}
esc::
exitapp
return
好像在 SetTimer,Show, 10 之后加一个 return 就可以了
使用BeautifulToolTip 内存升高比较快,当BTT不显示的时候,能释放内存吗?
根据我的测试,每个不同的 WhichToolTip 大概增加8M内存。
如果你一定要去释放这些内存的话,那么这样写。
BTT := new BeautifulToolTip()
BTT.ToolTip(11111111)
BTT.ToolTip()
BTT:=””
#Include btt.ahk
代价是速度会显著下降,并且写起来麻烦多了。
我测试发现 执行清理画布 Gdip_GraphicsClear(this[“G” WhichToolTip]) (大致在243行)这一行,内存一下子增加到30多M。 我把这个注释掉之后,可以正常显示,但内存维持在10M以内。 然后关闭显示btt(),内存也会一下子增加到30多M。 内存占用大 是不是画布的原因?
内存占用大 是不是 清理 画布的原因?
不清理画布,我打开15个tooltip 内存才18M
15个btt还是15个tooltip?
另外你是同一个btt打开15次,还是whichtooltip参数分别设置为1-15的那样同时打开15个?
昨天测试的 是同一个btt whichtooltip参数分别设置为1-15的那样同时打开15个,当时我是把Gdip_GraphicsClear(this[“G” WhichToolTip])注释掉测试的。
如果CreateDIBSection用的是整个虚拟屏幕的长和宽,则执行一次Gdip_GraphicsClear内存就立即升高到30M(我是双屏幕测试的)。 我在BeautifulToolTip Class中把CreateDIBSection的长和宽设置为1000和800 ,并把GraphicsClear的注释打开,测试内存只升高几M。 1000X800的尺寸对于一般的显示 完全够用。
另外,我上面留言说 导致AutoHotkey 崩溃的问题,后来测试加上一个 return就没问题了,不知道什么原因。
还有,当我BTT:=”” 这样释放内存后,按Win + L锁屏,再解锁,也出现了AutoHotkey崩溃 停止工作的问题, 不知道是什么原因?
1 关于锁屏崩溃的问题,因为我脚本中另外一个地方也用到了pToken,我把 BeautifulToolTip类中的
pToken换成了全局统一用的pToken,而不是自己创建pToken,__Delete函数中注释掉 Gdip_Shutdown(this.pToken)。 然后锁屏就不再崩溃了。
2 上面加return才不崩溃的问题,因为我另外一个脚本中有在用pToken,两个相互影响?? 我测试 把 Gdip_Shutdown(this.pToken)注释掉,就可以了。
初步来看:
1 好像同一个程序中,只能有一个pToken 。
2 不同程序中,都打开了pToken,可能会相互影响。
以上两点不知道,理解的对不对。
另外,我在btt函数中添加了如下代码,每次Text为空时,检查所有whichtooltip的Text如果都为空,则释放内存,如果对内存要求高的,可以尝试。
if(!Text and BTT and BTT.check_is_all_null()) ;如果每个tooltip都为空了,则清理内存。
BTT:=””
check_is_all_null() 是在BeautifulToolTip类中添加的函数 检测是否所有whichtooltip的Text如果都为空:
check_is_all_null()
{
loop % this.NumToolTips
if(this[“SavedText” A_Index])
return 0
return 1
}
你这个问题吧,就是在于,不停的关闭gdip然后又初始化它,然后还多个地方初始化gdip,还没开多实例。
完全不建议其它人用同样的方式去做,你目前改代码属于拎着一半就跑的那种,意思就是很多地方的代码并没有完全弄明白就改掉了。这样就结果就是,虽然看起来好像运行了,但其实又给自己引入了很多bug(你后来的那些bug似乎都是这样引入的)。我建议如果你特别介意内存的问题,可以试试局部清空画布之类的方式去实现(这是基于你前面说,画布一清空,内存立马就飚高,所以我猜测,会不会是清空的时候,某种值填满了整个画布,所以建议你尝试局部清空。另外,你后面又说,改了画布初始大小,所以我现在也分不清,到底是大小问题影响的,还是清空问题影响的)。
CreateDIBSection 设很大,是因为你复制一篇很长的文章就明白了。
是的,画布设置小了,如果要显示的文字很多就会显示不全。
所以我根据个人需要指定了一个适合自己的尺寸1000X800 。
如果画布设置的大,执行Gdip_GraphicsClear,则内存升高的就多,如果设置的小,执行Gdip_GraphicsClear,则内存升高的小(这是我测试得到的结果)。
我是双屏幕,画布由原来的尺寸(整个虚拟屏幕)改成1000X800,内存由原来的30多M变成了几M。
如果不对BeautifulToolTip做任何修改的话,多次测试得到如下结论:
1 我是双屏幕,每开一个whichtooltip,内存新增差不多30M。
2 使用BTT的话,如果自己脚本中其他地方有用Gdip,在退出脚本的时候,如果清理自己创建的Gdip(Gdip_Shutdown(pToken)) 会导致AutohotKey崩溃。
3 执行如下脚本,2秒过后,按ESC会导致AutoHotkey崩溃,把return的注释取消掉,就没事了,不知道什么原因,你可以测试一下。
#SingleInstance Force
CoordMode, ToolTip, Screen
SetTimer,Show, 10
;return
Show:
Text := “hello world”
btt(Text,,300,,”Style2″)
return
esc::exitapp
我会想想有没有不影响性能和兼容性的,纯改善内存占用的方法。如果没想出来的话,建议还是正常用,不要太在意那点内存占用(想想 chrome 一个页面都比咱全开完占的多 是不是好受一些了?)
我测试了,return注释取消或不取消,2秒后或2秒内,都正常。
? 我电脑的问题??
好的,非常感谢你的脚本及抽空回答!
如果你要开很多个gdip,在初始化函数里,传入值 1(代表开启多实例)。还有注意返回值不要取一个名字,例如 pToken1 pToken2 pToken3.
好的,我抽空再试试
SysGet, VirtualWidth, 78
SysGet, VirtualHeight, 79
this.DIBWidth := VirtualWidth
this.DIBHeight := VirtualHeight
this[“hbm” A_Index] := CreateDIBSection(this.DIBWidth, this.DIBHeight)
如果创建hbm的时候,使用这个虚拟屏幕,则执行Gdip_GraphicsClear后,内存立即升高,我是双屏幕测试,内存立即升高到30多M。
感谢大佬分享
這邊高手真多,謝謝大老的分享,有的學習了。
一位网友,基于btt做的multibtt。
#include
CoordMode, ToolTip, Screen
t1 := new muti_btt(“11111111”, 100, 100, 1000)
t2 := new muti_btt(“22222222”, 200, 200, 2000)
t3 := new muti_btt(“33333333”, 300, 300, 3000)
t4 := new muti_btt(“44444444”, 400, 400, 4000)
t5 := new muti_btt(“55555555”, 500, 500, 5000)
class muti_btt {
static s_tooltip_number := 1
__New(txt, x, y, show_time) {
this.timer := ObjBindMethod(this, “Tick”)
this.x := x
this.y := y
this.txt := txt
this.show_time := show_time
this.which := this.base.s_tooltip_number
if(this.base.s_tooltip_number == 20)
{
this.base.s_tooltip_number := 0
}
this.base.s_tooltip_number++
this.Start()
}
Start() {
timer := this.timer
SetTimer % timer,% -this.show_time
btt(this.txt, this.x, this.y, this.which)
}
Stop() {
timer := this.timer
SetTimer % timer, Off
btt(,,, this.which)
}
Tick() {
this.stop()
}
}
v2用户拥抱不上?
[…] btt 显示速度、效果完爆内置tooltip 2021.10.03 BeautifulToolTip 高兼容 高性能 简单易用 自定义效果丰富的 ToolTip &ndash… […]
感谢大佬,体验超棒!!
膜拜大佬
不错
非常感谢大佬的写的东西,对我非常有帮助???
想请教,如何用BTT实现上文中右端文本对齐??
有个问题,公司的系统还是xp的
btt(“test”,,,,”style1″)
这个是可以显示的
但是无论下面那种指令都无法让Btt消失
Btt()
Btt(“”)
btt(,,,,”style1″)
btt(“”,,,,”style1″)
让它消失的方法,除了重载脚本之外都无法
通过更改 BTT 的 Options 参数,可以很容易的实现一些特效。
请问哪里可以看到有哪些参数可以设定的?
有哪些参数可以使用?
可以直接在函数内指定字型吗?
btt(“Text2”, 500, 350,, “Style1”,{FontSize:20}) 像這樣之類的