feat: 桌面拾取器——UIA 元素拾取(空格确认/Esc 取消)、窗口列表、屏幕区域框选截图,属性面板按能力类型切换网页/桌面拾取
This commit is contained in:
1 parent
1e649d7121
commit
8b0004bf72
4 files changed
+184
No files matched your search
@@ -0,0 +1,72 @@
|
||||
param([string]$Mode = "element")
|
||||
$ErrorActionPreference = "Continue"
|
||||
Add-Type -AssemblyName UIAutomationClient, UIAutomationTypes
|
||||
Add-Type -AssemblyName System.Windows.Forms
|
||||
Add-Type -MemberDefinition "[DllImport(`"user32.dll`")] public static extern short GetAsyncKeyState(int key); [DllImport(`"user32.dll`", CharSet = CharSet.Unicode)] public static extern int GetWindowTextW(IntPtr h, System.Text.StringBuilder sb, int max);" -Name PickW32 -Namespace RpaPick | Out-Null
|
||||
|
||||
if ($Mode -eq "windows") {
|
||||
$wins = @()
|
||||
foreach ($p in Get-Process) {
|
||||
if ($p.MainWindowHandle -ne [IntPtr]::Zero -and $p.MainWindowTitle) {
|
||||
$wins += @{ title = $p.MainWindowTitle; process = $p.ProcessName }
|
||||
}
|
||||
}
|
||||
Write-Output (ConvertTo-Json $wins -Compress -AsArray)
|
||||
exit 0
|
||||
}
|
||||
|
||||
$form = New-Object System.Windows.Forms.Form
|
||||
$form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::None
|
||||
$form.TopMost = $true
|
||||
$form.StartPosition = [System.Windows.Forms.FormStartPosition]::Manual
|
||||
$form.Location = New-Object System.Drawing.Point(20, 20)
|
||||
$form.Size = New-Object System.Drawing.Size(460, 130)
|
||||
$form.BackColor = [System.Drawing.Color]::FromArgb(20, 60, 120)
|
||||
$label = New-Object System.Windows.Forms.Label
|
||||
$label.Dock = [System.Windows.Forms.DockStyle]::Fill
|
||||
$label.ForeColor = [System.Drawing.Color]::White
|
||||
$label.Font = New-Object System.Drawing.Font("Microsoft YaHei", 11)
|
||||
$label.Text = "移动鼠标选择元素..."
|
||||
$form.Controls.Add($label)
|
||||
$form.Show()
|
||||
|
||||
$prevDown = $false
|
||||
$result = $null
|
||||
while ($true) {
|
||||
$ptX = [System.Windows.Forms.Cursor]::Position.X
|
||||
$ptY = [System.Windows.Forms.Cursor]::Position.Y
|
||||
$point = New-Object System.Windows.Automation.Point($ptX, $ptY)
|
||||
$el = $null
|
||||
try { $el = [System.Windows.Automation.AutomationElement]::FromPoint($point) } catch {}
|
||||
$down = ([RpaPick.PickW32]::GetAsyncKeyState(32) -band 0x8000) -ne 0
|
||||
$esc = ([RpaPick.PickW32]::GetAsyncKeyState(27) -band 0x8000) -ne 0
|
||||
if ($esc) { break }
|
||||
if ($el) {
|
||||
$c = $el.Current
|
||||
$ctrlName = $c.ControlType.ProgrammaticName.Replace("ControlType.", "")
|
||||
$label.Text = "名称: " + $c.Name + [Environment]::NewLine + "类型: " + $ctrlName + [Environment]::NewLine + "空格=拾取 Esc=取消"
|
||||
}
|
||||
if ($down -and $el) {
|
||||
$c = $el.Current
|
||||
$rootName = ""
|
||||
$walker = [System.Windows.Automation.TreeWalker]::ControlViewWalker
|
||||
$anc = $walker.GetParent($el)
|
||||
while ($anc -and -not $anc.Equals([System.Windows.Automation.AutomationElement]::RootElement)) {
|
||||
$h = $anc.Current.NativeWindowHandle
|
||||
if ($h -ne 0) {
|
||||
$sb = New-Object System.Text.StringBuilder 512
|
||||
[RpaPick.PickW32]::GetWindowTextW([IntPtr]$h, $sb, 512) | Out-Null
|
||||
if ($sb.ToString()) { $rootName = $sb.ToString(); break }
|
||||
}
|
||||
$anc = $walker.GetParent($anc)
|
||||
}
|
||||
$ctrlName = $c.ControlType.ProgrammaticName.Replace("ControlType.", "")
|
||||
$result = @{ window = $rootName; name = $c.Name; automationId = $c.AutomationId; controlType = $ctrlName; className = $c.ClassName }
|
||||
break
|
||||
}
|
||||
$prevDown = $down
|
||||
Start-Sleep -Milliseconds 80
|
||||
}
|
||||
$form.Close()
|
||||
|
||||
if ($result) { Write-Output (ConvertTo-Json $result -Compress) } else { Write-Output (ConvertTo-Json @{ cancelled = $true } -Compress) }
|
||||
Reference in new issue
Block a user