界面自动化添加启用禁用元素功能

This commit is contained in:
fofolee 2025-01-18 09:02:00 +08:00
parent cf4d38c3b1
commit 7a7cb8dd54
3 changed files with 64 additions and 34 deletions

View File

@ -94,6 +94,9 @@ public class AutomationManager
[DllImport("user32.dll")] [DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId); private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
[DllImport("user32.dll")]
private static extern bool EnableWindow(IntPtr hWnd, bool bEnable);
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
private struct RECT private struct RECT
{ {
@ -121,6 +124,7 @@ public class AutomationManager
private static Form overlayForm; private static Form overlayForm;
private static Form previewForm; private static Form previewForm;
private static AutomationElement lastElement; private static AutomationElement lastElement;
private static Point lastCursorPos;
private static bool completed; private static bool completed;
private static CacheRequest CreateCacheRequest() private static CacheRequest CreateCacheRequest()
@ -318,6 +322,11 @@ public class AutomationManager
SendKeys(GetTargetElement(args), keys); SendKeys(GetTargetElement(args), keys);
break; break;
case "enable":
bool enable = GetArgumentValue(args, "-enable") == "true";
EnableElement(GetTargetElement(args), enable);
break;
default: default:
throw new Exception(string.Format("不支持的操作类型: {0}", type)); throw new Exception(string.Format("不支持的操作类型: {0}", type));
} }
@ -586,18 +595,10 @@ public class AutomationManager
- {DIVIDE} - - {DIVIDE} -
- {NUMPAD0} - {NUMPAD9} - - {NUMPAD0} - {NUMPAD9} -
: 12. enable - /
+ () - SHIFT : -xpath <XPath路径> -enable <true/false> [-window <>]
^ () - CTRL
% () - ALT
: :
- : -keys ""Hello"" - : -xpath ""//Button[@Name='确定']"" -enable true
- Enter键: -keys ""{ENTER}""
- Ctrl+C: -keys ""^c""
- Ctrl+Home: -keys ""^{HOME}""
- Alt+F4: -keys ""%{F4}""
- Shift+Tab: -keys ""+{TAB}""
: :
-window <> 使 -window <> 使
@ -1127,6 +1128,23 @@ public class AutomationManager
}; };
} }
private static void EnableElement(AutomationElement element, bool enable)
{
if (element == null)
{
throw new Exception("元素不能为空");
}
try
{
EnableWindow((IntPtr)element.Current.NativeWindowHandle, enable);
Console.WriteLine("true");
}
catch (Exception ex)
{
throw new Exception("无法更改元素的启用/禁用状态: " + ex.Message);
}
}
private static void ClickElement(AutomationElement element) private static void ClickElement(AutomationElement element)
{ {
if (element == null) if (element == null)
@ -1310,7 +1328,7 @@ public class AutomationManager
completed = false; // 使用静态字段 completed = false; // 使用静态字段
Rectangle lastRect = Rectangle.Empty; Rectangle lastRect = Rectangle.Empty;
lastElement = null; lastElement = null;
Point lastCursorPos = new Point(); lastCursorPos = new Point();
AutomationElement taskbarElement = null; AutomationElement taskbarElement = null;
List<AutomationElement> taskbarChildren = null; List<AutomationElement> taskbarChildren = null;
@ -1474,12 +1492,7 @@ public class AutomationManager
{ {
try try
{ {
mouseTimer.Stop();
overlayForm.Hide();
previewForm.Hide();
InspectElementInfo(lastElement, lastCursorPos); InspectElementInfo(lastElement, lastCursorPos);
completed = true;
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -1487,8 +1500,7 @@ public class AutomationManager
} }
finally finally
{ {
overlayForm.Close(); stopInspect();
previewForm.Close();
} }
} }
}; };
@ -1684,6 +1696,7 @@ public class AutomationManager
Clipboard.SetText(lastElement.Current.Name); Clipboard.SetText(lastElement.Current.Name);
if (e.KeyChar == 'x' || e.KeyChar == 'X') if (e.KeyChar == 'x' || e.KeyChar == 'X')
{ {
InspectElementInfo(lastElement, lastCursorPos);
stopInspect(); stopInspect();
} }
} }
@ -1694,6 +1707,4 @@ public class AutomationManager
} }
} }
} }
} }

View File

@ -64,7 +64,7 @@ async function runAutomation(
break; break;
case "select": case "select":
if (params.item) { if (params.item !== undefined) {
args.push("-item", params.item); args.push("-item", params.item);
} }
break; break;
@ -76,7 +76,7 @@ async function runAutomation(
break; break;
case "scroll": case "scroll":
if (params.direction) { if (params.direction !== undefined) {
args.push("-direction", params.direction); args.push("-direction", params.direction);
} }
if (params.amount !== undefined) { if (params.amount !== undefined) {
@ -85,9 +85,6 @@ async function runAutomation(
break; break;
case "wait": case "wait":
if (params.condition) {
args.push("-condition", params.condition);
}
if (params.timeout !== undefined) { if (params.timeout !== undefined) {
args.push("-timeout", params.timeout); args.push("-timeout", params.timeout);
} }
@ -100,10 +97,16 @@ async function runAutomation(
break; break;
case "sendkeys": case "sendkeys":
if (params.keys) { if (params.keys !== undefined) {
args.push("-keys", params.keys); args.push("-keys", params.keys);
} }
break; break;
case "enable":
if (params.enable !== undefined) {
args.push("-enable", params.enable);
}
break;
} }
let error; let error;
@ -144,4 +147,5 @@ module.exports = {
focus: (...args) => runAutomation("focus", ...args), focus: (...args) => runAutomation("focus", ...args),
highlight: (...args) => runAutomation("highlight", ...args), highlight: (...args) => runAutomation("highlight", ...args),
sendkeys: (...args) => runAutomation("sendkeys", ...args), sendkeys: (...args) => runAutomation("sendkeys", ...args),
enable: (...args) => runAutomation("enable", ...args),
}; };

View File

@ -491,6 +491,28 @@ export const windowsCommands = {
}, },
], ],
}, },
{
value: "quickcomposer.windows.automation.enable",
label: "启用/禁用元素",
icon: "toggle_on",
config: [
{
component: "OptionEditor",
options: {
enable: {
component: "ButtonGroup",
options: [
{ label: "启用", value: true },
{ label: "禁用", value: false },
],
},
},
defaultValue: {
enable: true,
},
},
],
},
{ {
value: "quickcomposer.windows.automation.expand", value: "quickcomposer.windows.automation.expand",
label: "展开/折叠", label: "展开/折叠",
@ -559,13 +581,6 @@ export const windowsCommands = {
{ {
component: "OptionEditor", component: "OptionEditor",
options: { options: {
condition: {
label: "条件",
component: "VariableInput",
icon: "filter_alt",
width: 8,
placeholder: "name=xx;type=Button",
},
timeout: { timeout: {
label: "超时(秒)", label: "超时(秒)",
component: "NumberInput", component: "NumberInput",