该脚本实现了一个简单的鼠标手势工具,结合图形化显示轨迹,支持手势操作和自定义动作的功能。
功能概述:
- 鼠标手势检测:
- 通过鼠标右键按住并移动,检测鼠标的移动轨迹。
- 根据轨迹方向(例如“上”、“下”、“左”、“右”或复杂轨迹如“右下左”)触发对应的动作。
- 轨迹绘制:
- 实时显示鼠标的移动轨迹。
- 在屏幕上动态绘制鼠标移动的线条,使用不同颜色表示当前轨迹。
- 自定义动作:
- 支持用户自定义手势对应的动作。
- 内置一些示例动作,如:
- 上:上翻页
- 下:下翻页
- 左:后退
- 右:前进
- 右下左:退出程序
- 用户可以通过
tip
字典添加更多手势动作。
- 可视化轨迹面板:
- 利用自定义的图形界面工具(GDI+)在屏幕上绘制轨迹。
- 面板可实时刷新显示手势。
- 兼容常见浏览器:
- 提供对常见浏览器的支持,通过分组功能检测激活的浏览器窗口,限制手势在浏览器中生效。
热键功能:
- 右键拖动 (RButton):
- 开启鼠标手势识别,并显示轨迹。
- 松开右键后,执行对应的手势动作或显示提示。
Esc
:直接退出程序。
核心实现逻辑:
- 手势识别:
- 鼠标移动轨迹分为“上”、“下”、“左”、“右”四个基本方向。
- 通过计算鼠标位置的相对变化(
dx
和dy
)判断当前的方向。 - 累积方向轨迹字符串(如“右下左”),用于匹配手势动作。
- 轨迹绘制:
- 使用自定义的
GDI
类(封装了 Windows GDI 图形绘制功能)绘制鼠标的移动轨迹。 - 每次鼠标移动时,绘制一段线段并刷新显示。
- 使用自定义的
- 手势动作触发:
- 当鼠标右键释放后,检查轨迹字符串是否与预定义的动作匹配。
- 如果匹配,调用对应的动作处理函数。
- 如果未定义动作,提示“没有设置动作”。
- 面板更新和清理:
- 使用
生成画板()
初始化轨迹绘制面板。 显示画板()
和隐藏画板()
控制面板的显示。清空()
和更新()
方法清除或刷新轨迹显示。
- 使用
应用场景:
- 快速操作常用任务:
- 通过简单的鼠标手势实现快捷操作,例如浏览器前进、后退、翻页等。
- 动态反馈:
- 提供实时的轨迹可视化,让用户清楚看到鼠标的移动方向。
- 自定义扩展:
- 用户可以修改
tip
字典,添加更多复杂手势及对应动作。
- 用户可以修改
; 简单可视化鼠标手势 v1.5 By FeiYue
#NoEnv
#SingleInstance, force
SetWinDelay -1
SetBatchLines, -1
CoordMode, Mouse
CoordMode, ToolTip
生成画板()
tip:= { 0 : 0
, "上" : "上翻页"
, "下" : "下翻页"
, "左" : "后退"
, "右" : "前进"
, "右下左" : "退出"
, 0 : 0 }
return
上:
下:
左:
右:
k:=A_ThisLabel
MsgBox, 4096,, % k " > " tip[k], 1
return
右下左:
ExitApp
Esc:: ExitApp
start_01() {
static init:=start_01()
SetTitleMatchMode, 2 ;//匹配部分标题
GroupAdd, MyBrowser, 360安全浏览器
GroupAdd, MyBrowser, 360极速浏览器
GroupAdd, MyBrowser, 搜狗高速浏览器
GroupAdd, MyBrowser, 世界之窗浏览器
GroupAdd, MyBrowser, 2345加速浏览器
GroupAdd, MyBrowser, GreenBrowser
GroupAdd, MyBrowser, Firefox
GroupAdd, MyBrowser, Chrome
GroupAdd, MyBrowser, ahk_class IEFrame
GroupAdd, MyBrowser, ahk_class 360se5_Frame
GroupAdd, MyBrowser, ahk_class 360se6_Frame
GroupAdd, MyBrowser, ahk_class Chrome_WidgetWin_1
GroupAdd, MyBrowser, ahk_class ShockwaveFlashFullScreen
}
#If !WinActive("ahk_group MyBrowser")
RButton::
显示画板(), 轨迹:=方向:=上次方向:="", arr:=[], p:=Tan(60*ATan(1)/45)
MouseGetPos, x1, y1
While GetKeyState("RButton", "P") {
Sleep, 10
MouseGetPos, x2, y2
Loop, % (i:=arr.MaxIndex())>10 ? 10 : i
if ((dx:=x2-arr[i].3)*0+(dy:=y2-arr[i--].4)*0+Abs(dx)>5 or Abs(dy)>5) {
方向:=(Abs(dy)>=Abs(dx)*p) ? (dy<0 ? "上":"下")
: (Abs(dx)>=Abs(dy)*p) ? (dx<0 ? "左":"右") : 方向
Break
}
if (方向!=上次方向)
轨迹.=方向, 上次方向:=方向
if (x1!=x2 or y1!=y2) {
arr.Push([x1,y1,x2,y2]), x1:=x2, y1:=y2
ToolTip, % 轨迹 " > " (tip[轨迹] ? tip[轨迹]:"没有设置动作")
}
color:=A_MSec<500 ? 0xFF9050 : 0x5090FF
For k,v in arr
划线(v.1, v.2, v.3, v.4, color)
更新()
}
ToolTip
清空(), 更新(), 隐藏画板()
if (轨迹="") {
Click, R
return
}
if IsLabel(轨迹)
Goto, %轨迹%
else
MsgBox, 4096,, % 轨迹 " > 没有设置动作", 1
return
#If
;========== 下面是函数 ==========
生成画板() {
global my_gdi
Gui, My_DrawingBoard: New
Gui, +LastFound +AlwaysOnTop -Caption +ToolWindow
+E0x80000 +OwnDialogs +Hwndmy_id +E0x20
; 下面两行结合Bitblt更新与UpdateLayeredWindow更新互斥
; Gui, Color, 0x000000
; WinSet, TransColor, 0x000000
w:=A_ScreenWidth, h:=A_ScreenHeight
Gui, Show, Hide x0 y0 w%w% h%h%, 画板
my_gdi := new GDI(my_id, w, h), 清空()
return
}
显示画板() {
Gui, My_DrawingBoard: Show, NA
}
隐藏画板() {
Gui, My_DrawingBoard: Hide
}
划线(x,y,x2,y2,color=0xFF0000) {
global my_gdi
my_gdi.DrawLine(x, y, x2, y2, Color, 4)
}
更新(color=0x000000) {
global my_gdi
; my_gdi.Bitblt()
my_gdi.UpdateLayeredWindow(0, 0, 0, 0, color)
}
清空(color=0x000000) {
global my_gdi
my_gdi.FillRectangle(0, 0, my_gdi.CliWidth, my_gdi.CliHeight, color)
}
class GDI { ; thanks dwitter, RUNIE
__New(hWnd, CliWidth=0, CliHeight=0) {
if !(CliWidth && CliHeight) {
VarSetCapacity(Rect, 16, 0)
DllCall("GetClientRect", "Ptr", hWnd, "Ptr", &Rect)
CliWidth := NumGet(Rect, 8, "Int")
CliHeight := NumGet(Rect, 12, "Int")
}
this.CliWidth := CliWidth
this.CliHeight := CliHeight
this.hWnd := hWnd
this.hDC := DllCall("GetDC", "UPtr", hWnd, "UPtr")
this.hMemDC := DllCall("CreateCompatibleDC", "UPtr", this.hDC, "UPtr")
this.hBitmap := DllCall("CreateCompatibleBitmap", "UPtr", this.hDC, "Int", CliWidth, "Int", CliHeight, "UPtr")
this.hOriginalBitmap := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", this.hBitmap)
}
__Delete() {
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", this.hOriginalBitmap)
DllCall("DeleteObject", "UPtr", this.hBitmap)
DllCall("DeleteObject", "UPtr", this.hMemDC)
DllCall("ReleaseDC", "UPtr", this.hWnd, "UPtr", this.hDC)
}
Resize(w, h) {
this.CliWidth := w
this.CliHeight := h
this.hBitmap := DllCall("CreateCompatibleBitmap", "UPtr", this.hDC, "Int", w, "Int", h, "UPtr")
hPrevBitmap := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", this.hBitmap)
DllCall("DeleteObject", "UPtr", hPrevBitmap)
}
BitBlt(x=0, y=0, w=0, h=0) {
w := w ? w : this.CliWidth
h := h ? h : this.CliHeight
DllCall("BitBlt", "UPtr", this.hDC, "Int", x, "Int", y
, "Int", w, "Int", h, "UPtr", this.hMemDC, "Int", 0, "Int", 0, "UInt", 0xCC0020) ;SRCCOPY
}
UpdateLayeredWindow(x=0, y=0, w=0, h=0, color=0, Alpha=255) {
w := w ? w : this.CliWidth
h := h ? h : this.CliHeight
DllCall("UpdateLayeredWindow", "Ptr", this.hWnd, "Ptr", 0
, "Int64*", x|y<<32, "Int64*", w|h<<32
, "Ptr", this.hMemDC, "Int64*", 0, "uint", color
, "UInt*", Alpha<<16|1<<24, "uint", 1)
}
DrawLine(x, y, x2, y2, Color, Width=1) {
Pen := new GDI.Pen(Color, Width)
DllCall("MoveToEx", "UPtr", this.hMemDC, "Int", this.TranslateX(x), "Int", this.TranslateY(y), "UPtr", 0)
hOriginalPen := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Pen.Handle, "UPtr")
DllCall("LineTo", "UPtr", this.hMemDC, "Int", this.TranslateX(x2), "Int", this.TranslateY(y2))
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalPen, "UPtr")
}
SetPixel(x, y, Color) {
x := this.TranslateX(x)
y := this.TranslateY(y, this.Invert) ; Move up 1 px if inverted (drawing "up" instead of down)
DllCall("SetPixelV", "UPtr", this.hMemDC, "Int", x, "Int", y, "UInt", Color)
}
FillRectangle(x, y, w, h, Color, BorderColor=-1) {
if (w == 1 && h == 1)
return this.SetPixel(x, y, Color)
Pen := new this.Pen(BorderColor < 0 ? Color : BorderColor)
Brush := new this.Brush(Color)
; Replace the original pen and brush with our own
hOriginalPen := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Pen.Handle, "UPtr")
hOriginalBrush := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Brush.Handle, "UPtr")
x1 := this.TranslateX(x)
y1 := this.TranslateY(y)
x2 := this.TranslateX(x+w)
y2 := this.TranslateY(y+h)
DllCall("Rectangle", "UPtr", this.hMemDC
, "Int", x1, "Int", y1
, "Int", x2, "Int", y2)
; Reselect the original pen and brush
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalPen, "UPtr")
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalBrush, "UPtr")
}
FillEllipse(x, y, w, h, Color, BorderColor=-1) {
Pen := new this.Pen(BorderColor < 0 ? Color : BorderColor)
Brush := new this.Brush(Color)
; Replace the original pen and brush with our own
hOriginalPen := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Pen.Handle, "UPtr")
hOriginalBrush := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Brush.Handle, "UPtr")
x1 := this.TranslateX(x)
y1 := this.TranslateY(y)
x2 := this.TranslateX(x+w)
y2 := this.TranslateY(y+h)
DllCall("Ellipse", "UPtr", this.hMemDC
, "Int", x1, "Int", y1
, "Int", x2, "Int", y2)
; Reselect the original pen and brush
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalPen, "UPtr")
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalBrush, "UPtr")
}
TranslateX(X) {
return Floor(X)
}
TranslateY(Y, Offset=0) {
if this.Invert
return this.CliHeight - Floor(Y) - Offset
return Floor(Y)
}
class Pen {
__New(Color, Width=1, Style=0) {
this.Handle := DllCall("CreatePen", "Int", Style, "Int", Width, "UInt", Color, "UPtr")
}
__Delete() {
DllCall("DeleteObject", "UPtr", this.Handle)
}
}
class Brush {
__New(Color) {
this.Handle := DllCall("CreateSolidBrush", "UInt", Color, "UPtr")
}
__Delete() {
DllCall("DeleteObject", "UPtr", this.Handle)
}
}
}
; 简单可视化鼠标手势 v1.5 By FeiYue
#NoEnv
#SingleInstance, force
SetWinDelay -1
SetBatchLines, -1
CoordMode, Mouse
CoordMode, ToolTip
生成画板()
tip:= { 0 : 0
, "上" : "上翻页"
, "下" : "下翻页"
, "左" : "后退"
, "右" : "前进"
, "右下左" : "退出"
, 0 : 0 }
return
上:
下:
左:
右:
k:=A_ThisLabel
MsgBox, 4096,, % k " > " tip[k], 1
return
右下左:
ExitApp
Esc:: ExitApp
start_01() {
static init:=start_01()
SetTitleMatchMode, 2 ;//匹配部分标题
GroupAdd, MyBrowser, 360安全浏览器
GroupAdd, MyBrowser, 360极速浏览器
GroupAdd, MyBrowser, 搜狗高速浏览器
GroupAdd, MyBrowser, 世界之窗浏览器
GroupAdd, MyBrowser, 2345加速浏览器
GroupAdd, MyBrowser, GreenBrowser
GroupAdd, MyBrowser, Firefox
GroupAdd, MyBrowser, Chrome
GroupAdd, MyBrowser, ahk_class IEFrame
GroupAdd, MyBrowser, ahk_class 360se5_Frame
GroupAdd, MyBrowser, ahk_class 360se6_Frame
GroupAdd, MyBrowser, ahk_class Chrome_WidgetWin_1
GroupAdd, MyBrowser, ahk_class ShockwaveFlashFullScreen
}
#If !WinActive("ahk_group MyBrowser")
RButton::
显示画板(), 轨迹:=方向:=上次方向:="", arr:=[], p:=Tan(60*ATan(1)/45)
MouseGetPos, x1, y1
While GetKeyState("RButton", "P") {
Sleep, 10
MouseGetPos, x2, y2
Loop, % (i:=arr.MaxIndex())>10 ? 10 : i
if ((dx:=x2-arr[i].3)*0+(dy:=y2-arr[i--].4)*0+Abs(dx)>5 or Abs(dy)>5) {
方向:=(Abs(dy)>=Abs(dx)*p) ? (dy<0 ? "上":"下")
: (Abs(dx)>=Abs(dy)*p) ? (dx<0 ? "左":"右") : 方向
Break
}
if (方向!=上次方向)
轨迹.=方向, 上次方向:=方向
if (x1!=x2 or y1!=y2) {
arr.Push([x1,y1,x2,y2]), x1:=x2, y1:=y2
ToolTip, % 轨迹 " > " (tip[轨迹] ? tip[轨迹]:"没有设置动作")
}
color:=A_MSec<500 ? 0xFF9050 : 0x5090FF
For k,v in arr
划线(v.1, v.2, v.3, v.4, color)
更新()
}
ToolTip
清空(), 更新(), 隐藏画板()
if (轨迹="") {
Click, R
return
}
if IsLabel(轨迹)
Goto, %轨迹%
else
MsgBox, 4096,, % 轨迹 " > 没有设置动作", 1
return
#If
;========== 下面是函数 ==========
生成画板() {
global my_gdi
Gui, My_DrawingBoard: New
Gui, +LastFound +AlwaysOnTop -Caption +ToolWindow
+E0x80000 +OwnDialogs +Hwndmy_id +E0x20
; 下面两行结合Bitblt更新与UpdateLayeredWindow更新互斥
; Gui, Color, 0x000000
; WinSet, TransColor, 0x000000
w:=A_ScreenWidth, h:=A_ScreenHeight
Gui, Show, Hide x0 y0 w%w% h%h%, 画板
my_gdi := new GDI(my_id, w, h), 清空()
return
}
显示画板() {
Gui, My_DrawingBoard: Show, NA
}
隐藏画板() {
Gui, My_DrawingBoard: Hide
}
划线(x,y,x2,y2,color=0xFF0000) {
global my_gdi
my_gdi.DrawLine(x, y, x2, y2, Color, 4)
}
更新(color=0x000000) {
global my_gdi
; my_gdi.Bitblt()
my_gdi.UpdateLayeredWindow(0, 0, 0, 0, color)
}
清空(color=0x000000) {
global my_gdi
my_gdi.FillRectangle(0, 0, my_gdi.CliWidth, my_gdi.CliHeight, color)
}
class GDI { ; thanks dwitter, RUNIE
__New(hWnd, CliWidth=0, CliHeight=0) {
if !(CliWidth && CliHeight) {
VarSetCapacity(Rect, 16, 0)
DllCall("GetClientRect", "Ptr", hWnd, "Ptr", &Rect)
CliWidth := NumGet(Rect, 8, "Int")
CliHeight := NumGet(Rect, 12, "Int")
}
this.CliWidth := CliWidth
this.CliHeight := CliHeight
this.hWnd := hWnd
this.hDC := DllCall("GetDC", "UPtr", hWnd, "UPtr")
this.hMemDC := DllCall("CreateCompatibleDC", "UPtr", this.hDC, "UPtr")
this.hBitmap := DllCall("CreateCompatibleBitmap", "UPtr", this.hDC, "Int", CliWidth, "Int", CliHeight, "UPtr")
this.hOriginalBitmap := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", this.hBitmap)
}
__Delete() {
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", this.hOriginalBitmap)
DllCall("DeleteObject", "UPtr", this.hBitmap)
DllCall("DeleteObject", "UPtr", this.hMemDC)
DllCall("ReleaseDC", "UPtr", this.hWnd, "UPtr", this.hDC)
}
Resize(w, h) {
this.CliWidth := w
this.CliHeight := h
this.hBitmap := DllCall("CreateCompatibleBitmap", "UPtr", this.hDC, "Int", w, "Int", h, "UPtr")
hPrevBitmap := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", this.hBitmap)
DllCall("DeleteObject", "UPtr", hPrevBitmap)
}
BitBlt(x=0, y=0, w=0, h=0) {
w := w ? w : this.CliWidth
h := h ? h : this.CliHeight
DllCall("BitBlt", "UPtr", this.hDC, "Int", x, "Int", y
, "Int", w, "Int", h, "UPtr", this.hMemDC, "Int", 0, "Int", 0, "UInt", 0xCC0020) ;SRCCOPY
}
UpdateLayeredWindow(x=0, y=0, w=0, h=0, color=0, Alpha=255) {
w := w ? w : this.CliWidth
h := h ? h : this.CliHeight
DllCall("UpdateLayeredWindow", "Ptr", this.hWnd, "Ptr", 0
, "Int64*", x|y<<32, "Int64*", w|h<<32
, "Ptr", this.hMemDC, "Int64*", 0, "uint", color
, "UInt*", Alpha<<16|1<<24, "uint", 1)
}
DrawLine(x, y, x2, y2, Color, Width=1) {
Pen := new GDI.Pen(Color, Width)
DllCall("MoveToEx", "UPtr", this.hMemDC, "Int", this.TranslateX(x), "Int", this.TranslateY(y), "UPtr", 0)
hOriginalPen := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Pen.Handle, "UPtr")
DllCall("LineTo", "UPtr", this.hMemDC, "Int", this.TranslateX(x2), "Int", this.TranslateY(y2))
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalPen, "UPtr")
}
SetPixel(x, y, Color) {
x := this.TranslateX(x)
y := this.TranslateY(y, this.Invert) ; Move up 1 px if inverted (drawing "up" instead of down)
DllCall("SetPixelV", "UPtr", this.hMemDC, "Int", x, "Int", y, "UInt", Color)
}
FillRectangle(x, y, w, h, Color, BorderColor=-1) {
if (w == 1 && h == 1)
return this.SetPixel(x, y, Color)
Pen := new this.Pen(BorderColor < 0 ? Color : BorderColor)
Brush := new this.Brush(Color)
; Replace the original pen and brush with our own
hOriginalPen := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Pen.Handle, "UPtr")
hOriginalBrush := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Brush.Handle, "UPtr")
x1 := this.TranslateX(x)
y1 := this.TranslateY(y)
x2 := this.TranslateX(x+w)
y2 := this.TranslateY(y+h)
DllCall("Rectangle", "UPtr", this.hMemDC
, "Int", x1, "Int", y1
, "Int", x2, "Int", y2)
; Reselect the original pen and brush
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalPen, "UPtr")
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalBrush, "UPtr")
}
FillEllipse(x, y, w, h, Color, BorderColor=-1) {
Pen := new this.Pen(BorderColor < 0 ? Color : BorderColor)
Brush := new this.Brush(Color)
; Replace the original pen and brush with our own
hOriginalPen := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Pen.Handle, "UPtr")
hOriginalBrush := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Brush.Handle, "UPtr")
x1 := this.TranslateX(x)
y1 := this.TranslateY(y)
x2 := this.TranslateX(x+w)
y2 := this.TranslateY(y+h)
DllCall("Ellipse", "UPtr", this.hMemDC
, "Int", x1, "Int", y1
, "Int", x2, "Int", y2)
; Reselect the original pen and brush
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalPen, "UPtr")
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalBrush, "UPtr")
}
TranslateX(X) {
return Floor(X)
}
TranslateY(Y, Offset=0) {
if this.Invert
return this.CliHeight - Floor(Y) - Offset
return Floor(Y)
}
class Pen {
__New(Color, Width=1, Style=0) {
this.Handle := DllCall("CreatePen", "Int", Style, "Int", Width, "UInt", Color, "UPtr")
}
__Delete() {
DllCall("DeleteObject", "UPtr", this.Handle)
}
}
class Brush {
__New(Color) {
this.Handle := DllCall("CreateSolidBrush", "UInt", Color, "UPtr")
}
__Delete() {
DllCall("DeleteObject", "UPtr", this.Handle)
}
}
}
; 简单可视化鼠标手势 v1.5 By FeiYue
#NoEnv
#SingleInstance, force
SetWinDelay -1
SetBatchLines, -1
CoordMode, Mouse
CoordMode, ToolTip
生成画板()
tip:= { 0 : 0
, "上" : "上翻页"
, "下" : "下翻页"
, "左" : "后退"
, "右" : "前进"
, "右下左" : "退出"
, 0 : 0 }
return
上:
下:
左:
右:
k:=A_ThisLabel
MsgBox, 4096,, % k " > " tip[k], 1
return
右下左:
ExitApp
Esc:: ExitApp
start_01() {
static init:=start_01()
SetTitleMatchMode, 2 ;//匹配部分标题
GroupAdd, MyBrowser, 360安全浏览器
GroupAdd, MyBrowser, 360极速浏览器
GroupAdd, MyBrowser, 搜狗高速浏览器
GroupAdd, MyBrowser, 世界之窗浏览器
GroupAdd, MyBrowser, 2345加速浏览器
GroupAdd, MyBrowser, GreenBrowser
GroupAdd, MyBrowser, Firefox
GroupAdd, MyBrowser, Chrome
GroupAdd, MyBrowser, ahk_class IEFrame
GroupAdd, MyBrowser, ahk_class 360se5_Frame
GroupAdd, MyBrowser, ahk_class 360se6_Frame
GroupAdd, MyBrowser, ahk_class Chrome_WidgetWin_1
GroupAdd, MyBrowser, ahk_class ShockwaveFlashFullScreen
}
#If !WinActive("ahk_group MyBrowser")
RButton::
显示画板(), 轨迹:=方向:=上次方向:="", arr:=[], p:=Tan(60*ATan(1)/45)
MouseGetPos, x1, y1
While GetKeyState("RButton", "P") {
Sleep, 10
MouseGetPos, x2, y2
Loop, % (i:=arr.MaxIndex())>10 ? 10 : i
if ((dx:=x2-arr[i].3)*0+(dy:=y2-arr[i--].4)*0+Abs(dx)>5 or Abs(dy)>5) {
方向:=(Abs(dy)>=Abs(dx)*p) ? (dy<0 ? "上":"下")
: (Abs(dx)>=Abs(dy)*p) ? (dx<0 ? "左":"右") : 方向
Break
}
if (方向!=上次方向)
轨迹.=方向, 上次方向:=方向
if (x1!=x2 or y1!=y2) {
arr.Push([x1,y1,x2,y2]), x1:=x2, y1:=y2
ToolTip, % 轨迹 " > " (tip[轨迹] ? tip[轨迹]:"没有设置动作")
}
color:=A_MSec<500 ? 0xFF9050 : 0x5090FF
For k,v in arr
划线(v.1, v.2, v.3, v.4, color)
更新()
}
ToolTip
清空(), 更新(), 隐藏画板()
if (轨迹="") {
Click, R
return
}
if IsLabel(轨迹)
Goto, %轨迹%
else
MsgBox, 4096,, % 轨迹 " > 没有设置动作", 1
return
#If
;========== 下面是函数 ==========
生成画板() {
global my_gdi
Gui, My_DrawingBoard: New
Gui, +LastFound +AlwaysOnTop -Caption +ToolWindow
+E0x80000 +OwnDialogs +Hwndmy_id +E0x20
; 下面两行结合Bitblt更新与UpdateLayeredWindow更新互斥
; Gui, Color, 0x000000
; WinSet, TransColor, 0x000000
w:=A_ScreenWidth, h:=A_ScreenHeight
Gui, Show, Hide x0 y0 w%w% h%h%, 画板
my_gdi := new GDI(my_id, w, h), 清空()
return
}
显示画板() {
Gui, My_DrawingBoard: Show, NA
}
隐藏画板() {
Gui, My_DrawingBoard: Hide
}
划线(x,y,x2,y2,color=0xFF0000) {
global my_gdi
my_gdi.DrawLine(x, y, x2, y2, Color, 4)
}
更新(color=0x000000) {
global my_gdi
; my_gdi.Bitblt()
my_gdi.UpdateLayeredWindow(0, 0, 0, 0, color)
}
清空(color=0x000000) {
global my_gdi
my_gdi.FillRectangle(0, 0, my_gdi.CliWidth, my_gdi.CliHeight, color)
}
class GDI { ; thanks dwitter, RUNIE
__New(hWnd, CliWidth=0, CliHeight=0) {
if !(CliWidth && CliHeight) {
VarSetCapacity(Rect, 16, 0)
DllCall("GetClientRect", "Ptr", hWnd, "Ptr", &Rect)
CliWidth := NumGet(Rect, 8, "Int")
CliHeight := NumGet(Rect, 12, "Int")
}
this.CliWidth := CliWidth
this.CliHeight := CliHeight
this.hWnd := hWnd
this.hDC := DllCall("GetDC", "UPtr", hWnd, "UPtr")
this.hMemDC := DllCall("CreateCompatibleDC", "UPtr", this.hDC, "UPtr")
this.hBitmap := DllCall("CreateCompatibleBitmap", "UPtr", this.hDC, "Int", CliWidth, "Int", CliHeight, "UPtr")
this.hOriginalBitmap := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", this.hBitmap)
}
__Delete() {
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", this.hOriginalBitmap)
DllCall("DeleteObject", "UPtr", this.hBitmap)
DllCall("DeleteObject", "UPtr", this.hMemDC)
DllCall("ReleaseDC", "UPtr", this.hWnd, "UPtr", this.hDC)
}
Resize(w, h) {
this.CliWidth := w
this.CliHeight := h
this.hBitmap := DllCall("CreateCompatibleBitmap", "UPtr", this.hDC, "Int", w, "Int", h, "UPtr")
hPrevBitmap := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", this.hBitmap)
DllCall("DeleteObject", "UPtr", hPrevBitmap)
}
BitBlt(x=0, y=0, w=0, h=0) {
w := w ? w : this.CliWidth
h := h ? h : this.CliHeight
DllCall("BitBlt", "UPtr", this.hDC, "Int", x, "Int", y
, "Int", w, "Int", h, "UPtr", this.hMemDC, "Int", 0, "Int", 0, "UInt", 0xCC0020) ;SRCCOPY
}
UpdateLayeredWindow(x=0, y=0, w=0, h=0, color=0, Alpha=255) {
w := w ? w : this.CliWidth
h := h ? h : this.CliHeight
DllCall("UpdateLayeredWindow", "Ptr", this.hWnd, "Ptr", 0
, "Int64*", x|y<<32, "Int64*", w|h<<32
, "Ptr", this.hMemDC, "Int64*", 0, "uint", color
, "UInt*", Alpha<<16|1<<24, "uint", 1)
}
DrawLine(x, y, x2, y2, Color, Width=1) {
Pen := new GDI.Pen(Color, Width)
DllCall("MoveToEx", "UPtr", this.hMemDC, "Int", this.TranslateX(x), "Int", this.TranslateY(y), "UPtr", 0)
hOriginalPen := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Pen.Handle, "UPtr")
DllCall("LineTo", "UPtr", this.hMemDC, "Int", this.TranslateX(x2), "Int", this.TranslateY(y2))
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalPen, "UPtr")
}
SetPixel(x, y, Color) {
x := this.TranslateX(x)
y := this.TranslateY(y, this.Invert) ; Move up 1 px if inverted (drawing "up" instead of down)
DllCall("SetPixelV", "UPtr", this.hMemDC, "Int", x, "Int", y, "UInt", Color)
}
FillRectangle(x, y, w, h, Color, BorderColor=-1) {
if (w == 1 && h == 1)
return this.SetPixel(x, y, Color)
Pen := new this.Pen(BorderColor < 0 ? Color : BorderColor)
Brush := new this.Brush(Color)
; Replace the original pen and brush with our own
hOriginalPen := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Pen.Handle, "UPtr")
hOriginalBrush := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Brush.Handle, "UPtr")
x1 := this.TranslateX(x)
y1 := this.TranslateY(y)
x2 := this.TranslateX(x+w)
y2 := this.TranslateY(y+h)
DllCall("Rectangle", "UPtr", this.hMemDC
, "Int", x1, "Int", y1
, "Int", x2, "Int", y2)
; Reselect the original pen and brush
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalPen, "UPtr")
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalBrush, "UPtr")
}
FillEllipse(x, y, w, h, Color, BorderColor=-1) {
Pen := new this.Pen(BorderColor < 0 ? Color : BorderColor)
Brush := new this.Brush(Color)
; Replace the original pen and brush with our own
hOriginalPen := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Pen.Handle, "UPtr")
hOriginalBrush := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Brush.Handle, "UPtr")
x1 := this.TranslateX(x)
y1 := this.TranslateY(y)
x2 := this.TranslateX(x+w)
y2 := this.TranslateY(y+h)
DllCall("Ellipse", "UPtr", this.hMemDC
, "Int", x1, "Int", y1
, "Int", x2, "Int", y2)
; Reselect the original pen and brush
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalPen, "UPtr")
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalBrush, "UPtr")
}
TranslateX(X) {
return Floor(X)
}
TranslateY(Y, Offset=0) {
if this.Invert
return this.CliHeight - Floor(Y) - Offset
return Floor(Y)
}
class Pen {
__New(Color, Width=1, Style=0) {
this.Handle := DllCall("CreatePen", "Int", Style, "Int", Width, "UInt", Color, "UPtr")
}
__Delete() {
DllCall("DeleteObject", "UPtr", this.Handle)
}
}
class Brush {
__New(Color) {
this.Handle := DllCall("CreateSolidBrush", "UInt", Color, "UPtr")
}
__Delete() {
DllCall("DeleteObject", "UPtr", this.Handle)
}
}
}
声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。
评论(0)