# randare_preview.ps1 - deschide un raport VFP in PREVIEW si salveaza pagina intr-un PNG, fara sa # fure focus (PrintWindow pe fereastra copil de preview, nu captura de ecran). # Captureaza strict fereastra "Report Preview - .frx [- Page N]" (copil al shell-ului VFP); # NU "Report Designer" si NU fereastra Command Window. # Scriptul VFP dat (-Fxp, precompilat) trebuie sa pregateasca cursorul de test, apoi: # REPORT FORM "" PREVIEW NOWAIT # =INKEY(, 'H') && cat timp scriptul e viu, fereastra randeaza si poate fi capturata # Utilizare: # powershell -File randare_preview.ps1 -Fxp ui_render.FXP -Png preview.png -TitleMatch pvcasare_mf param( [Parameter(Mandatory=$true)][string]$Fxp, [string]$Png, [int]$WaitSec = 20, [string]$TitleMatch = '', [string]$Vfp = 'C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe' ) $ErrorActionPreference = 'Stop' if (-not (Test-Path -LiteralPath $Fxp -PathType Leaf)) { Write-Output ('randare_preview: nu gasesc ' + $Fxp); exit 2 } if (-not $Png) { $Png = Join-Path (Split-Path -Parent $Fxp) 'preview.png' } Add-Type -AssemblyName System.Drawing Add-Type @" using System; using System.Text; using System.Collections.Generic; using System.Runtime.InteropServices; public class W32Prev { [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left, Top, Right, Bottom; } public delegate bool EnumProc(IntPtr hWnd, IntPtr lParam); [DllImport("user32.dll")] public static extern bool EnumChildWindows(IntPtr hWnd, EnumProc cb, IntPtr lParam); [DllImport("user32.dll", CharSet=CharSet.Unicode)] public static extern int GetWindowText(IntPtr hWnd, StringBuilder s, int max); [DllImport("user32.dll")] public static extern bool IsWindowVisible(IntPtr hWnd); [DllImport("user32.dll")] public static extern bool GetWindowRect(IntPtr hWnd, out RECT r); [DllImport("user32.dll")] public static extern bool PrintWindow(IntPtr hWnd, IntPtr hdc, uint flags); [DllImport("user32.dll")] public static extern bool MoveWindow(IntPtr hWnd, int x, int y, int w, int h, bool repaint); public static string Text(IntPtr h) { var sb = new StringBuilder(512); GetWindowText(h, sb, 512); return sb.ToString(); } public static List Children(IntPtr parent) { var list = new List(); EnumChildWindows(parent, delegate(IntPtr h, IntPtr l) { list.Add(h); return true; }, IntPtr.Zero); return list; } } "@ $proc = Start-Process -FilePath $Vfp -ArgumentList @('-A', ('"' + $Fxp + '"')) -PassThru $page = [IntPtr]::Zero $deadline = (Get-Date).AddSeconds($WaitSec) while ((Get-Date) -lt $deadline) { if ($proc.HasExited) { break } $proc.Refresh() $main = $proc.MainWindowHandle if ($main -ne [IntPtr]::Zero) { foreach ($h in [W32Prev]::Children($main)) { if (-not [W32Prev]::IsWindowVisible($h)) { continue } $t = [W32Prev]::Text($h) if (-not $t) { continue } if ($t -like '*Print Preview*') { [W32Prev]::MoveWindow($h, 2100, 0, 320, 90, $true) | Out-Null; continue } if ($t -like '*Report Designer*' -or $t -like '*Command Window*') { continue } if ($t -notlike '*Report Preview*') { continue } $match = if ($TitleMatch) { $t -like ('*' + $TitleMatch + '*') } else { $true } if ($match) { $r = New-Object W32Prev+RECT [W32Prev]::GetWindowRect($h, [ref]$r) | Out-Null if (($r.Right - $r.Left) -gt 200 -and ($r.Bottom - $r.Top) -gt 200) { $page = $h; break } } } } if ($page -ne [IntPtr]::Zero) { break } Start-Sleep -Milliseconds 400 } if ($page -eq [IntPtr]::Zero) { if (-not $proc.HasExited) { $proc.Kill() } Write-Output 'randare_preview: nu am gasit fereastra de preview (TitleMatch gresit sau raportul nu s-a deschis)' exit 1 } [W32Prev]::MoveWindow($page, 0, 0, 1450, 980, $true) | Out-Null Start-Sleep -Seconds 3 $r = New-Object W32Prev+RECT [W32Prev]::GetWindowRect($page, [ref]$r) | Out-Null $w = $r.Right - $r.Left; $h = $r.Bottom - $r.Top if ($w -le 0 -or $h -le 0) { $w = 1450; $h = 980 } $bmp = New-Object System.Drawing.Bitmap $w, $h $g = [System.Drawing.Graphics]::FromImage($bmp) $hdc = $g.GetHdc() $ok = [W32Prev]::PrintWindow($page, $hdc, 2) $g.ReleaseHdc($hdc); $g.Dispose() if (-not $ok) { $g2 = [System.Drawing.Graphics]::FromImage($bmp); $hdc2 = $g2.GetHdc() [W32Prev]::PrintWindow($page, $hdc2, 0) | Out-Null $g2.ReleaseHdc($hdc2); $g2.Dispose() } $bmp.Save($Png, [System.Drawing.Imaging.ImageFormat]::Png) $bmp.Dispose() if (-not $proc.HasExited) { $proc.Kill() } Write-Output ('randare_preview: SAVED ' + $Png + ' (' + $w + ' x ' + $h + ')')