From 8c442bd83213e710089d9f22ff1d7fa80c75dfe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=A5=E4=B8=80=E4=B8=80?= <1204244136@qq.com> Date: Wed, 7 May 2025 00:38:15 +0800 Subject: [PATCH] =?UTF-8?q?build:=20=E6=B7=BB=E5=8A=A0=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=BA=93=E4=BE=9D=E8=B5=96=EF=BC=8C=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E8=BE=85=E5=8A=A9=E7=A8=8B=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- lib/DoroDebugger.ahk | 325 +++++++++++++++++++++++++++++++++++++++++++ lib/FindText.ahk | 8 +- 3 files changed, 331 insertions(+), 5 deletions(-) create mode 100644 lib/DoroDebugger.ahk diff --git a/.gitignore b/.gitignore index 33e6d21..2ef2303 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.exe -*.ini \ No newline at end of file +*.ini +.vscode \ No newline at end of file diff --git a/lib/DoroDebugger.ahk b/lib/DoroDebugger.ahk new file mode 100644 index 0000000..0a15587 --- /dev/null +++ b/lib/DoroDebugger.ahk @@ -0,0 +1,325 @@ +#Requires AutoHotkey v2.0 +#SingleInstance Force + +; --- 全局变量定义 --- +Global MyGui := "" ; GUI 对象 +Global gFocusedProgramEdit := "" ; 聚焦窗口编辑框 +Global gCalculatedCoordsEdit := "" ; 换算坐标编辑框 (可编辑) +Global gStatusText := "" ; 状态信息文本 +Global gMouseCoordsEdit := "" ; 鼠标屏幕坐标显示框 +Global gRelativeMouseCoordsEdit := "" ; 鼠标窗口相对坐标显示框 +Global gClientAreaEdit := "" ; 客户区矩形显示框 +Global gPixelColorEdit := "" ; 位置颜色显示框 (十六进制) +Global gPixelCharacterBlock := "" ; 显示颜色字符的 Text 控件 +Global gSelectedRefWidth := 3840 ; 默认目标宽度 (4K) +Global gSelectedRefHeight := 2160 ; 默认目标高度 (4K) +Global gTargethWnd := "" ; 存储上次记录的目标窗口句柄 + +; --- 目标分辨率映射表 --- +resolutions := Map( + "4K", [3840, 2160], + "2K", [2560, 1440], + "1080p", [1920, 1080] +) +defaultRefKey := "4K" + +; --- 获取当前屏幕分辨率 --- +currentW := A_ScreenWidth +currentH := A_ScreenHeight +currentResText := "当前屏幕分辨率: " . currentW . "x" . currentH + +; --- 创建图形用户界面 (GUI) --- +MyGui := Gui("+AlwaysOnTop") +MyGui.Title := "DDB v1.0" + +; 提示信息 +MyGui.Add("Text", "xm y+10", "注意:标题栏和边框均不属于客户区") + +; --- 行 1: 当前分辨率 --- +MyGui.Add("Text", "xm y+10", currentResText) + +; --- 行 2: 目标分辨率 --- +MyGui.Add("Text", "xm y+15", "目标分辨率:") +radio4k := MyGui.Add("Radio", "x+m yp vSelectedResName Checked Group", "4K") +radio2k := MyGui.Add("Radio", "x+m yp", "2K") +radio1080p := MyGui.Add("Radio", "x+m yp", "1080p") + +; --- 行 3: 聚焦窗口 --- +MyGui.Add("Text", "xm y+15", "聚焦窗口:") +gFocusedProgramEdit := MyGui.Add("Edit", "x+m yp w150 ReadOnly Left") + +; --- 行 4: 屏幕位置 --- +MyGui.Add("Text", "xm y+10", "屏幕位置:") +gMouseCoordsEdit := MyGui.Add("Edit", "x+m yp w150 ReadOnly Left") + +; --- 行 5: 窗口位置 --- +MyGui.Add("Text", "xm y+10", "窗口位置:") +gRelativeMouseCoordsEdit := MyGui.Add("Edit", "x+m yp w150 ReadOnly Left") + +; --- 行 6: 客户区矩形 --- +MyGui.Add("Text", "xm y+10", "客户区: ") ; 注意标签后的空格是用户特意加的 +gClientAreaEdit := MyGui.Add("Edit", "x+m yp w150 ReadOnly Left") + +; --- 行 7: 位置颜色 & 复制按钮 & 颜色字符 --- +MyGui.Add("Text", "xm y+10", "位置颜色:") ; 标签 +gPixelColorEdit := MyGui.Add("Edit", "x+m yp w100 ReadOnly Left") ; 显示框 +copyColorButton := MyGui.Add("Button", "x+m yp", "复制") ; 复制按钮 +copyColorButton.OnEvent("Click", CopyPixelColor) +; 使用带颜色的文本字符 '■' 显示颜色,初始为灰色 +myGui.SetFont("s12") +gPixelCharacterBlock := MyGui.Add("Text", "x+m yp c808080", "■") +myGui.SetFont("") + + +; --- 行 8: 换算坐标 & 复制按钮 & 跳转按钮 --- +MyGui.Add("Text", "xm y+10", "换算坐标:") +gCalculatedCoordsEdit := MyGui.Add("Edit", "x+m yp w100 Left", "") ; 允许输入 +copyCoordsButton := MyGui.Add("Button", "x+m yp", "复制") +copyCoordsButton.OnEvent("Click", CopyCalculatedCoords) +jumpButton := MyGui.Add("Button", "y+10", "跳转") ; 跳转按钮另起一行 +jumpButton.OnEvent("Click", JumpToCoords) + +; --- 行 9: 状态信息 --- +gStatusText := MyGui.Add("Text", "xm y+10 w300 vStatusMessage", "按 Ctrl+Alt+Q 获取鼠标信息") ; 初始提示 + +; --- 绑定其他 GUI 事件 --- +radio4k.OnEvent("Click", ResolutionChange) +radio2k.OnEvent("Click", ResolutionChange) +radio1080p.OnEvent("Click", ResolutionChange) +MyGui.OnEvent("Close", GuiClose) + +; --- 显示 GUI --- +MyGui.Show() + +; ============================================================================== +; --- 函数定义 --- +; ============================================================================== + +; --- GUI 事件处理: 分辨率选择变化 --- +ResolutionChange(GuiCtrlObj, Info) { + global gSelectedRefWidth, gSelectedRefHeight, gStatusText, resolutions + selectedName := MyGui["SelectedResName"].Value + logMsg := "" + if RegExMatch(selectedName, "^\w+", &match) { + selectedKey := match[0] + if resolutions.Has(selectedKey) { + gSelectedRefWidth := resolutions[selectedKey][1] + gSelectedRefHeight := resolutions[selectedKey][2] + logMsg := "目标分辨率已更改为 " . selectedKey . " (" . gSelectedRefWidth . "x" . gSelectedRefHeight . ")" + gStatusText.Value := logMsg + } + } +} + +; --- 热键定义: Ctrl+Alt+Q --- +; --- 热键定义: Ctrl+Alt+Q --- +^!Q:: { + ; 引用全局变量 + global MyGui, gFocusedProgramEdit, gCalculatedCoordsEdit, gStatusText, gSelectedRefWidth, gSelectedRefHeight, gMouseCoordsEdit, gRelativeMouseCoordsEdit, gClientAreaEdit, gTargethWnd, gPixelColorEdit, gPixelCharacterBlock + ; 定义局部变量 + local hWnd, progName, winTitle, displayProgInfo, mX, mY, winX, winY, winW, relX, relY, propX, propY, finalX, finalY, isInside := False + local pixelColorRGB, strColor, sixDigitColor + + ; 检查 gPixelCharacterBlock 是否有效 (保留) + if !IsObject(gPixelCharacterBlock) { + MsgBox("脚本错误: 颜色字符控件 'gPixelCharacterBlock' 未初始化。" . "请检查 GUI 创建部分代码是否正确执行。", "初始化错误", "IconError") + Return + } + + ; 强制坐标模式 + CoordMode "Mouse", "Screen" + CoordMode "Pixel", "Screen" + + ; 清空或重置显示字段 + gCalculatedCoordsEdit.Value := "" + gRelativeMouseCoordsEdit.Value := "" + gStatusText.Value := "正在处理..." + gMouseCoordsEdit.Value := "" + gClientAreaEdit.Value := "" + gPixelColorEdit.Value := "" + ; --- ↓↓↓ 直接重置颜色,不再使用 try-catch ↓↓↓ --- + gPixelCharacterBlock.Opt("c808080") ; 重置字符颜色为灰色 (依赖上面的 IsObject 检查) + + ; 获取当前活动窗口 + hWnd := WinActive("A") + if (!hWnd) { + gStatusText.Value := "错误: 未找到活动窗口。" + gFocusedProgramEdit.Value := "N/A" + gTargethWnd := "" + gPixelCharacterBlock.Opt("c808080") ; ★★★ 直接重置 ★★★ + Return + } + gTargethWnd := hWnd + + ; 获取并显示窗口信息 + progName := WinGetProcessName("A") + winTitle := WinGetTitle("A") + displayProgInfo := progName ? progName : (winTitle ? winTitle : "N/A") + gFocusedProgramEdit.Value := displayProgInfo + + ; 获取并显示鼠标屏幕坐标 + MouseGetPos(&mX, &mY) + gMouseCoordsEdit.Value := mX . ", " . mY + + ; 获取并显示像素颜色 及 更新颜色字符 (保留此处的 try-catch) + try { + pixelColorRGB := PixelGetColor(mX, mY, "RGB") + sixDigitColor := Format("{:06X}", pixelColorRGB) + strColor := "0x" . sixDigitColor + gPixelCharacterBlock.Opt("c" . sixDigitColor) ; 设置字符颜色 + gPixelColorEdit.Value := strColor + } catch Error as e { + gPixelColorEdit.Value := "获取失败: " e.Message + gPixelCharacterBlock.Opt("c808080") ; ★★★ 直接重置 ★★★ + } + + ; 获取并显示窗口客户区信息 (保留此处的 try-catch) + try { + WinGetClientPos(&winX, &winY, &winW, &winH, hWnd) + gClientAreaEdit.Value := Format("{},{} {}x{}", winX, winY, winW, winH) + } catch Error as e { + gStatusText.Value := "错误: 获取客户区失败 - " . e.Message + gClientAreaEdit.Value := "Error" + gPixelCharacterBlock.Opt("c808080") ; ★★★ 直接重置 ★★★ + Return + } + + ; 检查窗口尺寸是否有效 + if (winW <= 0 or winH <= 0) { + gStatusText.Value := "错误: 无效窗口尺寸 W:" . winW . ", H:" . winH + gClientAreaEdit.Value := Format("{},{} {}x{}", winX, winY, winW, winH) + gPixelCharacterBlock.Opt("c808080") ; ★★★ 直接重置 ★★★ + Return + } + + ; 进行边界检查 + isInside := (mX >= winX and mX < (winX + winW) and mY >= winY and mY < (winY + winH)) + + ; 根据边界检查结果进行计算和显示 + if (isInside) { + relX := mX - winX + relY := mY - winY + gRelativeMouseCoordsEdit.Value := relX . ", " . relY + + propX := relX / winW + propY := relY / winH + finalX := Round(propX * gSelectedRefWidth) + finalY := Round(propY * gSelectedRefHeight) + gCalculatedCoordsEdit.Value := finalX . ", " . finalY + + gStatusText.Value := "边界检查: 内部" + } else { + gRelativeMouseCoordsEdit.Value := "N/A" + gCalculatedCoordsEdit.Value := "" + gStatusText.Value := "边界检查: 外部(请重新聚焦鼠标)" + } +} ; 热键函数结束 ; 热键函数结束 + +; --- 跳转按钮点击处理函数 --- +JumpToCoords(GuiCtrlObj, Info) { + ; 引用全局变量 + global MyGui, gCalculatedCoordsEdit, gStatusText, gSelectedRefWidth, gSelectedRefHeight, gTargethWnd + + ; 定义局部变量 + local targetX, targetY, propX, propY, desiredRelX, desiredRelY, finalScreenX, finalScreenY + local hWnd, winX, winY, winW, winH + local inputText, match + + gStatusText.Value := "正在处理跳转..." + + ; 检查并使用存储的目标窗口句柄 + if (!gTargethWnd or !WinExist("ahk_id " . gTargethWnd)) { + gStatusText.Value := "错误: 请先用 Ctrl+Alt+Q 记录一个有效的目标窗口。" + gTargethWnd := "" + Return + } + hWnd := gTargethWnd + + ; 获取并验证用户输入的坐标 + inputText := gCalculatedCoordsEdit.Value + if (!RegExMatch(inputText, "^\s*(-?\d+)\s*[,; ]\s*(-?\d+)\s*$", &match)) { + gStatusText.Value := "错误: 无效坐标格式 (请输入 X, Y)" + Return + } + targetX := Integer(match[1]) + targetY := Integer(match[2]) + + ; 可选: 检查输入坐标范围 + if (targetX < 0 or targetX >= gSelectedRefWidth or targetY < 0 or targetY >= gSelectedRefHeight) { + gStatusText.Value := "提示: 输入坐标可能超出目标分辨率范围。" + } + + ; 获取目标窗口的客户区信息 + try { + WinGetClientPos(&winX, &winY, &winW, &winH, hWnd) + if (winW <= 0 or winH <= 0) { + throw Error("无效窗口尺寸 W:" . winW . ", H:" . winH) + } + } catch Error as e { + gStatusText.Value := "错误: 获取目标窗口客户区失败 - " . e.Message + Return + } + + ; 执行反向换算 + if (gSelectedRefWidth <= 0 or gSelectedRefHeight <= 0) { + gStatusText.Value := "错误: 无效的目标分辨率尺寸用于计算。" + Return + } + propX := targetX / gSelectedRefWidth + propY := targetY / gSelectedRefHeight + desiredRelX := propX * winW + desiredRelY := propY * winH + finalScreenX := Round(winX + desiredRelX) + finalScreenY := Round(winY + desiredRelY) + + ; 尝试重新激活目标窗口 + try { + WinActivate("ahk_id " . hWnd) + Sleep 100 + } catch Error as e { + gStatusText.Value := "警告: 激活目标窗口失败 - " e.Message ",仍尝试跳转。" + } + + ; 移动鼠标 + CoordMode "Mouse", "Screen" + MouseMove finalScreenX, finalScreenY, 0 + + ; 更新状态 + gStatusText.Value := "鼠标已跳转至目标窗口对应坐标: " . finalScreenX . ", " . finalScreenY +} + +; --- GUI 关闭处理函数 --- +GuiClose(GuiObj) { + ExitApp() +} + +; --- 复制按钮事件处理函数 --- +CopyPixelColor(GuiCtrlObj, Info) { + global gPixelColorEdit, gStatusText + local colorValue + + colorValue := gPixelColorEdit.Value + if (colorValue != "" && colorValue != "获取失败") { ; 检查是否有有效内容 + A_Clipboard := colorValue + gStatusText.Value := "颜色值 '" colorValue "' 已复制!" + SetTimer(() => (gStatusText.Value == "颜色值 '" colorValue "' 已复制!" ? gStatusText.Value := "" : ""), -2000) + } else { + gStatusText.Value := "没有有效颜色值可复制。" + SetTimer(() => (gStatusText.Value == "没有有效颜色值可复制。" ? gStatusText.Value := "" : ""), -2000) + } +} + +CopyCalculatedCoords(GuiCtrlObj, Info) { + global gCalculatedCoordsEdit, gStatusText + local coordsValue + + coordsValue := gCalculatedCoordsEdit.Value + if (coordsValue != "") { + A_Clipboard := coordsValue + gStatusText.Value := "换算坐标 '" coordsValue "' 已复制!" + SetTimer(() => (gStatusText.Value == "换算坐标 '" coordsValue "' 已复制!" ? (gStatusText.Value := "") : ""), -2000) + } else { + gStatusText.Value := "没有换算坐标可复制。" + SetTimer(() => (gStatusText.Value == "没有换算坐标可复制。" ? (gStatusText.Value := "") : ""), -2000) + } +} \ No newline at end of file diff --git a/lib/FindText.ahk b/lib/FindText.ahk index 99ad688..c62df06 100644 --- a/lib/FindText.ahk +++ b/lib/FindText.ahk @@ -3344,11 +3344,11 @@ Gui(cmd, arg1:="", args*) y:=nY+CutUp+(nH-CutUp-CutDown)//2 s:=StrReplace(s, "Text.=", "Text:="), r:=StrSplit(Lang["s8"] "|||||||", "|") s:="`; #Include `n" - . "`nt1:=A_TickCount, Text:=X:=Y:=`"`"`n" s + . "currentScale := A_ScreenDPI / 96" + . "`nt1:=A_TickCount, Text:=X:=Y:=`"`"" s . "`nif (ok:=FindText(&X, &Y, " x "-150000, " - . y "-150000, " x "+150000, " y "+150000, 0, 0, Text))" - . "`n{" - . "`n `; FindText()." . "Click(" . "X, Y, `"L`")" + . y "-150000, " x "+150000, " y "+150000, 0.1, 0.1, Text,,,,,,, currentScale, currentScale)){" + . "`n `; FindText()." . "Click(" . "X, Y, `"L`")" . "`n}`n" . "`n`; ok:=FindText(&X:=`"wait`", &Y:=3, 0,0,0,0,0,0,Text) `; " r[7] . "`n`; ok:=FindText(&X:=`"wait0`", &Y:=-1, 0,0,0,0,0,0,Text) `; " r[8]