; 自定义的函数写在这个文件里, 然后能在 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("定时器已停止")
}
评论区