侧边栏壁纸
博主头像
谷爱雨 博主等级

独立人格

  • 累计撰写 19 篇文章
  • 累计创建 34 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

autohotkey V2函数自定义增强版

谷爱雨
2025-04-07 / 0 评论 / 0 点赞 / 10 阅读 / 0 字
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。
; 自定义的函数写在这个文件里,  然后能在 MyKeymap 中调用
; 使用如下写法,来加载当前目录下的其他 AutoHotKey v2 脚本
; #Include ../data/test.ahk

; #Requires AutoHotkey v2.0
; 定义全局变量用于控制提示窗口
global MyGui
global currentHandlerIndex := 1  ; 新增全局变量用于记录当前模式
global currentT := 1  ; 新增全局变量控制切换范围

;切换范围
ToggleTRange() {
    global currentT, currentHandlerIndex
    static rangeOptions := [1, 2, 3, 4]
    static currentIndex := 1
    
    ; 循环切换选项
    currentIndex := Mod(currentIndex, rangeOptions.Length) + 1
    currentT := rangeOptions[currentIndex]
    
    ; 生成模式描述
    modeDesc := ""
    switch currentT {
        case 1: modeDesc := "aa"
        case 2: modeDesc := "aa,中文"
        case 3: modeDesc := "中文"
        case 4: modeDesc := "aa,中文,AA"
    }
    
    currentHandlerIndex := 1
    ShowToolTip(modeDesc)  ; 使用换行显示更清晰
}



ShowToolTip(message, x?, y?) {  ; 使用可选参数语法
    try {
        ; 设置坐标系为屏幕坐标
        CoordMode "Caret", "Screen"
        
        ; v2 正确获取方式
        CaretGetPos(&caretX, &caretY)  ; 通过引用传递参数
        
        x := caretX
        y := caretY+50
        
    } catch as e {
        x := A_ScreenWidth // 2
        y := 0
    }

    ; GUI 创建部分保持不变
    myGui := Gui("+AlwaysOnTop -Caption +ToolWindow +E0x20")
    myGui.BackColor := "FF7F53"
    WinSetTransparent(255, myGui.Hwnd)
    myGui.SetFont("s12", "微软雅黑")
    myGui.MarginX := 5  ; 左右边距
    myGui.MarginY := 5   ; 上下边距
    myGui.Add("Text", "h25 Center", message)  ; 固定高并居中
    myGui.Show("x" x " y" y " NoActivate")
    
    SetTimer(() => myGui.Destroy(), 500)
}


; 循环切换函数小写,中文,大写,之间切换;4种模式切换
; 修改后的循环切换函数
CycleHandlers() {
    global currentHandlerIndex, currentT
    
    ; 根据currentT值建立对应的模式数组
    static handlerGroups := Map(
        1, [LShiftHandler],                   ; aa模式
        2, [LShiftHandler, RShiftHandler],     ; aa+中文模式
        3, [RShiftHandler],                    ; 中文模式
        4, [LShiftHandler, RShiftHandler, CapsLockHandler] ; 全模式
    )
    
    ; 获取当前模式组的处理函数数组
    handlers := handlerGroups.Has(currentT) ? handlerGroups[currentT] : [LShiftHandler]
    
    ; 执行当前索引对应的处理函数
    try handlers[currentHandlerIndex].Call()
    
    ; 循环索引(1-based)
    currentHandlerIndex := Mod(currentHandlerIndex, handlers.Length) + 1
}


; 右Shift键处理函数
RShiftHandler() {
    ; 长按逻辑
    static longPressThreshold := 130  ;
    keyDownTime := A_TickCount

    ; 保持原有~LShift热键特性
    KeyWait "RShift"
    duration := A_TickCount - keyDownTime

    ; 长按逻辑(保持当前输入法)
    if (duration >= longPressThreshold) {
        if isEnglishMode() {
            ; ShowToolTip("aa(长按耗时:" duration "ms)")
        } else {
            ; ShowToolTip("中(长按耗时:" duration "ms)")
        }
        return
    }
    ; 短按逻辑
    if GetKeyState("CapsLock", "T") {
        SetCapsLockState 0
    }
    if isEnglishMode() {   ; 当前为英文时切换
        Send "^{Space}"
    }
    ShowToolTip("中")
    ; ShowToolTip("中(短按耗时:" duration "ms)")  ; 新增时间显示
}

; 左Shift键处理函数
; 英文 → 长按LShift,保持英文,不执行后续操作
; 中文→ 长按LShift,保持中文,不执行后续操作
; 中文 → 短按LShift,切英文
; 英文 → 短按LShift,英文
LShiftHandler() {
    ; 长按逻辑
    static longPressThreshold := 130  ;
    keyDownTime := A_TickCount

    ; 保持原有~LShift热键特性
    KeyWait "LShift"
    duration := A_TickCount - keyDownTime

    ; 长按逻辑(保持当前输入法)
    if (duration >= longPressThreshold) {
        if isEnglishMode() {
            ; ShowToolTip("aa(长按耗时:" duration "ms)")
        } else {
            ; ShowToolTip("中(长按耗时:" duration "ms)")

        }
        return
    }
    ; 短按逻辑
    if GetKeyState("CapsLock", "T") {
        SetCapsLockState 0
        if !isEnglishMode() {
            Send "^{Space}"
        }
    } else {
        if !isEnglishMode() {
            Send "^{Space}"
        }
    }
    ShowToolTip("aa")
    ; ShowToolTip("aa(短按耗时:" duration "ms)")  ; 新增时间显示
}

; CapsLock键处理函数
CapsLockHandler() {
    if GetKeyState("CapsLock", "T") {
        SetCapsLockState 0
        if !isEnglishMode() {  ; 关闭CapsLock时强制切英文
            Send "^{Space}"
            ShowToolTip("aa")
        }
    } else {
        SetCapsLockState 1
        ShowToolTip("AA")
    }
}


isEnglishMode() {
    static IMC_GETCONVERSIONMODE := 0x001
    static WM_IME_CONTROL := 0x0283

    try {
        ; 启用隐藏窗口检测
        originalState := A_DetectHiddenWindows
        DetectHiddenWindows true

        ; 获取活动窗口句柄
        if !(hWnd := WinExist("A")) {
            throw Error("窗口句柄获取失败", -1)
        }

        ; 获取输入法窗口句柄
        if !(imeWnd := DllCall("imm32\ImmGetDefaultIMEWnd", "Uint", hWnd, "Uint")) {
            throw Error("输入法窗口未找到", -2)
        }

        ; 发送控制消息
        result := SendMessage(
            WM_IME_CONTROL,
            IMC_GETCONVERSIONMODE,
            0,
            ,
            "ahk_id " imeWnd
        )

        return result == 0  ; 0=英文模式
    }
    catch as e {
        ; 显示错误提示(调试用)
        ToolTip "输入法检测错误: " e.Message
        SetTimer () => ToolTip(), -1000
        
        ; 安全返回值
        return true  ; 默认英文模式
    }
    finally {
        ; 恢复窗口检测状态
        DetectHiddenWindows originalState
    }
}


;-------------------------切换虚拟桌面-------------------------------------------------------------------
; 切换虚拟桌面的独立函数
SwitchVirtualDesktop() {
    static pressed := false           ; 静态变量保存切换状态
    pressed := !pressed               ; 每次调用翻转状态
    
    ; 根据状态发送不同的组合键
    if pressed {
        Send("^#{Right}")             ; 切换到右侧虚拟桌面
    } else {
        Send("^#{Left}")              ; 切换到左侧虚拟桌面
    }
    
}



; #Tab:: {  ; Win+Tab 热键切换两个窗口
;     static pressed := false          ; 静态变量保存状态
;     pressed := !pressed             ; 切换状态
;     if (pressed) {
;         Send("^#{Right}")           ; 切换到右侧虚拟桌面
;     } else {
;         Send("^#{Left}")            ; 切换到左侧虚拟桌面
;     }
; }


;--------------------所有窗口最大化和最小化(全局设置DetectHiddenWindows True的时候有冲突)------------------------------------------------------

; 切换最小化和还原所有窗口(排除 Rainmeter)
ToggleMinimizeAll() {
    static isMinimized := false
    if (isMinimized) {
        RestoreAllWindows()
        isMinimized := false
    } else {
        MinimizeAllWindows()
        isMinimized := true
    }
}

; 最小化所有窗口(排除 Rainmeter)
MinimizeAllWindows() {
  windows := WinGetList()
  for id in windows {
    try {  ; 防止无效窗口导致崩溃
      processName := WinGetProcessName(id)
      if (processName != "Rainmeter.exe") {
        WinMinimize(id)
      }
    }
  }
}

; 还原所有最小化窗口(排除 Rainmeter)
RestoreAllWindows() {
  windows := WinGetList()
  for id in windows {
    try {
      ; 先检查窗口是否存在,避免无效句柄
      if !WinExist("ahk_id " id)
        continue
      
      ; 排除 Rainmeter 进程
      processName := WinGetProcessName(id)
      if (processName == "Rainmeter.exe")
        continue
      
      ; 获取窗口状态(关键修正点)
      minMaxState := WinGetMinMax(id)
      
      ; AHK 中最小化状态值为 -1,最大化是 1,正常是 0
      if (minMaxState == -1) {
        WinRestore(id)
        ; 可选:激活窗口确保还原(部分系统需要)
        ; WinActivate(id)
      }
    } catch Error {
      ; 捕获异常(例如权限问题)
      continue
    }
  }
}



;--------------------窗口调整循环切换位置------------------------------------------------------
; ;函数切换windowtop,windowbottom,windowleft,windowright
; ; 窗口位置配置中心(默认参数)
global WindowPositions := {
    top:    { width: 2560, height: 460 },
    bottom: { width: 2560, height: 460 },
    left:   { width: 870, height: 1440 },
    right:  { width: 870, height: 1440 }
}

ToggleWindowPosition(params := "") {
    static state := 0
    state := Mod(state, 5) + 1
    
    ; 合并全局配置与自定义参数
    config := MergeConfig(WindowPositions.Clone(), params)
    
    switch state {
        case 1:
            windowtop(config.top.width, config.top.height)
        case 2:
            windowbottom(config.bottom.width, config.bottom.height)
        case 3:
            windowleft(config.left.width, config.left.height)
        case 4:
            windowright(config.right.width, config.right.height)
        case 5:
            MaximizeWindows()
    }
}

; 配置合并函数
MergeConfig(base, extend) {
    if !IsObject(extend)
        return base
    for k, v in extend {
        if IsObject(v) && base.HasKey(k)
            base[k] := MergeConfig(base[k], v)
        else
            base[k] := v
    }
    return base
}



; 调整窗口大小并定位到屏幕顶部(任务栏下方)且水平居中
windowtop(width, height) {
  if NotActiveWin() {
    return
  }

  DllCall("SetThreadDpiAwarenessContext", "ptr", -1, "ptr")

  WinExist("A")
  if (WindowMaxOrMin())
    WinRestore

  WinGetPos(&x, &y, &w, &h)

  ms := GetMonitorAt(x + w / 2, y + h / 2)
  MonitorGetWorkArea(ms, &l, &t, &r, &b)
  w := r - l   ; 工作区宽度
  h := b - t   ; 工作区高度

  ; 计算窗口尺寸(不超过工作区)
  winW := Min(width, w+20)
  winH := Min(height, h)
  
  ; 水平居中,顶部对齐
  winX := l + (w - winW) / 2
  winY := t  ; 关键修改:从工作区顶部开始定位

  WinMove(winX, winY, winW, winH)
  DllCall("SetThreadDpiAwarenessContext", "ptr", -3, "ptr")
  ; SetWindowTopMost()
}

; 将当前窗口调整至显示器底部并水平居中显示
windowbottom(width, height) {
    ; 检查当前是否有活动窗口,没有则直接返回
    if NotActiveWin() {
        return
    }

    ; 设置DPI感知模式为UNAWARE(-1),让系统自动处理缩放
    ; 当执行窗口移动操作时,即使指定固定像素尺寸,系统会自动适配显示器缩放比例
    DllCall("SetThreadDpiAwarenessContext", "ptr", -1, "ptr")

    ; 确保操作对象是当前活动窗口
    WinExist("A")
    
    ; 如果窗口处于最大化/最小化状态,先恢复窗口
    if (WindowMaxOrMin())
        WinRestore

    ; 获取窗口当前位置和尺寸(&表示输出变量)
    WinGetPos(&x, &y, &w, &h)

    ; 根据窗口中心点坐标获取所在显示器序号
    ms := GetMonitorAt(x + w / 2, y + h / 2)
    ; 获取该显示器的工作区域坐标(排除任务栏等区域)
    MonitorGetWorkArea(ms, &l, &t, &r, &b)
    w := r - l ; 计算工作区实际可用宽度
    h := b - t ; 计算工作区实际可用高度

    ; 计算最终窗口尺寸(不超过显示器工作区大小)
    winW := Min(width, w+20)    ; 取期望宽度与最大可用宽度的较小值
    winH := Min(height, h)   ; 取期望高度与最大可用高度的较小值
    
    ; 计算窗口位置(水平居中 + 底部对齐)
    winX := l + (w - winW) / 2  ; 水平居中:左边界 + (可用宽度-窗口宽度)/2
    winY := b - winH            ; 垂直底部:工作区下边界 - 窗口高度

    ; 移动窗口到计算位置(使用新的尺寸)
    WinMove(winX, winY, winW, winH)
    
    ; 还原DPI感知模式为PER_MONITOR_AWARE(-3),确保鼠标移动等操作精准
    DllCall("SetThreadDpiAwarenessContext", "ptr", -3, "ptr")
    
    ; 设置窗口置顶状态(根据之前的配置)
    ; SetWindowTopMost()
}

; 调整窗口大小并定位到屏幕左侧(垂直居中)
windowleft(width, height) {
  if NotActiveWin() {
    return
  }

  DllCall("SetThreadDpiAwarenessContext", "ptr", -1, "ptr")

  WinExist("A")
  if (WindowMaxOrMin())
    WinRestore

  WinGetPos(&x, &y, &w, &h)

  ms := GetMonitorAt(x + w / 2, y + h / 2)
  MonitorGetWorkArea(ms, &l, &t, &r, &b)
  w := r - l   ; 工作区宽度
  h := b - t   ; 工作区高度

  ; 计算窗口尺寸(不超过工作区)
  winW := Min(width, w)
  winH := Min(height, h)
  
  ; 左侧对齐,垂直居中
  winX := l-10               ; 关键修改:从工作区左侧开始
  winY := t + (h - winH) / 2  ; 垂直居中计算

  WinMove(winX, winY, winW, winH)
  DllCall("SetThreadDpiAwarenessContext", "ptr", -3, "ptr")
  ; SetWindowTopMost()
}

; 调整窗口大小并定位到屏幕右侧(垂直居中)

windowright(width, height) {
  if NotActiveWin() {
    return
  }

  DllCall("SetThreadDpiAwarenessContext", "ptr", -1, "ptr")

  WinExist("A")
  if (WindowMaxOrMin())
    WinRestore

  WinGetPos(&x, &y, &w, &h)

  ms := GetMonitorAt(x + w / 2, y + h / 2)
  MonitorGetWorkArea(ms, &l, &t, &r, &b)
  w := r - l   ; 工作区宽度
  h := b - t   ; 工作区高度

  ; 计算窗口尺寸(不超过工作区)
  winW := Min(width, w)
  winH := Min(height, h)
  
  ; 右侧对齐,垂直居中
  winX := r - winW +10          ; 关键修改:从工作区右侧向左计算
  winY := t + (h - winH) / 2  ; 垂直居中计算

  WinMove(winX, winY, winW, winH)
  DllCall("SetThreadDpiAwarenessContext", "ptr", -3, "ptr")
  ; SetWindowTopMost()
}

; 窗口最大化
MaximizeWindows() {
  if NotActiveWin() {
    return
  }

  if WindowMaxOrMin() {
    WinRestore("A")
    ; SetWindowTopMost()
  } else {
    WinMaximize("A")
    ; UnsetWindowTopMost()
  }
}

; 置顶窗口函数 
SetWindowTopMost() {
    WinSetAlwaysOnTop(true, "A")
    if (WinGetExStyle("A") & 0x8) {  ; 状态校验 
        Tip(Translation().always_on_top_on)
        ; 可扩展功能点:记录置顶日志/触发声音反馈 
    }
}
 
; 取消置顶函数 
UnsetWindowTopMost() {
    WinSetAlwaysOnTop(false, "A")
    if !(WinGetExStyle("A") & 0x8) {  ; 状态校验 
        Tip(Translation().always_on_top_off)
        ; 可扩展功能点:窗口位置复位/透明度重置 
    }
}




;--------------------配合automa,用于自动发送google邮箱,找到图片位置,在图片位置向上一点单击,然后粘贴内容------------------------------------------------------

; 设置图像文件的路径(确保使用相对路径或绝对路径)
imagePath := "D:\Program Files\MyKeymap-2.0-beta33\data\ee.bmp" ; 替换为你的图像文件路径

; 设置图像搜索的模式
CoordMode("Mouse", "Screen")
CoordMode("Pixel", "Screen")

; 定义检查间隔时间(毫秒)
checkInterval := 1000 ; 每1秒检查一次

; 定义全局变量用于保存图像位置
global Fx := 0
global Fy := 0
global imageFound := false ; 用于标记是否已经找到图像
global timerRunning := false ; 用于标记定时器是否在运行

CheckImage() {
    global Fx, Fy, imagePath, imageFound
    ; 查找目标窗口
    if WinExist("ahk_exe chrome.exe") {
        ; 在整个屏幕范围内搜索图像
        found := ImageSearch(&Fx, &Fy, 0, 0, A_ScreenWidth, A_ScreenHeight, imagePath)
        ; 检查图像是否找到
        if found {
            ; 如果图像之前没有被找到,则执行操作
            if !imageFound {
                ; 点击图像左上角位置向上偏移28像素
                Sleep 500
                Click Fx, Fy-28
                Send("^v")
                Sleep 500 ; 等待0.5秒,以确保粘贴完成
                ; 移动鼠标到屏幕中间
                MouseMove A_ScreenWidth // 2, A_ScreenHeight // 2
                imageFound := true ; 更新标志,表示图像已找到并处理
                ShowToolTip("图像已找到并处理")
            }
        } else {
            imageFound := false ; 如果没有找到图像,重置标志
            ShowToolTip("未找到图像")
        }
    } else {
        ShowToolTip("Chrome未运行")
    }
}



; 定义热键以手动控制定时器
;`::ToggleTimer() ; 切换定时器状态
;+`::StopTimer()

; 切换定时器状态函数
ToggleTimer() {
    global timerRunning
    if (timerRunning) {
        SetTimer(CheckImage, -1) ; 暂停检测
        timerRunning := false
        ShowToolTip("定时器已暂停")
    } else {
        if WinExist("ahk_exe chrome.exe") {
            SetTimer(CheckImage, checkInterval) ; 启动检测
            timerRunning := true
            ShowToolTip("定时器已启动,每 " checkInterval " 毫秒检查一次图像")
        } else {
            ShowToolTip("Chrome未运行,无法启动定时器")
        }
    }
}

; 停止定时器函数
StopTimer() {
    SetTimer(CheckImage, 0) ; 停止检测
    timerRunning := false
    ShowToolTip("定时器已停止")
}

; 自定义的函数写在这个文件里, 然后能在 MyKeymap 中调用

; 使用如下写法,来加载当前目录下的其他 AutoHotKey v2 脚本

; #Include ../data/test.ahk

; #Requires AutoHotkey v2.0

; 定义全局变量用于控制提示窗口

global MyGui

global currentHandlerIndex := 1 ; 新增全局变量用于记录当前模式

global currentT := 1 ; 新增全局变量控制切换范围

;切换范围

ToggleTRange() {

global currentT, currentHandlerIndex

static rangeOptions := [1, 2, 3, 4]

static currentIndex := 1

; 循环切换选项

currentIndex := Mod(currentIndex, rangeOptions.Length) + 1

currentT := rangeOptions[currentIndex]

; 生成模式描述

modeDesc := ""

switch currentT {

case 1: modeDesc := "aa"

case 2: modeDesc := "aa,中文"

case 3: modeDesc := "中文"

case 4: modeDesc := "aa,中文,AA"

}

currentHandlerIndex := 1

ShowToolTip(modeDesc) ; 使用换行显示更清晰

}

ShowToolTip(message, x?, y?) { ; 使用可选参数语法

try {

; 设置坐标系为屏幕坐标

CoordMode "Caret", "Screen"

; v2 正确获取方式

CaretGetPos(&caretX, &caretY) ; 通过引用传递参数

x := caretX

y := caretY+50

} catch as e {

x := A_ScreenWidth // 2

y := 0

}

; GUI 创建部分保持不变

myGui := Gui("+AlwaysOnTop -Caption +ToolWindow +E0x20")

myGui.BackColor := "FF7F53"

WinSetTransparent(255, myGui.Hwnd)

myGui.SetFont("s12", "微软雅黑")

myGui.MarginX := 5 ; 左右边距

myGui.MarginY := 5 ; 上下边距

myGui.Add("Text", "h25 Center", message) ; 固定高并居中

myGui.Show("x" x " y" y " NoActivate")

SetTimer(() => myGui.Destroy(), 500)

}

; 循环切换函数小写,中文,大写,之间切换;如果需要改为

; 修改后的循环切换函数

CycleHandlers() {

global currentHandlerIndex, currentT

; 根据currentT值建立对应的模式数组

static handlerGroups := Map(

1, [LShiftHandler], ; aa模式

2, [LShiftHandler, RShiftHandler], ; aa+中文模式

3, [RShiftHandler], ; 中文模式

4, [LShiftHandler, RShiftHandler, CapsLockHandler] ; 全模式

)

; 获取当前模式组的处理函数数组

handlers := handlerGroups.Has(currentT) ? handlerGroups[currentT] : [LShiftHandler]

; 执行当前索引对应的处理函数

try handlers[currentHandlerIndex].Call()

; 循环索引(1-based)

currentHandlerIndex := Mod(currentHandlerIndex, handlers.Length) + 1

}

; 右Shift键处理函数

RShiftHandler() {

; 长按逻辑

static longPressThreshold := 130 ;

keyDownTime := A_TickCount

; 保持原有~LShift热键特性

KeyWait "RShift"

duration := A_TickCount - keyDownTime

; 长按逻辑(保持当前输入法)

if (duration >= longPressThreshold) {

if isEnglishMode() {

; ShowToolTip("aa(长按耗时:" duration "ms)")

} else {

; ShowToolTip("中(长按耗时:" duration "ms)")

}

return

}

; 短按逻辑

if GetKeyState("CapsLock", "T") {

SetCapsLockState 0

}

if isEnglishMode() { ; 当前为英文时切换

Send "^{Space}"

}

ShowToolTip("中")

; ShowToolTip("中(短按耗时:" duration "ms)") ; 新增时间显示

}

; 左Shift键处理函数

; 英文 → 长按LShift,保持英文,不执行后续操作

; 中文→ 长按LShift,保持中文,不执行后续操作

; 中文 → 短按LShift,切英文

; 英文 → 短按LShift,英文

LShiftHandler() {

; 长按逻辑

static longPressThreshold := 130 ;

keyDownTime := A_TickCount

; 保持原有~LShift热键特性

KeyWait "LShift"

duration := A_TickCount - keyDownTime

; 长按逻辑(保持当前输入法)

if (duration >= longPressThreshold) {

if isEnglishMode() {

; ShowToolTip("aa(长按耗时:" duration "ms)")

} else {

; ShowToolTip("中(长按耗时:" duration "ms)")

}

return

}

; 短按逻辑

if GetKeyState("CapsLock", "T") {

SetCapsLockState 0

if !isEnglishMode() {

Send "^{Space}"

}

} else {

if !isEnglishMode() {

Send "^{Space}"

}

}

ShowToolTip("aa")

; ShowToolTip("aa(短按耗时:" duration "ms)") ; 新增时间显示

}

; CapsLock键处理函数

CapsLockHandler() {

if GetKeyState("CapsLock", "T") {

SetCapsLockState 0

if !isEnglishMode() { ; 关闭CapsLock时强制切英文

Send "^{Space}"

ShowToolTip("aa")

}

} else {

SetCapsLockState 1

ShowToolTip("AA")

}

}

isEnglishMode() {

static IMC_GETCONVERSIONMODE := 0x001

static WM_IME_CONTROL := 0x0283

try {

; 启用隐藏窗口检测

originalState := A_DetectHiddenWindows

DetectHiddenWindows true

; 获取活动窗口句柄

if !(hWnd := WinExist("A")) {

throw Error("窗口句柄获取失败", -1)

}

; 获取输入法窗口句柄

if !(imeWnd := DllCall("imm32\ImmGetDefaultIMEWnd", "Uint", hWnd, "Uint")) {

throw Error("输入法窗口未找到", -2)

}

; 发送控制消息

result := SendMessage(

WM_IME_CONTROL,

IMC_GETCONVERSIONMODE,

0,

,

"ahk_id " imeWnd

)

return result == 0 ; 0=英文模式

}

catch as e {

; 显示错误提示(调试用)

ToolTip "输入法检测错误: " e.Message

SetTimer () => ToolTip(), -1000

; 安全返回值

return true ; 默认英文模式

}

finally {

; 恢复窗口检测状态

DetectHiddenWindows originalState

}

}

;-------------------------切换虚拟桌面-------------------------------------------------------------------

; 切换虚拟桌面的独立函数

SwitchVirtualDesktop() {

static pressed := false ; 静态变量保存切换状态

pressed := !pressed ; 每次调用翻转状态

; 根据状态发送不同的组合键

if pressed {

Send("^#{Right}") ; 切换到右侧虚拟桌面

} else {

Send("^#{Left}") ; 切换到左侧虚拟桌面

}

}

; #Tab:: { ; Win+Tab 热键切换两个窗口

; static pressed := false ; 静态变量保存状态

; pressed := !pressed ; 切换状态

; if (pressed) {

; Send("^#{Right}") ; 切换到右侧虚拟桌面

; } else {

; Send("^#{Left}") ; 切换到左侧虚拟桌面

; }

; }

;--------------------所有窗口最大化和最小化(全局设置DetectHiddenWindows True的时候有冲突)------------------------------------------------------

; 切换最小化和还原所有窗口(排除 Rainmeter)

ToggleMinimizeAll() {

static isMinimized := false

if (isMinimized) {

RestoreAllWindows()

isMinimized := false

} else {

MinimizeAllWindows()

isMinimized := true

}

}

; 最小化所有窗口(排除 Rainmeter)

MinimizeAllWindows() {

windows := WinGetList()

for id in windows {

try { ; 防止无效窗口导致崩溃

processName := WinGetProcessName(id)

if (processName != "Rainmeter.exe") {

WinMinimize(id)

}

}

}

}

; 还原所有最小化窗口(排除 Rainmeter)

RestoreAllWindows() {

windows := WinGetList()

for id in windows {

try {

; 先检查窗口是否存在,避免无效句柄

if !WinExist("ahk_id " id)

continue

; 排除 Rainmeter 进程

processName := WinGetProcessName(id)

if (processName == "Rainmeter.exe")

continue

; 获取窗口状态(关键修正点)

minMaxState := WinGetMinMax(id)

; AHK 中最小化状态值为 -1,最大化是 1,正常是 0

if (minMaxState == -1) {

WinRestore(id)

; 可选:激活窗口确保还原(部分系统需要)

; WinActivate(id)

}

} catch Error {

; 捕获异常(例如权限问题)

continue

}

}

}

;--------------------窗口调整循环切换位置------------------------------------------------------

; ;函数切换windowtop,windowbottom,windowleft,windowright

; ; 窗口位置配置中心(默认参数)

global WindowPositions := {

top: { width: 2560, height: 460 },

bottom: { width: 2560, height: 460 },

left: { width: 870, height: 1440 },

right: { width: 870, height: 1440 }

}

ToggleWindowPosition(params := "") {

static state := 0

state := Mod(state, 5) + 1

; 合并全局配置与自定义参数

config := MergeConfig(WindowPositions.Clone(), params)

switch state {

case 1:

windowtop(config.top.width, config.top.height)

case 2:

windowbottom(config.bottom.width, config.bottom.height)

case 3:

windowleft(config.left.width, config.left.height)

case 4:

windowright(config.right.width, config.right.height)

case 5:

MaximizeWindows()

}

}

; 配置合并函数

MergeConfig(base, extend) {

if !IsObject(extend)

return base

for k, v in extend {

if IsObject(v) && base.HasKey(k)

base[k] := MergeConfig(base[k], v)

else

base[k] := v

}

return base

}

; 调整窗口大小并定位到屏幕顶部(任务栏下方)且水平居中

windowtop(width, height) {

if NotActiveWin() {

return

}

DllCall("SetThreadDpiAwarenessContext", "ptr", -1, "ptr")

WinExist("A")

if (WindowMaxOrMin())

WinRestore

WinGetPos(&x, &y, &w, &h)

ms := GetMonitorAt(x + w / 2, y + h / 2)

MonitorGetWorkArea(ms, &l, &t, &r, &b)

w := r - l ; 工作区宽度

h := b - t ; 工作区高度

; 计算窗口尺寸(不超过工作区)

winW := Min(width, w+20)

winH := Min(height, h)

; 水平居中,顶部对齐

winX := l + (w - winW) / 2

winY := t ; 关键修改:从工作区顶部开始定位

WinMove(winX, winY, winW, winH)

DllCall("SetThreadDpiAwarenessContext", "ptr", -3, "ptr")

; SetWindowTopMost()

}

; 将当前窗口调整至显示器底部并水平居中显示

windowbottom(width, height) {

; 检查当前是否有活动窗口,没有则直接返回

if NotActiveWin() {

return

}

; 设置DPI感知模式为UNAWARE(-1),让系统自动处理缩放

; 当执行窗口移动操作时,即使指定固定像素尺寸,系统会自动适配显示器缩放比例

DllCall("SetThreadDpiAwarenessContext", "ptr", -1, "ptr")

; 确保操作对象是当前活动窗口

WinExist("A")

; 如果窗口处于最大化/最小化状态,先恢复窗口

if (WindowMaxOrMin())

WinRestore

; 获取窗口当前位置和尺寸(&表示输出变量)

WinGetPos(&x, &y, &w, &h)

; 根据窗口中心点坐标获取所在显示器序号

ms := GetMonitorAt(x + w / 2, y + h / 2)

; 获取该显示器的工作区域坐标(排除任务栏等区域)

MonitorGetWorkArea(ms, &l, &t, &r, &b)

w := r - l ; 计算工作区实际可用宽度

h := b - t ; 计算工作区实际可用高度

; 计算最终窗口尺寸(不超过显示器工作区大小)

winW := Min(width, w+20) ; 取期望宽度与最大可用宽度的较小值

winH := Min(height, h) ; 取期望高度与最大可用高度的较小值

; 计算窗口位置(水平居中 + 底部对齐)

winX := l + (w - winW) / 2 ; 水平居中:左边界 + (可用宽度-窗口宽度)/2

winY := b - winH ; 垂直底部:工作区下边界 - 窗口高度

; 移动窗口到计算位置(使用新的尺寸)

WinMove(winX, winY, winW, winH)

; 还原DPI感知模式为PER_MONITOR_AWARE(-3),确保鼠标移动等操作精准

DllCall("SetThreadDpiAwarenessContext", "ptr", -3, "ptr")

; 设置窗口置顶状态(根据之前的配置)

; SetWindowTopMost()

}

; 调整窗口大小并定位到屏幕左侧(垂直居中)

windowleft(width, height) {

if NotActiveWin() {

return

}

DllCall("SetThreadDpiAwarenessContext", "ptr", -1, "ptr")

WinExist("A")

if (WindowMaxOrMin())

WinRestore

WinGetPos(&x, &y, &w, &h)

ms := GetMonitorAt(x + w / 2, y + h / 2)

MonitorGetWorkArea(ms, &l, &t, &r, &b)

w := r - l ; 工作区宽度

h := b - t ; 工作区高度

; 计算窗口尺寸(不超过工作区)

winW := Min(width, w)

winH := Min(height, h)

; 左侧对齐,垂直居中

winX := l-10 ; 关键修改:从工作区左侧开始

winY := t + (h - winH) / 2 ; 垂直居中计算

WinMove(winX, winY, winW, winH)

DllCall("SetThreadDpiAwarenessContext", "ptr", -3, "ptr")

; SetWindowTopMost()

}

; 调整窗口大小并定位到屏幕右侧(垂直居中)

windowright(width, height) {

if NotActiveWin() {

return

}

DllCall("SetThreadDpiAwarenessContext", "ptr", -1, "ptr")

WinExist("A")

if (WindowMaxOrMin())

WinRestore

WinGetPos(&x, &y, &w, &h)

ms := GetMonitorAt(x + w / 2, y + h / 2)

MonitorGetWorkArea(ms, &l, &t, &r, &b)

w := r - l ; 工作区宽度

h := b - t ; 工作区高度

; 计算窗口尺寸(不超过工作区)

winW := Min(width, w)

winH := Min(height, h)

; 右侧对齐,垂直居中

winX := r - winW +10 ; 关键修改:从工作区右侧向左计算

winY := t + (h - winH) / 2 ; 垂直居中计算

WinMove(winX, winY, winW, winH)

DllCall("SetThreadDpiAwarenessContext", "ptr", -3, "ptr")

; SetWindowTopMost()

}

; 窗口最大化

MaximizeWindows() {

if NotActiveWin() {

return

}

if WindowMaxOrMin() {

WinRestore("A")

; SetWindowTopMost()

} else {

WinMaximize("A")

; UnsetWindowTopMost()

}

}

; 置顶窗口函数

SetWindowTopMost() {

WinSetAlwaysOnTop(true, "A")

if (WinGetExStyle("A") & 0x8) { ; 状态校验

Tip(Translation().always_on_top_on)

; 可扩展功能点:记录置顶日志/触发声音反馈

}

}

; 取消置顶函数

UnsetWindowTopMost() {

WinSetAlwaysOnTop(false, "A")

if !(WinGetExStyle("A") & 0x8) { ; 状态校验

Tip(Translation().always_on_top_off)

; 可扩展功能点:窗口位置复位/透明度重置

}

}

;--------------------配合automa,用于自动发送google邮箱,找到图片位置,在图片位置向上一点单击,然后粘贴内容------------------------------------------------------

; 设置图像文件的路径(确保使用相对路径或绝对路径)

imagePath := "D:\Program Files\MyKeymap-2.0-beta33\data\ee.bmp" ; 替换为你的图像文件路径

; 设置图像搜索的模式

CoordMode("Mouse", "Screen")

CoordMode("Pixel", "Screen")

; 定义检查间隔时间(毫秒)

checkInterval := 1000 ; 每1秒检查一次

; 定义全局变量用于保存图像位置

global Fx := 0

global Fy := 0

global imageFound := false ; 用于标记是否已经找到图像

global timerRunning := false ; 用于标记定时器是否在运行

CheckImage() {

global Fx, Fy, imagePath, imageFound

; 查找目标窗口

if WinExist("ahk_exe chrome.exe") {

; 在整个屏幕范围内搜索图像

found := ImageSearch(&Fx, &Fy, 0, 0, A_ScreenWidth, A_ScreenHeight, imagePath)

; 检查图像是否找到

if found {

; 如果图像之前没有被找到,则执行操作

if !imageFound {

; 点击图像左上角位置向上偏移28像素

Sleep 500

Click Fx, Fy-28

Send("^v")

Sleep 500 ; 等待0.5秒,以确保粘贴完成

; 移动鼠标到屏幕中间

MouseMove A_ScreenWidth // 2, A_ScreenHeight // 2

imageFound := true ; 更新标志,表示图像已找到并处理

ShowToolTip("图像已找到并处理")

}

} else {

imageFound := false ; 如果没有找到图像,重置标志

ShowToolTip("未找到图像")

}

} else {

ShowToolTip("Chrome未运行")

}

}

; 定义热键以手动控制定时器

;`::ToggleTimer() ; 切换定时器状态

;+`::StopTimer()

; 切换定时器状态函数

ToggleTimer() {

global timerRunning

if (timerRunning) {

SetTimer(CheckImage, -1) ; 暂停检测

timerRunning := false

ShowToolTip("定时器已暂停")

} else {

if WinExist("ahk_exe chrome.exe") {

SetTimer(CheckImage, checkInterval) ; 启动检测

timerRunning := true

ShowToolTip("定时器已启动,每 " checkInterval " 毫秒检查一次图像")

} else {

ShowToolTip("Chrome未运行,无法启动定时器")

}

}

}

; 停止定时器函数

StopTimer() {

SetTimer(CheckImage, 0) ; 停止检测

timerRunning := false

ShowToolTip("定时器已停止")

}

  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区