介绍
此脚本源自远古的ahk1,里面甚至使用了IfLess这种语法。
但不管怎么说,它是个十分好的脚本,代码精简,效率也好。所以我将它升级到了ahk2版,并对部分内容做提炼,疏通了整个脚本的脉络(老语法实在混乱)。
它的作用就是可以放大鼠标下的屏幕,以gui的形式展示出来。效果如下:
此外,还有以下特点:
- 支持gui尺寸拖拽
- 支持暂停
- 支持缩放
- 支持抗锯齿(仅缩小时有用)
- 支持更多扩展
- 放大十分清晰
- 几乎无延迟
脚本
ahk2
热键
; #x 退出脚本
; #p 或 MButton 暂停画面(非暂停脚本)
; ^+WhellDown\WhellUp 缩放
; #a 抗锯齿
代码
依旧是将所有可配置项放在开头的config类内,其余功能可自行扩展。
#Requires AutoHotkey v2.0
#SingleInstance Force
CoordMode 'Mouse', 'Screen'
class Config {
static initialZoom := 2 ; initial magnification, 1..32
static guiOption := '+AlwaysOnTop +Resize'
static guiPosX := 60
static guiPosY := 0
static guiSize := 3
}
zoom := Config.initialZoom
Rx := 128 ; half vertical/horizontal side of magnifier window
Ry := 128
Zx := Rx / zoom ; frame x/y size
Zy := Ry / zoom
OnUpdate(GuiObj, MinMax, w, h) {
global
Rx := w / 2
Ry := h / 2
Zx := Rx / zoom
Zy := Ry / zoom
}
#x::
OnClose(*) {
DllCall("gdi32.dll\DeleteDC", 'UInt', hdc_frame)
DllCall("gdi32.dll\DeleteDC", 'UInt', hdd_frame)
ExitApp()
}
g := Gui(Config.guiOption)
g.OnEvent('Size', OnUpdate)
g.OnEvent('Close', OnClose)
g.Show('w' Config.guiSize * Rx ' h' Config.guiSize * Ry 'x' Config.guiPosX ' y' Config.guiPosY)
MagnifierID := g.Hwnd
PrintSourceID := 0
hdd_frame := DllCall("GetDC", 'UInt', PrintSourceID)
hdc_frame := DllCall("GetDC", 'UInt', MagnifierID)
SetTimer Repaint, 5
GetClosest := (x, a, b) => x < a ? a : (b < x ? b : x)
Repaint() {
global
MouseGetPos(&x, &y)
xz := GetClosest(x - Zx - 6, 0, A_ScreenWidth - 2 * Zx) ; keep the frame on screen
yz := GetClosest(y - Zy - 6, 0, A_ScreenHeight - 2 * Zy)
DllCall("gdi32.dll\StretchBlt", 'UInt', hdc_frame, 'Int'
, 0, 'Int', 0, 'Int', 2 * Rx, 'Int', 2 * Ry
, 'UInt', hdd_frame, 'UInt', xz, 'UInt', yz
, 'Int', 2 * Zx, 'Int', 2 * Zy, 'UInt', 0xCC0020) ; SRCCOPY
}
#a::
{
static antialize := 0
DllCall("gdi32.dll\SetStretchBltMode", "uint", hdc_frame, "int", 4 * antialize) ; Antializing ?
antialize := !antialize
}
#p::
MButton::
{
static paused := true
paused
? SetTimer(Repaint, 0)
: SetTimer(Repaint, 5)
paused := !paused
}
^+WheelUp::
^+WheelDown::
{
global
if zoom < 31 and (A_ThisHotKey = "^+WheelUp")
zoom *= 1.189207115 ; sqrt(sqrt(2))
if zoom > 1 and (A_ThisHotKey = "^+WheelDown")
zoom /= 1.189207115
Zx := Rx / zoom
Zy := Ry / zoom
}
源
#NoEnv
SetBatchLines -1
CoordMode Mouse, Screen
OnExit GuiClose
zoom = 2 ; initial magnification, 1..32
antialize = 0
Rx = 128 ; half vertical/horizontal side of magnifier window
Ry = 128
Zx := Rx/zoom ; frame x/y size
Zy := Ry/zoom
; GUI to show the magnified image
Gui +AlwaysOnTop +Resize
Gui Show, % "w" 4*Rx " h" 4*Ry " x0 y0", Magnifier
WinGet MagnifierID, id, Magnifier
WinSet Transparent, 255, Magnifier ; makes the window invisible to magnification
WinGet PrintSourceID, ID
hdd_frame := DllCall("GetDC", UInt, PrintSourceID)
hdc_frame := DllCall("GetDC", UInt, MagnifierID)
MsgBox , \%PrintSourceID%\%MagnifierID%
SetTimer Repaint, 50 ; flow through
Repaint:
MouseGetPos x, y
xz := In(x-Zx-6,0,A_ScreenWidth-2*Zx) ; keep the frame on screen
yz := In(y-Zy-6,0,A_ScreenHeight-2*Zy)
; WinMove Frame,,%xz%, %yz%, % 2*Zx, % 2*Zy
DllCall("gdi32.dll\StretchBlt", UInt,hdc_frame, Int,0, Int,0, Int,2*Rx, Int,2*Ry
, UInt,hdd_frame, UInt,xz, UInt,yz, Int,2*Zx, Int,2*Zy, UInt,0xCC0020) ; SRCCOPY
Return
GuiSize:
Rx := A_GuiWidth/2
Ry := A_GuiHeight/2
Zx := Rx/zoom
Zy := Ry/zoom
; TrayTip,,% "Frame = " Round(2*Zx) " × " Round(2*Zy) "`nMagnified to = " A_GuiWidth "×" A_GuiHeight
Return
#a::
antialize := !antialize
DllCall( "gdi32.dll\SetStretchBltMode", "uint", hdc_frame, "int", 4*antialize ) ; Antializing ?
Return
#x::
GuiClose:
DllCall("gdi32.dll\DeleteDC", UInt,hdc_frame )
DllCall("gdi32.dll\DeleteDC", UInt,hdd_frame )
ExitApp
#p::
MButton::
if paused =
{
Gui, 2:Hide
Gui, Hide
SetTimer, Repaint, Off
paused = 1
}
else
{
Gui, 2:Show
Gui, Show
SetTimer, Repaint, 50
paused =
}
Return
^+Up::
^+Down::
^+WheelUp:: ; Ctrl+Shift+WheelUp to zoom in
^+WheelDown:: ; Ctrl+Shift+WheelUp to zoom out
If (zoom < 31 and ( A_ThisHotKey = "^+WheelUp" or A_ThisHotKey = "^+Up" ))
zoom *= 1.189207115 ; sqrt(sqrt(2))
If (zoom > 1 and ( A_ThisHotKey = "^+WheelDown" or A_ThisHotKey = "^+Down" ))
zoom /= 1.189207115
Zx := Rx/zoom
Zy := Ry/zoom
; TrayTip,,% "Zoom = " Round(100*zoom) "%"
Return
In(x,a,b) { ; closest number to x in [a,b]
IfLess x,%a%, Return a
IfLess b,%x%, Return b
Return x
}
标签:AHK2,frame,Rx,zoom,Ry,放大镜,UInt,Zx,屏幕
From: https://www.cnblogs.com/refiz/p/17652461.html