sync SVN r18202

This commit is contained in:
2026-09-24 23:07:59 +03:00
parent c8aac857a3
commit e13b0e928e
17 changed files with 730 additions and 2 deletions

View File

@@ -0,0 +1,20 @@
# frx_convert.ps1 - converteste un raport VFP .frx <-> .fr2 cu FoxBin2Prg (fara IDE).
# .frx -> .fr2 (BIN2PRG): textul editabil/diffabil. .fr2 -> .frx + .frt (PRG2BIN): regenerare
# dupa editarea textului. Extensia fisierului dat decide directia; verifica iesirea asteptata.
# Utilizare:
# powershell -File frx_convert.ps1 -Path Rapoarte\raport.frx # scrie raport.fr2
# powershell -File frx_convert.ps1 -Path Rapoarte\raport.fr2 # scrie raport.frx + .frt
param(
[Parameter(Mandatory=$true)][string]$Path,
[string]$Exe = 'D:\ROA\UTIL\foxbin2prg\FoxBin2Prg.EXE'
)
$ErrorActionPreference = 'Stop'
if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) { Write-Output ('frx_convert: nu gasesc ' + $Path); exit 2 }
if (-not (Test-Path -LiteralPath $Exe -PathType Leaf)) { Write-Output ('frx_convert: nu gasesc FoxBin2Prg ' + $Exe); exit 2 }
$ext = [IO.Path]::GetExtension($Path).ToLower()
if ($ext -eq '.frx') { $out = [IO.Path]::ChangeExtension($Path, '.fr2') }
elseif ($ext -eq '.fr2') { $out = [IO.Path]::ChangeExtension($Path, '.frx') }
else { Write-Output ('frx_convert: extensie neasteptata ' + $ext + ' (doar .frx/.fr2)'); exit 2 }
$p = Start-Process -FilePath $Exe -ArgumentList ('"' + $Path + '"') -Wait -WindowStyle Hidden -PassThru
if ($p.ExitCode -eq 0 -and (Test-Path -LiteralPath $out)) { Write-Output ('frx_convert: OK -> ' + $out); exit 0 }
Write-Output ('frx_convert: ESUAT (exit ' + $p.ExitCode + '), nu a aparut ' + $out); exit 1

View File

@@ -0,0 +1,96 @@
# 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 - <raport>.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 "<raport>" PREVIEW NOWAIT
# =INKEY(<secunde>, '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<IntPtr> Children(IntPtr parent) {
var list = new List<IntPtr>();
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 + ')')

View File

@@ -0,0 +1,60 @@
* structura_frx.prg - listeaza structura unui raport VFP (.frx): benzile si obiectele lor,
* exact cum le asociaza motorul de raportare (prin FFC\_FRXCursor.vcx).
* Utilizare headless: precompileaza intai, apoi
* vfp9.exe -A "<...>\structura_frx.FXP" "<raport>.frx" ["<iesire>.txt"]
* Fara al doilea parametru scrie langa raport, in "<raport>_structura.txt". Se termina cu QUIT.
LPARAMETERS tcReport, tcOut
SET SAFETY OFF
SET TALK OFF
PRIVATE pcReport, pcOut
LOCAL lnF, i, lcLine
LOCAL ARRAY laF[1, 1]
pcReport = IIF(VARTYPE(tcReport) = "C", tcReport, "")
IF EMPTY(pcReport) OR NOT FILE(pcReport)
STRTOFILE("structura_frx: raport inexistent: " + pcReport + CHR(13)+CHR(10), FORCEEXT(pcReport, "structura.txt"))
QUIT
ENDIF
pcOut = IIF(EMPTY(tcOut), FORCEEXT(pcReport, "structura.txt"), tcOut)
ON ERROR DO errhand WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
STRTOFILE("Raport: " + pcReport + CHR(13)+CHR(10), pcOut)
SET CLASSLIB TO (HOME() + "FFC\_FRXCursor.vcx") ADDITIVE
USE (pcReport) IN 0 ALIAS FRX
SELECT FRX
loFRX = CREATEOBJECT("FRXCursor")
loFRX.CreateObjectCursor()
IF USED("BANDS")
SELECT BANDS
lnF = AFIELDS(laF, "BANDS")
STRTOFILE("=== BENZI ===" + CHR(13)+CHR(10), pcOut, 1)
SCAN
lcLine = ""
FOR i = 1 TO lnF
IF INLIST(laF[i,1], "BANDLABEL", "START", "STOP", "HEIGHT")
lcLine = lcLine + laF[i,1] + "=" + TRANSFORM(EVALUATE(laF[i,1])) + " "
ENDIF
NEXT
STRTOFILE(lcLine + CHR(13)+CHR(10), pcOut, 1)
ENDSCAN
ENDIF
IF USED("OBJECTS")
SELECT OBJECTS
lnF = AFIELDS(laF, "OBJECTS")
STRTOFILE("=== OBIECTE (VPOS -> banda) ===" + CHR(13)+CHR(10), pcOut, 1)
SCAN
lcLine = ""
FOR i = 1 TO lnF
IF INLIST(laF[i,1], "OBJTYPE", "OBJCODE", "VPOS", "HPOS", "HEIGHT", "WIDTH", "BANDLABEL", "START_BAND_ID", "EXPR")
lcLine = lcLine + laF[i,1] + "=" + TRANSFORM(EVALUATE(laF[i,1])) + " "
ENDIF
NEXT
STRTOFILE(lcLine + CHR(13)+CHR(10), pcOut, 1)
ENDSCAN
ENDIF
USE IN FRX
STRTOFILE("gata" + CHR(13)+CHR(10), pcOut, 1)
QUIT
PROCEDURE errhand
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
STRTOFILE("ERROR " + TRANSFORM(tnErr) + " " + tcMsg + " @ " + tcProg + ":" + TRANSFORM(tnLine) + CHR(13)+CHR(10), pcOut, 1)
ENDPROC