首页 > 其他分享 >[AHK2] 屏幕放大镜

[AHK2] 屏幕放大镜

时间:2023-08-23 18:22:18浏览次数:38  
标签:AHK2 frame Rx zoom Ry 放大镜 UInt Zx 屏幕

介绍

此脚本源自远古的ahk1,里面甚至使用了IfLess这种语法。
但不管怎么说,它是个十分好的脚本,代码精简,效率也好。所以我将它升级到了ahk2版,并对部分内容做提炼,疏通了整个脚本的脉络(老语法实在混乱)。

它的作用就是可以放大鼠标下的屏幕,以gui的形式展示出来。效果如下:

image

此外,还有以下特点:

  • 支持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

相关文章

  • 采购订单屏幕增强
    1、业务需求采购订单行项目新增“图号”和“价格类型”字段。其中图号只查询底表展示,不做修改;价格类型做下拉框;2、增强实现增强标准表EKPO结构CI_EKPODB。抬头增加字段则修改EKKO结构CI_EKKODB增强点CMOD:MM06E005出口EXIT_SAPMM06E_016首先在TOP文件中引入全局CI_EKPODB......
  • [AHK2] 让终止符决定热字串
    介绍这是一种在使用同一热字串的情况下生成不同结果的技巧。例子下面是一个例子,用于生成三种样式的CommonJs导入语句。它在我写nodeJs时可以省下些许麻烦。根据终止符的不同,会生成三种导入语句:空格->使用默认名app,导入模块自行输入。分号->变量名和模块名相同,输入......
  • [AHK2] 更改脚本初始代码
    ahk初始提供的模版代码将在创建ahk2脚本时自动添加,如果需要更改的话,只要修改ahk安装目录/UX/Templates/Minimalforv2.ahk文件内容即可。它的初始内容只有#RequiresAutoHotkeyv2.0。我添加了些许片段:ifA_LineFile==A_ScriptFullPath{}在花括号内的代码只在以当前文......
  • [AHK2-UI] 实现自己的Show()方法
    为什么这其实是一种两阶段XX的设计模式,比如两阶段终止:调用终止方法时并不立即终止,而是设置终止信号,由别人自身决定终止的操作。同样,实现Show()方法算是一种两阶段启动:外部调用Show()方法时,由自身决定show前做什么,show后又做什么,以及如何show。例子这是一个Show()方法:staticS......
  • uniapp专栏——屏幕安全区域
    写在前面这些内容是在通过cli搭建的uniapp中,使用了vite4,ts4.9,vue3(组合式API,setup语法糖)。如果有版本不一致,请谨慎参考。正文css方式UNI提供的安全区CSS常量获取上安全距离(安全区域距离顶部边界的距离):env(safe-area-inset-top)获取左安全距离(安全区域距离左边边界的......
  • [AHK2-UI] 使用#Include
    #Include是什么一句话介绍:可以将一个脚本的代码插入到Include语句的位置。作用使用#Include可以实现分模块开发,对于代码组织有十分重要的作用。通常使用小型脚本(只有些热键和热字串)不需要使用;但当脚本不仅仅是这些,还要写ui界面或更繁杂的功能时,我们最好将ui和数据处理的逻辑分......
  • 大屏项目Echarts不同屏幕之间适配
    1.解决方案:使用缩放,前提:需要严格按照设计图提供的像素大小,尽可能少使用百分比以及尽可能少使用rem插件(会导致rem和缩放同时生效反而比例不对),如发现细节不对,需对该处细节精确去按照比例去调整大小,并配合echarts方法解决2.解决方法:2.1给最外层盒子设置缩放样式:.large-scre......
  • 请解释电竞游戏CS中的闪光弹为什么会让电脑屏幕出现闪光的效果,具体是怎样的原理请推测
    在电竞游戏《反恐精英》(Counter-Strike,简称CS)中,闪光弹是一种战术道具,用于干扰敌人的视觉。它会造成电脑屏幕出现闪光效果的原因是因为游戏引擎采用了特定的视觉效果技术来模拟真实世界中的闪光效果,让玩家在游戏中感受到更真实的环境。以下是可能用于模拟闪光效果的原理和推测:......
  • [AHK2-UI] 新系列~
    介绍这个系列中,我将分享我使用ahk2UI的经验,帮助更多小伙伴写出理想的UI界面。首先来看看一个精心设计的ui工具的截图,看看与你印象中的ahkUI有什么不同吧XD.效果图ui工具一SpMemo主界面某子界面退出界面夜间主题XD是不是像个小应用呢?它的作用其实是可以方......
  • [AHK2] 切换鼠标锁定
    介绍这个脚本在看视频时很有用,通过热键可以切换鼠标的锁定,从此不用担心误碰鼠标导致弹出进度条了。脚本使用的热键是ScrollLock的扫描码,一般情况下不会用到,但我很喜欢这个热键。可以根据自身喜好进行更改。注意:这里依旧使用了先前分享的更常用的ToolTip,作用是显示提示,并......