|
| 1 | +Add-Type -AssemblyName UIAutomationClient |
| 2 | +Add-Type -AssemblyName UIAutomationTypes |
| 3 | +Add-Type -AssemblyName System.Drawing |
| 4 | +Add-Type -AssemblyName System.Windows.Forms |
| 5 | +Add-Type @" |
| 6 | +using System; |
| 7 | +using System.Runtime.InteropServices; |
| 8 | +public class W32 { |
| 9 | + [DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr hWnd); |
| 10 | + [DllImport("user32.dll")] public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); |
| 11 | + [DllImport("user32.dll")] public static extern bool SetProcessDPIAware(); |
| 12 | + [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); |
| 13 | + [DllImport("user32.dll")] public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); |
| 14 | + [DllImport("user32.dll")] public static extern bool SetCursorPos(int X, int Y); |
| 15 | + [DllImport("user32.dll")] public static extern void mouse_event(uint dwFlags, int dx, int dy, uint dwData, IntPtr dwExtraInfo); |
| 16 | + [DllImport("kernel32.dll")] public static extern IntPtr GetConsoleWindow(); |
| 17 | + [StructLayout(LayoutKind.Sequential)] |
| 18 | + public struct RECT { public int Left, Top, Right, Bottom; } |
| 19 | + public static void Click(int x, int y) { |
| 20 | + SetCursorPos(x, y); |
| 21 | + System.Threading.Thread.Sleep(100); |
| 22 | + mouse_event(0x0002, 0, 0, 0, IntPtr.Zero); |
| 23 | + mouse_event(0x0004, 0, 0, 0, IntPtr.Zero); |
| 24 | + } |
| 25 | +} |
| 26 | +"@ |
| 27 | +[W32]::SetProcessDPIAware() |
| 28 | + |
| 29 | +$ch = [W32]::GetConsoleWindow() |
| 30 | +if ($ch -ne [IntPtr]::Zero) { [W32]::ShowWindow($ch, 6) } |
| 31 | + |
| 32 | +$log = "C:\Users\sonic\GitHub\PadForge\tools\capture_macros_log.txt" |
| 33 | +"Starting..." | Out-File $log -Encoding ascii |
| 34 | + |
| 35 | +try { |
| 36 | + $proc = Get-Process PadForge -ErrorAction Stop |
| 37 | + $hwnd = $proc.MainWindowHandle |
| 38 | + |
| 39 | + [W32]::ShowWindow($hwnd, 9) |
| 40 | + Start-Sleep -Milliseconds 300 |
| 41 | + [W32]::MoveWindow($hwnd, 50, 30, 1280, 800, $true) |
| 42 | + Start-Sleep -Milliseconds 500 |
| 43 | + [W32]::SetForegroundWindow($hwnd) |
| 44 | + Start-Sleep -Milliseconds 500 |
| 45 | + |
| 46 | + $root = [System.Windows.Automation.AutomationElement]::FromHandle($hwnd) |
| 47 | + |
| 48 | + # Click Pad1 in sidebar |
| 49 | + $pad1 = $root.FindFirst([System.Windows.Automation.TreeScope]::Descendants, |
| 50 | + (New-Object System.Windows.Automation.PropertyCondition( |
| 51 | + [System.Windows.Automation.AutomationElement]::NameProperty, "Pad1"))) |
| 52 | + if ($pad1) { |
| 53 | + $selPat = $pad1.GetCurrentPattern([System.Windows.Automation.SelectionItemPattern]::Pattern) |
| 54 | + $selPat.Select() |
| 55 | + $rect = $pad1.Current.BoundingRectangle |
| 56 | + [W32]::Click([int]($rect.Left + $rect.Width / 2), [int]($rect.Top + $rect.Height / 2)) |
| 57 | + Start-Sleep -Milliseconds 1000 |
| 58 | + "Selected+Clicked Pad1" | Out-File $log -Append -Encoding ascii |
| 59 | + } |
| 60 | + |
| 61 | + # Click Macros tab |
| 62 | + [W32]::SetForegroundWindow($hwnd) |
| 63 | + Start-Sleep -Milliseconds 300 |
| 64 | + $root = [System.Windows.Automation.AutomationElement]::FromHandle($hwnd) |
| 65 | + $macros = $root.FindFirst([System.Windows.Automation.TreeScope]::Descendants, |
| 66 | + (New-Object System.Windows.Automation.PropertyCondition( |
| 67 | + [System.Windows.Automation.AutomationElement]::NameProperty, "Macros"))) |
| 68 | + if ($macros) { |
| 69 | + $rect = $macros.Current.BoundingRectangle |
| 70 | + [W32]::Click([int]($rect.Left + $rect.Width / 2), [int]($rect.Top + $rect.Height / 2)) |
| 71 | + Start-Sleep -Milliseconds 1000 |
| 72 | + "Clicked Macros tab" | Out-File $log -Append -Encoding ascii |
| 73 | + } |
| 74 | + |
| 75 | + # Now click "Volume Control" in the macro list |
| 76 | + # From the screenshot we can see the list. Volume Control is the 2nd item. |
| 77 | + # The list area starts around X=320..680 (physical), items at Y~250(Quick Melee), Y~308(Volume Control), Y~367(Rapid Fire A) |
| 78 | + # Window is at (50,30), 1800x1200 physical (1280x800 logical at 150% DPI) |
| 79 | + # From screenshot: "Volume Control" text is roughly at row 2 of the list |
| 80 | + # List left edge ~320px from window left, item height ~60px physical |
| 81 | + # First item Y center ~ 250 from window top, second ~ 310 |
| 82 | + |
| 83 | + $wr = New-Object W32+RECT |
| 84 | + [W32]::GetWindowRect($hwnd, [ref]$wr) |
| 85 | + |
| 86 | + # Click Volume Control - second list item |
| 87 | + # From the screenshot proportions: list starts at ~22% from left, items at ~26%, 33%, 40% from top |
| 88 | + $clickX = $wr.Left + [int](0.37 * ($wr.Right - $wr.Left)) # center of list area |
| 89 | + $clickY = $wr.Top + [int](0.35 * ($wr.Bottom - $wr.Top)) # second item |
| 90 | + [W32]::Click($clickX, $clickY) |
| 91 | + Start-Sleep -Milliseconds 500 |
| 92 | + "Clicked Volume Control area at ($clickX, $clickY)" | Out-File $log -Append -Encoding ascii |
| 93 | + |
| 94 | + # Bring to front and capture |
| 95 | + [W32]::SetForegroundWindow($hwnd) |
| 96 | + Start-Sleep -Milliseconds 500 |
| 97 | + |
| 98 | + [W32]::GetWindowRect($hwnd, [ref]$wr) |
| 99 | + $w = $wr.Right - $wr.Left |
| 100 | + $h = $wr.Bottom - $wr.Top |
| 101 | + |
| 102 | + $bmp = New-Object System.Drawing.Bitmap($w, $h) |
| 103 | + $g = [System.Drawing.Graphics]::FromImage($bmp) |
| 104 | + $g.CopyFromScreen($wr.Left, $wr.Top, 0, 0, (New-Object System.Drawing.Size($w, $h))) |
| 105 | + $g.Dispose() |
| 106 | + |
| 107 | + $pngPath = "C:\Users\sonic\GitHub\PadForge\screenshots\macros.png" |
| 108 | + $bmp.Save($pngPath, [System.Drawing.Imaging.ImageFormat]::Png) |
| 109 | + $bmp.Dispose() |
| 110 | + "Screenshot saved" | Out-File $log -Append -Encoding ascii |
| 111 | + "DONE" | Out-File $log -Append -Encoding ascii |
| 112 | + |
| 113 | +} catch { |
| 114 | + "ERROR: $_" | Out-File $log -Append -Encoding ascii |
| 115 | +} |
0 commit comments