Náhled reportu, kam s ním ?

V skutku Nerudovská otázka. Náhled reportu se chová poněkud svéhlavě a donutit ho aby se zobrazil v jiném okně než hlavním či měl předdefinované vlastnosti, se nemusí každému podařit.

Náhled reportu se zobrazuje vždy v hlavním okně VFP ať je či není vidět. To vždy zkalilo radost těm, kteří se snažili zobrazit náhled reportu ve formuláři zobrazeného jako "As Top Level" (Grrr-!@#?@??!?!?!). Další mohli selhat při "vnucovaní" předdefinovaných vlastností reportu (výška a šířka okna, možnost s ním hýbat/nehýbat atd.) .

1) Předdefinované vlastnosti náhledu reportu
Mnoho VFP příkazů má možnost jak přesměrovat výstup do jiného okna nebo v jiném okně dotyčné okno zobrazit či aby zobrazené okno převzalo atributy jiného okna. Příkaz REPORT FORM mezi ně též patří. Má takový hezký klíč WINDOW který způsobí, že při Preview přebere atributy okna uvedeného za klíčem WINDOW.

Ukázka:

LOCAL lcWindow,lcWindowName
lcWindow="wndReport"+SYS(2015)
lcWindowName="wndReportName"+SYS(2015)

DEFINE WINDOW (lcWindow) FROM 0,0 TO 10,20 NOMDI NOMINIMIZE;
       NOZOOM NOGROW SYSTEM ;
       TITLE "Report " NAME (lcWindowName)

REPORT FORM (lcReport) PREVIEW WINDOW (lcWindow)
RELE WINDOW (lcWindow) && Smaž okno

2) Zobrazení náhledu reportu ve formuláři zobrazeného jako "As Top Level"
Na toto se použije podobný fígl, ale má to jednu podmínku - hlavní okno VFP po dobu spuštění reportu musí býti skryto. Fígl spočívá v tom, že při definici pomocného okna se přidá klauzule IN a název okna ve kterém se má pomocné okno zobrazit.

Ukázka:

LOCAL lcWindow,lcWindowName

yy=CREATEOBJECT("_form")
yy.Show()
yy.Name="yy"

lcWindow="wndReport"+SYS(2015)
lcWindowName="wndReportName"+SYS(2015)

DEFINE WINDOW (lcWindow) FROM 0,0 TO 10,20 NOMDI NOMINIMIZE;
       NOZOOM NOGROW SYSTEM ;
       TITLE "Report " NAME (lcWindowName) IN ("yy")

REPORT FORM (lcReport) PREVIEW WINDOW (lcWindow)
RELE WINDOW (lcWindow) && Smaž okno

****************************************
DEFINE CLASS _form AS form
   ShowWindow=2
ENDDEFINE

3) Oprava titulku a velikosti náhledu reportu
Zde použije knihovna Foxtools.fll a pomocný objekt třídy Timer. Změna velikosti náhledu je zde přizpůsobována velikosti hlavního okna VFP. Těsně před spuštěním reportu se vytvoří timer dle pomocné třídy. Po spuštění reportu dojde k vyvolání události Timer() pomocného timeru - ta zajistí změnu popisu a velikosti okna.

Fígl spočívá v tom, že již při prvním vyvolání události Timer() je aktivní náhled reportu. Pomocí funkce _WOnTop() se zjistí VFP handle okna a pomocí funkce _WTitle() jeho popisek. Pokud popisek okna "náhodou" nesedí dojde k ukončení události (zjišťování okna na vrchu se provádí jen tehdy je-li vlastnost hwnd rovna 0). Pokud popisek okna odpovídá, zapíše se VFP handle do vlastnosti hwnd a pomocí funkce _WSetTitle() dojde k opravě popisu. Následně dojde pomocí funkce _wSizeP() ke změně velikosti náhledu.

Ukázka:

LOCAL loTmr
loTmr=CREATEOBJECT("_tmrrpt")
.
.
.
REPORT FORM (lcReport) PREVIEW WINDOW (lcWindow)
.
.
.
RETURN


DEFINE CLASS _tmrrpt AS timer
   Interval=250
   hwnd=0
   PROCEDURE tmrc.Timer
      LOCAL liIH,lcCaption
      * Jde o první spuštění
      liIH=This.hwnd
      IF liIH=0
         liIH=_WOnTop() && IH okna
         IF "Report "#LEFT(_WTitle(liIH),7)
            * Nejedná se o report
            RETURN
         ENDIF
         This.hwnd=liIH
      ENDIF
      * Vygeneruj popis
      _Screen.Visible=.T.
      lcCaption="Popis reportu - stránka : " +STR(_pageno,10)
      IF SYS(2007,lcCaption)#SYS(2007,_WTitle(liIH))
         =_WSetTitle(liIH,lcCaption)
      ENDIF
      IF _wHeightP(liIH)#_Screen.Height OR _wWidthP(liIH)#_Screen.Width
         _wSizeP(liIH,_Screen.Width+SYSMETRIC(3)*2,_Screen.Height+SYSMETRIC(4)*2)
      ENDIF
   ENDPROC
ENDDEFINE

Koněc filmá ?
Výše uvedené zdrojové kódy jsou vytrhnuty z ukázky kterou je možno stáhnouti zde a která je též okomentována. Ukázka je spustitelná programem Main.