//////////////////////////////////////////////////////////////////////
//
//  PREVIEW.PRG
//
//  Copyright:
//      Alaska Software, (c) 1997-2002. Alle Rechte vorbehalten.
//
//  Inhalt:
//      Das Programm enth„lt die Klasse XbpPreview, welche die Ausgabe
//      auf einem Drucker WYSIWYG als Vorschau in einem Fenster anzeigt.
//      Die Anzeige kann gezoomt werden und l„át sich scrollen
//
//  Bemerkungen:
//      Die Prozedur Main erzeugt ein XbpDialog Fenster in das XbpPreview
//      sowie Pushbuttons zum Zoomen und Drucken eingebettet sind.
//      Die Anzeige der Druckausgabe erfolgt in der Funktion DrawDB(),
//      welche ein einfaches Listing einer Datenbank erzeugt.
//
//////////////////////////////////////////////////////////////////////

#include "Appevent.ch"
#include "Common.ch"
#include "Font.ch"
#include "Gra.ch"
#include "Xbp.ch"
#include "FileIO.ch"
#include "Thread.ch"
**
// 3.5.2004 : nOrientierung = 1 (Portrait) oder = 2 (Landscape):
PROCEDURE BPreview( aBlattG, oDlg1, cCP, aSchrift, aParamG, nOrientierung, aPP )   //24.03.2008 14:37
   LOCAL nEvent, mp1, mp2
   LOCAL oDlg, oXbpD1, oXbpDA, oXbpEoD, oXbpU, oXbpE, oXbpG, oXbpK, oXbpS, oXbpW
   LOCAL drawingArea, oVorSchau, oFocus := SetAppFocus()
//   LOCAL aSizeDesktop := AppDesktop():currentSize()
//   LOCAL nBSb := aSizeDesktop[1], nBSh := aSizeDesktop[2]   //, nV := nBSb/800
   LOCAL hp := 1, vp := 1, nBo, nBz := 20*nV, aVOSize
   LOCAL aPos := {oDlg1:cargo:currentpos()[1]+4,oDlg1:cargo:currentpos()[2]} //14.04.2008 14:28
   LOCAL ASize := {oDlg1:currentsize()[1],oBEDA:cargo:currentsize()[2]}  //14.04.2008 14:22 H”he wie Hauptmaske
   LOCAL aZoom := IIf(cDruckerName!="Microsoft" .OR. !"."$cZoom,&cZoom,{ 1.13, 30, 50 }) // damit beim Start die Vorschau vergr”áert wird
   PRIVATE oFocSle, oVODA
///*07.04.2008 21:19 nH, nV ver„ndert wegen Resize */
//   IF nV < 1      // wenn die Fensterh”he reduziert wurde
//      aPos := {5*IIf(nH<1,1,nH),30*IIf(nV<1,1,nV)}       //06.04.2008 19:20
//      aSize := {790*nH,560*nV+IIf(nV<1,50-nV*50,0)}   //06.04.2008 19:20
//   ENDIF
///**/
//**23.03.2008 12:16://///////////////////////////////////
   IF cBfont != NIL
      DEFAULT aPP TO {{ XBP_PP_COMPOUNDNAME, IIf(Val(cBfont)>5, Trim(cBfont) , ;
                           cBfont := IIf(nV>1.5,"12.Arial",IIf(nV>1,"10.Arial","8.Arial")) ) }} 
   ENDIF
   IIf( DUM0==NIL, DUM0:="",)  //29.03.2008 17:29
   cDup := ""  //30.04.2007 20:52 'DUPLIKAT'
   IF Len(aParamG) = 0
      aParamG := { {"P","t","Anzahl Drucke:","1",0,"","cAnz",0,1,0} }
   ENDIF
   
   oDlg := AKDialog():new(  AppDeskTop(), oDlg1:cargo, aPos, ASize, aPP, .F.) //24.03.2008 14:37
   oDlg:border    := XBPDLG_RAISEDBORDERTHICK_FIXED
   ctitle     := "Vorschau-Dialog  - Ausdruck auf " + cDruckerName + Trim(1->name)+", "+Trim(1->vorname)+" - "+StrX(1->auftrnr)
   oDlg:title     := "Vorschau-Dialog  - Ausdruck auf " + cDruckerName + Space(150-Len(ctitle))+Trim(1->name)+", "+Trim(1->vorname)+" - "+StrX(1->auftrnr)
   oDlg:title := IIf(SET(43)==0,ConvToAnsiCP(oDlg:title),oDlg:title)   //03.12.2006 18:02
   oDlg:minButton := .F.
   oDlg:maxButton := .F.
   oDlg:taskList  := .T.
   oDlg:create()

   oVODA := oDlg:drawingArea
   oVODA:cargo := oDlg
   aVOSize := oVODA:currentSize()
//####   aVOSize[2] := aVOSize[2]/nOrientierung
   
   oVorSchau := XbpPreview():new( oVODA, oDlg, {0,0}, {aVOSize[1]/2,aVOSize[2]},aPP,, nOrientierung ) //24.03.2008 14:37
   oVorSchau:aBlatt := aBlattG
   oVorSchau:aParam := aParamG
   oVorSchau:cCP := cCP
   oVorSchau:aSchrift := aSchrift
   IF lVor     // .F. -> es wird nur editiert, ohne daá man die Seite sehen kann
      oVorSchau:drawBlock := {|oPS, nPageNo, nNumRows, aSegment, aBlatt, cCP, aSchrift, nO, cVonWo| ;
                              Vorschau_Ausgabe( oPS, aSegment, aBlatt, cCP, aSchrift, nO, cVonWo )}	//06.12.2022 18:49 von wo aufgerufen
   ENDIF
   oVorSchau:create()

//////      // SpinButton:
//////   oSpin := XbpGetSpinButton():new( oVODA, oDlg,{aVOSize[1]/2+10*nV,aVOSize[2]*nOrientierung-30*nV}, {30*nV,20*nV} )
////////   oSpin:fastSpin := .T.
//////   oSpin:create()
//////   oSpin:setNumLimits( 0, 5 )
//////   oSpin:dataLink := {|x| IIf( x==NIL, nAnz,  aParamG[ AScan( aParamG, "cAnz" ),4] := Str( nAnz := x,1 ) ) }
//////   oSpin:endSpin  := {|mp1, mp2, obj| nAnz := obj:getData(), oVorSchau:oParameter:SingleZeile[ AScan( oVorSchau:oParameter:SingleZeile, {|x| x:cargo="cAnz"} )]:setData( Str( nAnz,1 ) ) }
//////   oSpin:keyboard := {|mp1, mp2, obj| nAnz := obj:getData(), oVorSchau:oParameter:SingleZeile[ AScan( oVorSchau:oParameter:SingleZeile, {|x| x:cargo="cAnz"} )]:setData( Str( nAnz,1 ) ) }
//////   oDlg:addEditControl( oSpin )

   IF lVorH
//####      oXbpN := XbpPushButton():new( oVODA, oDlg, {aVOSize[1]/2+20*nH,aVOSize[2]*nOrientierung-30*nV}, {20*nH,20*nV} )
      oXbpN := XbpPushButton():new( oVODA, oDlg, {aVOSize[1]/2+20*nH,aVOSize[2]-30*nV}, {20*nH,20*nV}, aPP )
      oXbpN:caption := "A~v"
      oXbpN:create()
      oXbpN:helpLink := MagicHelpLabel():New(701)
      oXbpN:activate := {|| xM := 0, ;
               oVorschau:zoomfactor := 1, ;
               oVorschau:zoom( oVorschau:zoomfactor ), ;
               oVorschau:setorigin( 0,0 ) } 
      oDlg:addEditControl( oXbpN )
   
//####      oXbpG := XbpPushButton():new( oVODA, oDlg, {aVOSize[1]/2+50*nH,aVOSize[2]*nOrientierung-30*nV}, {20*nH,20*nV} )
      oXbpG := XbpPushButton():new( oVODA, oDlg, {aVOSize[1]/2+50*nH,aVOSize[2]-30*nV}, {20*nH,20*nV}, aPP )
      oXbpG:caption := "~G"
      oXbpG:create()
      oXbpG:helpLink := MagicHelpLabel():New(702)
      oXbpG:activate := {|| xM := 0, ;
               oVorschau:zoomfactor := aZoom[1], ;
               oVorschau:zoom( oVorschau:zoomfactor ), ;
               oVorschau:hScroll:setData( aZoom[2] ), ;
               oVorschau:vScroll:setData( aZoom[3] ), ;
               oVorschau:setOrigin( oVorschau:hScroll:getData(), oVorschau:vScroll:getData() ) }
      oDlg:addEditControl( oXbpG )

//####      oXbpD1 := XbpPushButton():new( oVODA, oDlg, {aVOSize[1]/2+80*nH,aVOSize[2]*nOrientierung-30*nV}, {60*nH,20*nV} )
      oXbpD1 := XbpPushButton():new( oVODA, oDlg, {aVOSize[1]/2+80*nH,aVOSize[2]-30*nV}, {60*nH,20*nV}, aPP )
      oXbpD1:caption := "~Druck 1Seite"
      oXbpD1:create()
      oXbpD1:helpLink := MagicHelpLabel():New(703)
      oXbpD1:activate := {|| xM := 0, oVorSchau:print( oVorSchau:PageNo() ) }
      oDlg:addEditControl( oXbpD1 )
   
//####      oXbpDA := XbpPushButton():new( oVODA, oDlg, {aVOSize[1]/2+160*nH,aVOSize[2]*nOrientierung-30*nV}, {60*nH,20*nV} )
      oXbpDA := XbpPushButton():new( oVODA, oDlg, {aVOSize[1]/2+160*nH,aVOSize[2]-30*nV}, {60*nH,20*nV}, aPP )
      oXbpDA:caption := "Druck ~Alles"
      oXbpDA:create()
      oXbpDA:helpLink := MagicHelpLabel():New(704)
      oXbpDA:activate := {|| xM := 0, oVorSchau:print() }   //, SetAppFocus(oFocSle) }
      oDlg:addEditControl( oXbpDA )
   ENDIF

//####   oXbpEoD := XbpPushButton():new( oVODA, oDlg, {aVOSize[1]/2+240*nH,aVOSize[2]*nOrientierung-30*nV}, {60*nH,20*nV} )
   oXbpEoD := XbpPushButton():new( oVODA, oDlg, {aVOSize[1]/2+240*nH,aVOSize[2]-30*nV}, {60*nH,20*nV}, aPP )
   oXbpEoD:caption := "Ende/~oDr"
   oXbpEoD:create()
   oXbpEoD:helpLink := MagicHelpLabel():New(705)
   // 18.6.2005: um BlattDruck() wegen der Bitmap-Probleme zu vermeiden
   IF Upper(AppName())$cAc .AND. Upper(cDru) == "BL_CHEC"   //+03.12.2012 08:14 damit auch ohne Druck automatisch gespeichert wird
      oXbpEoD:activate := {|| oEdit:TextSpeichern("Karten","ta",PadR(cTKurz0,10)+oEdit:aTxBd[2],oEdit:aTxBd), ASize(aBlattG,0), PostAppEvent( xbeP_Close ) }
   ELSE
      oXbpEoD:activate := {|| ASize(aBlattG,0), PostAppEvent( xbeP_Close ) }
   ENDIF
   oDlg:addEditControl( oXbpEoD )

//####   oXbpE := XbpPushButton():new( oVODA, oDlg, {aVOSize[1]/2+320*nH,aVOSize[2]*nOrientierung-30*nV}, {60*nH,20*nV} )
   oXbpE := XbpPushButton():new( oVODA, oDlg, {aVOSize[1]/2+320*nH,aVOSize[2]-30*nV}, {60*nH,20*nV}, aPP )
   oXbpE:caption := "Ende+Druc~k"
   oXbpE:create(,,,,aPP)
   oXbpE:helpLink := MagicHelpLabel():New(706)
   IF Upper(AppName())$"HANELX.EXE-RAGUSEX.EXE-SONNEX.EXE-BUCKX.EXE-FLUESX.EXE-BERGX.EXE-VELLX.EXE-RUDOX.EXE-VOGELX8.EXE-BARTX.EXE-SONNEX.EXE"+cAc    // 18.6.2005: um BlattDruck() wegen der Bitmap-Probleme zu vermeiden
      oXbpE:activate := {|a| xR:=xD:=xM:=0, aAnz:=Array(Val(cAnz)), AEval(aAnz,{|a,i|cDup:=IIf(i>1,DUM0,""),oVorSchau:print(,1)}), PostAppEvent( xbeP_Close ) } //27.02.2008 09:23
   ELSEIF Upper(AppName())$"MUELLX.EXE-BLEINX.EXE-NOLTEX.EXE-KLUCKX.EXE-GUDDX.EXE-SONNEX.EXE"   //+05.06.2009 13:23
      oXbpE:activate := {|a| xR:=xD:=xM:=0, nDAn:=Val(cAnz)+1, aAnz:=Array(Val(cAnz)), AEval(aAnz,{|a,i|cDup:=IIf(i>1,DUM0,""),--nDAn,oVorSchau:print(,1)}), IIf(FExists(cDatver+"safe_bl.dbf"),oVorschau:BlattSchreiben(),), PostAppEvent( xbeP_Close ) }   //+01.05.2009 19:12
   ELSEIF Upper(AppName())$"LANGEX.EXE"   //+05.06.2009 13:23
      oXbpE:activate := {|| IIf(FExists(cDatver+"safe_bl.dbf"),oVorschau:BlattSchreiben(),), PostAppEvent( xbeP_Close ) }   //+01.05.2009 19:12
   ELSE
      oXbpE:activate := {|| PostAppEvent( xbeP_Close ) }
   ENDIF
   oDlg:addEditControl( oXbpE )

//+16.12.2010 08:57 vorsichtshalber noch mal geREMt:
////+11.12.2010 17:06 Druckerwahl in der Vorschau:
//      oXbpE := XbpPushButton():new( oVODA, oDlg, {aVOSize[1]/2+240*nH,aVOSize[2]*nOrientierung-60*nV}, {60*nH,20*nV} )
      oXbpW := XbpPushButton():new( oVODA, oDlg, {aVOSize[1]/2+240*nH,aVOSize[2]-60*nV}, {60*nH,20*nV}, aPP )
      oXbpW:caption := "Druckerwahl"
      oXbpW:create()
   //   oXbpE:helpLink := MagicHelpLabel():New(706)
      oXbpW:activate := {|| cDruckername := Druckerwahl(), ASize(aBlattG,0), ASize(aParamG,0), lReset := .T., ;
                           PostAppEvent( xbeP_Close,,,oVODA:cargo ) }   //+30.01.2011 16:54 lLesen bei MuellX
//                           lLesen := IIf(Upper(AppName())$"MUELLX.EXE-BLEINX.EXE-GUDDX.EXE-LANGEX.EXE",.T.,.F.), ;
      oDlg:addEditControl( oXbpW )
////++//

//+01.05.2009 19:12 NeuStart ohne die in Safe_bl gespeicherten vorigen Daten:
   IF FExists(cDatver+"safe_bl.dbf") .AND. !Upper(AppName())$"NOLTEX.EXE-BARTX.EXE-SONNEX.EXE"
//      oXbpE := XbpPushButton():new( oVODA, oDlg, {aVOSize[1]/2+320*nH,aVOSize[2]*nOrientierung-60*nV}, {60*nH,20*nV} )
      oXbpS := XbpPushButton():new( oVODA, oDlg, {aVOSize[1]/2+320*nH,aVOSize[2]-60*nV}, {40*nH,20*nV}, aPP )
      oXbpS:caption := "Neu-Start"
      oXbpS:create()
   //   oXbpE:helpLink := MagicHelpLabel():New(706)
      oXbpS:activate := {|| ASize(aBlattG,0), ASize(aParamG,0), lReset := .T., lLesen := .F., PostAppEvent( xbeP_Close ) }
      oDlg:addEditControl( oXbpS )
		IF Upper(AppName())$"MUELLX.EXE-BLEINX.EXE-KLUCKX.EXE" //14.07.2019 21:18			10.11.2019 21:54 KLUCKX
	      oXbpS := XbpPushButton():new( oVODA, oDlg, {aVOSize[1]/2+360*nH,aVOSize[2]-60*nV}, {20*nH,20*nV}, aPP )
	      oXbpS:caption := "Mail"
	      oXbpS:create()
	   //   oXbpE:helpLink := MagicHelpLabel():New(706)
	      oXbpS:activate := {|| oVorschau:BlattMailen() }
	      oDlg:addEditControl( oXbpS )
	   ENDIF
//10.09.2020 11:29   ELSEIF Upper(AppName())$"NOLTEX.EXE" //27.05.2019 20:49  geREMt: .AND. cDru == "BL_BLUM"
//16.08.2023 18:55	ELSEIF Upper(AppName())$"NOLTEX.EXE" .AND. cDru == "BL_BLUM"	//18.01.2022 wieder aktiviert und dafr n„chste Zeile geREMt (Nolte hat nie die neue MAIL offiziell bekommen)
//18.01.2022   ELSEIF Upper(AppName())$"NOLTEX.EXE-SONNEX.EXE" .AND. !Upper(cDru)$"BL_TERM-BL_BRF0-BL_BRF1-BL_BRF2-BL_FOTO-BL_KAS-BL_KAST-BL_KASK-BL_KATX" //.AND. cDru == "BL_BLUM"
   ELSEIF Upper(AppName())$"SONNEX.EXE-VELLX.EXE-NOLTEX.EXE" .AND. !Upper(cDru)$"BL_TERM-BL_BRF0-BL_BRF1-BL_BRF2-BL_FOTO-BL_KAS-BL_KAST-BL_KASK-BL_KATX" //.AND. cDru == "BL_BLUM"
//   ELSEIF Upper(AppName())$"SONNEX.EXE-V____.EXE" .AND. !Upper(cDru)$"BL_TERM-BL_BRF0-BL_BRF1-BL_BRF2-BL_FOTO-BL_KAS-BL_KAST-BL_KASK-BL_KATX" //.AND. cDru == "BL_BLUM"
      oXbpS := XbpPushButton():new( oVODA, oDlg, {aVOSize[1]/2+320*nH,aVOSize[2]-60*nV}, {60*nH,20*nV}, aPP )
      oXbpS:caption := "Mail"
      oXbpS:create()
   //   oXbpE:helpLink := MagicHelpLabel():New(706)
      oXbpS:activate := {|| oVorschau:BlattMailen() }
      oDlg:addEditControl( oXbpS )
   ENDIF
//++//

// jetzt folgt die Erzeugung der Eingabefelder
//####   oVorSchau:oParameter := BlattFA():new( oVODA,oDlg, {aVOSize[1]/2,0}, {aVOSize[1]*.49,aVOSize[2]*nOrientierung-40*nV},,, nBz, aBlattG, aParamG )
   oVorSchau:oParameter := BlattFA():new( oVODA,oDlg, {aVOSize[1]/2,0}, {aVOSize[1]*.49,aVOSize[2]-40*nV},aPP,, nBz, aBlattG, aParamG )
   oVorschau:oParameter:Vorschau := oVorschau
//####   oVorSchau:oParameter:CREATE( oVODA,oDlg, {aVOSize[1]/2,0}, {aVOSize[1]*.49,aVOSize[2]*nOrientierung-40*nV},,, nBz )
   oVorSchau:oParameter:CREATE( oVODA,oDlg, {aVOSize[1]/2,0}, {aVOSize[1]*.49,aVOSize[2]-40*nV},aPP,, nBz )
   AEval( oVorSchau:oParameter:editControls, {|x| oDlg:addEditControl( x ) } )  // fr XbpGetController
//   AEval( oVorSchau:appendControls, {|x| oDlg:addAppendControl( x ) } )
// bis hierhin geht die Erzeugung der Eingabefelder
   oVorschau:aBlatt := oVorschau:oParameter:aBlatt
   oVorschau:aParam := oVorschau:oParameter:aParam

//+01.05.2009 19:20 Lesen der vorigen Ausflldaten aus der Safe_bl:
   IF Upper(AppName())$"MUELLX.EXE-LANGEX.EXE-KLUCKX.EXE--?BLEINX.EXE-?GUDDX.EXE"   //+27.03.2013 11:13
      IF lLesen .AND. !Upper(cDru)$"BL_ALBR-BL_ALB2-BL_6WA-BL_V-BL_VOLL-BL_FIRM-BL_RENT-BL_M14"     //+27.03.2013 11:12
         oVorschau:BlattLesen()
      ELSE
         lLesen := .T.
      ENDIF
//   ELSEIF Upper(AppName())$"NOLTEX.EXE" .AND. Upper(cDru)$"BL_FRMD"
//         oVorschau:BlattLesen()
   ENDIF
////////   //+27.03.2018 21:42 abgeschlossene Rechnung darf nicht mehr ver„ndert werden:
////////   IF Upper(AppName())$"NOLTEX.EXE"
////////      IF IsMemVar("lRechModi") .AND. lRechModi == .F.
////////         AEval( oVorSchau:oParameter:editControls, {|x| IIf(ValType(x)=="O" .AND. x:isderivedfrom("XbpSle"), x:editable := .F.,) } )
////////      ENDIF
////////   ENDIF

//   SetAppFocus(oDlg)       // Fenster muá den Focus haben, damit Parts ihn dann kriegen k”nnen!
   oDlg:setModalState( XBP_DISP_APPMODAL )
//   oDlg:show()

   oCtrl := XbpGetController():new( oDlg )
   oCtrl:create()
   oCtrl:READ( 1, .F. )

   * Shortcuts initialisieren
   oDlg:InitShortCuts( oDlg )

   IF lVor
      XXXak := "Y"
      oVorschau:UPDATE()
//24.01.2008 11:59 geREMt, weil schon in UPDATE() enthalten 06.03.2008 14:27: war wohl nicht so...
      IF !Upper(AppName())$cAc+"MUELLX.EXE-BLEINX.EXE"      //06.03.2008 14:28	//08.01.2026 13:26 BLEINX
         oVorschau:zoomfactor := aZoom[1]
         oVorschau:zoom( oVorschau:zoomfactor )
         oVorschau:hScroll:setData( aZoom[2] )
         oVorschau:vScroll:setData( aZoom[3] )
         oVorschau:setOrigin( oVorschau:hScroll:getData(), oVorschau:vScroll:getData() )
      ENDIF
   ENDIF

   nEvent := 0
   DO WHILE nEvent <> xbeP_Close
      nEvent := AppEvent( @mp1, @mp2, @oXbp )
      IF nEvent == xbeSB_Scroll
         aa01 := mp1
         aa02 := mp2
         aa03 := oXbp
      ENDIF
      IF nEvent == xbeM_LbDown   //DblClick
         aa01 := mp1
         aa02 := mp2
         aa03 := oXbp
         aa04 := "1"
      ENDIF
      IF nEvent == xbeP_Keyboard
      DO CASE
         CASE mp1 == xbeK_CTRL_G .AND. lVor
            oVorschau:zoomfactor := aZoom[1]
            oVorschau:zoom( oVorschau:zoomfactor, aZoom[2], aZoom[3] )  //24.01.2008 13:01 macht schon alles
//            oVorschau:hScroll:setData( aZoom[2] )
//            oVorschau:vScroll:setData( aZoom[3] )
//            oVorschau:setOrigin( oVorschau:hScroll:getData(), oVorschau:vScroll:getData() )
         CASE mp1 == xbeK_CTRL_K .AND. lVor
            oVorschau:zoomfactor := 1
            oVorschau:zoom( oVorschau:zoomfactor, 0, 0 ) //24.01.2008 13:01 macht schon alles
//            oVorschau:hScroll:setData( 0 )
//            oVorschau:vScroll:setData( 0 )
//            oVorschau:setorigin( 0,0 )
         CASE mp1 == xbeK_CTRL_RIGHT .AND. lVor
            PostAppEvent( xbeSB_Scroll, {hp, XBPSB_NEXTPOS},.T., oVorSchau:hScroll )
            LOOP
         CASE mp1 == xbeK_CTRL_LEFT .AND. lVor
            PostAppEvent( xbeSB_Scroll, {hp, XBPSB_PREVPOS},.T., oVorSchau:hScroll )
            LOOP
         CASE mp1 == xbeK_CTRL_DOWN .AND. lVor
            PostAppEvent( xbeSB_Scroll, {hp, XBPSB_NEXTPOS},.T., oVorSchau:vScroll )
            LOOP
         CASE mp1 == xbeK_CTRL_UP .AND. lVor
            PostAppEvent( xbeSB_Scroll, {hp, XBPSB_PREVPOS},.T., oVorSchau:vScroll )
            LOOP
//         CASE mp1 == xbeK_P_CTRL_PLUS .OR. mp1 == Asc("*") .AND. lVor
         CASE (mp1 == xbeK_P_CTRL_PLUS .OR. mp1 == xbeK_CTRL_PGUP) .AND. lVor
            PostAppEvent( xbeP_Activate,,, oVorSchau:oZoomG )
            LOOP
//         CASE mp1 == xbeK_P_CTRL_MINUS .OR. mp1 == Asc("_") .AND. lVor
         CASE (mp1 == xbeK_P_CTRL_MINUS .OR. mp1 == xbeK_CTRL_PGDN) .AND. lVor
            PostAppEvent( xbeP_Activate,,, oVorSchau:oZoomK )
            LOOP
         CASE mp1 == xbeK_SH_PGUP .AND. lVor
            PostAppEvent( xbeP_Activate,,, oVorSchau:oPrevPage )
            LOOP
         CASE mp1 == xbeK_SH_PGDN .AND. lVor
            PostAppEvent( xbeP_Activate,,, oVorSchau:oNextPage )
            LOOP
         CASE mp1 == xbeK_PGUP .AND. oVorSchau:oParameter:BEArea[2]:minimized == .F.
            PostAppEvent( xbeTab_TabActivate,,, oVorSchau:oParameter:BEArea[4] )
         CASE mp1 == xbeK_PGUP .AND. oVorSchau:oParameter:BEArea[3]:minimized == .F.
            PostAppEvent( xbeTab_TabActivate,,, oVorSchau:oParameter:BEArea[2] )
            SetAppFocus( oVorSchau:oParameter:SingleZeile[1] )
         CASE mp1 == xbeK_PGUP .AND. oVorSchau:oParameter:BEArea[4]:minimized == .F.
            PostAppEvent( xbeTab_TabActivate,,, oVorSchau:oParameter:BEArea[3] )
         CASE mp1 == xbeK_PGDN .AND. oVorSchau:oParameter:BEArea[2]:minimized == .F.
            PostAppEvent( xbeTab_TabActivate,,, oVorSchau:oParameter:BEArea[3] )
         CASE mp1 == xbeK_PGDN .AND. oVorSchau:oParameter:BEArea[3]:minimized == .F.
            nFlucht := ConfirmBox( oCB, "Mit Druck? J/N", ;
                        "Beenden:", ;
                        XBPMB_YESNOCANCEL, ;
                        XBPMB_QUESTION )
            IF nFlucht == XBPMB_RET_CANCEL
               SetAppFocus( oVorSchau:oParameter:BEArea[3] )
               LOOP
            ELSEIF nFlucht == XBPMB_RET_NO
               SetAppFocus( oXbpE )
               ASize( aBlattG, 0 )
               PostAppEvent( xbeP_Close)
            ELSE
               SetAppFocus( oXbpE )
               PostAppEvent( xbeP_Activate,,, oXbpE )
            ENDIF
         CASE mp1 == xbeK_PGDN .AND. oVorSchau:oParameter:BEArea[4]:minimized == .F.
            PostAppEvent( xbeTab_TabActivate,,, oVorSchau:oParameter:BEArea[2] )
         CASE mp1 == xbeK_F10
            SetAppFocus( oXbpE )
            PostAppEvent( xbeP_Activate,,, oXbpE )
         CASE mp1 == xbeK_ESC
            ASize( aBlattG, 0 )
            PostAppEvent( xbeP_Close)
         CASE mp1 == xbeK_F3
            oVorschau:Zoom(3)
         CASE mp1 == xbeK_CTRL_F2      //+22.08.2009 22:41
            IF FExists("Z:\Scans","D") //+01.04.2014 09:06 fr GuddX auf der WDMyCloud als Lw. Z:\
               IF !FExists("Z:\Scans\Dokumente\"+StrX(1->auftrnr,E,0),"D")
                  RunShell( "/C MD Z:\Scans\Dokumente\"+StrX(1->auftrnr,E,0),, .T. )
               ENDIF
               nP := oVorschau:numPages()
               FOR p := 1 TO nP  //+24.08.2010 18:21 Bemerkung: mehrere Seiten speichern klappt noch nicht! 24.08.2010 18:21
                  oVorschau:savepage(p,,"Z:\scans\dokumente\"+StrX(auftrnr,E)+"\"+StrX(auftrnr,E)+cDru+StrX(p,2,0)+DtoS(Date())+Left(Time(),2)+Substr(time(),4,2)+Right(time(),2)+".jpg" )
                  Sleep(100)
               NEXT
            ELSE
               IF !FExists("Scans\Dokumente\"+StrX(1->auftrnr,E,0),"D")
                  RunShell( "/C MD "+cDatver + "Scans\Dokumente\"+StrX(1->auftrnr,E,0),, .T. )
               ENDIF
               nP := oVorschau:numPages()
//               FOR p := 1 TO nP  //+24.08.2010 18:21 Bemerkung: mehrere Seiten speichern klappt noch nicht! 24.08.2010 18:21
                  oVorschau:savepage(1,,"\scans\dokumente\"+StrX(auftrnr,E)+"\"+StrX(auftrnr,E)+cDru+DtoS(Date())+Left(Time(),2)+Substr(time(),4,2)+Right(time(),2)+".jpg" )
//                  Sleep(100)
//               NEXT
            ENDIF
         CASE mp1 == xbeK_F2      //+01.12.2010 14:38
            aDateiName := {{150,150,250}} //+02.12.2010 10:07 gibt aBC als 'blau' vor
            IF FExists("Z:\Scans","D") //+01.04.2014 09:06 fr GuddX auf der WDMyCloud als Lw. Z:\
               FOR i := 1 TO oVorschau:numPages()
                  cDateiname := StrX(auftrnr,E)+SubStr(cDru,3)+"_"+StrX(i,2)+".jpg"
                  oVorschau:savepage(i,,"Z:\scans\dokumente\"+cDateiname )
                  AAdd(aDateiName,cDateiName)
               NEXT
            ELSE
               FOR i := 1 TO oVorschau:numPages()
                  cDateiname := StrX(auftrnr,E)+SubStr(cDru,3)+"_"+StrX(i,2)+".jpg"
                  oVorschau:savepage(i,,cDatver+"scans\dokumente\"+cDateiname )
                  AAdd(aDateiName,cDateiName)
               NEXT
            ENDIF
            //+01.04.2014 21:18 scannen nur fr Scanner-Kunden! (andere haben kein s_scan!!
            IF Upper(AppName())$"MUELLX.EXE-BLEINX.EXE-SCHIERX.EXE-KREMERX.EXE-HANELX.EXE-RAGUSEX.EXE-NOLTEX.EXE-TDX.EXE-KLUCKX.EXE-VELLX.EXE-GUDDX.EXE-BARTX.EXE-SONNEX.EXE"
               oBest:Scannen( aDateiname, {0,0}, {300*nHur,400*nVur}, "S_SCAN", 300, 399 )
            ENDIF
         CASE mp1 == xbeK_CTRL_F1      //+22.08.2009 22:41
            cDateiname := StrX(auftrnr,E)+cDru+DtoS(Date())+Left(Time(),2)+Substr(time(),4,2)+Right(time(),2)+".jpg"
            oVorschau:savepage(oVorschau:pageno(),,cDatver+"scans\dokumente\"+StrX(1->auftrnr,E)+"\"+cDateiname ) //+24.08.2010 18:58
            oBest:Scannen( cDateiname, {0,0}, {300*nHur,400*nVur}, "S_SCAN", 300, 399 )
         CASE mp1 == xbeK_F1
            ModalDialog( (cDatver+"f1_dr.rtf"), "Bedienungshinweise", oDlg:drawingArea, 680*nH, 460*nV )
         //+01.05.2009 21:15 DOWN+UP zum Scrollen der Parameter/Daten-Felder:
         CASE oXbp:IsDerivedFrom("XbpSle") .AND. ( mp1 == xbeK_TAB .OR. ;
                  mp1 == xbeK_RETURN .OR. mp1 == xbeK_DOWN ) .AND. Len(oVorSchau:oParameter:ScrollSeite)>0
              nSP := AScan( oVorschau:oParameter:BEArea, oXbp:setParent() ) - 1
              IF nSP > 0 .AND. oXbp:currentpos()[2] - abs( oVorschau:oParameter:ScrollSeite[nSP]:oScrollPage:currentpos()[2]) < nBz      //+nLineSpace
                 oVorschau:oParameter:ScrollSeite[nSP]:ScrollDn()
              ENDIF
         CASE oXbp:IsDerivedFrom("XbpSle") .AND. ( mp1 == xbeK_SH_TAB .OR. mp1 == xbeK_UP ) .AND. Len(oVorSchau:oParameter:ScrollSeite)>0
              nSP := AScan( oVorschau:oParameter:BEArea, oXbp:setParent() ) - 1
              IF nSP > 0 .AND. ( oXbp:currentpos()[2] - abs( oVorschau:oParameter:ScrollSeite[nSP]:oScrollPage:currentpos()[2])) + nBz * 4 > oVorschau:oParameter:ScrollSeite[nSP]:oStatic:currentsize()[2]
                 oVorschau:oParameter:ScrollSeite[nSP]:ScrollUp()
              ENDIF
         CASE mp1 == xbeK_ESC   ; exit
         ENDCASE
      ELSEIF nEvent == xbeM_Wheel .AND. Len(oVorSchau:oParameter:ScrollSeite)>0      //+01.05.2009 21:16
         nSP := AScan( oVorschau:oParameter:BEArea, oXbp:setParent() ) - 1
         IF nSP > 0        //+05.03.2012 21:54 verhindert Fehlermeldung - VellX
            IF mp2[2] < 0
               oVorschau:oParameter:ScrollSeite[nSP]:ScrollDn()
            ELSEIF mp2[2] > 0
               oVorschau:oParameter:ScrollSeite[nSP]:ScrollUp()
            ENDIF
         ENDIF
      ENDIF
      oXbp:handleEvent( nEvent, mp1, mp2 )
   ENDDO
   IF oVorschau:lDruckOK .OR. Len(aBlattG)>0   //09.10.2006 15:27   21.10.2006 14:30
      oBest:FormularNotiz(cDru)  // in BestPx.prg
   ENDIF
   oDlg:setModalState( XBP_DISP_MODELESS )
//   DbDeRegisterClient(oVorschau)
//   oVorSchau:destroy()    // mit gibt es Error bei Beenden mit ïxï /
   oDlg:destroy()
   ThreadObject():cargo := oDlg1:cargo //+16.12.2010 18:39 wegen MagicHelp
   SetAppFocus(oFocus)     // 19.11.2005
//   GO TOP       // 8.2.2005 geremt
RETURN

/*
 * Klassendeklaration
 */
CLASS XbpPreview FROM XbpStatic
   PROTECTED:
   VAR oView                      // XbpDialog als Anzeigebereich
   VAR oSquare                    // XbpStatic zum Fllen der Lcke zw. Scrollbars
   VAR oPresSpace                 // XbpPresSpace fr Vorschauausgabe
   VAR oPresSpaceP                // XbpPresSpace fr Druckerausgabe
   VAR oFont                      // XbpFont
   VAR aViewPort                  // Viewport zum zoomen
   VAR aPageSize                  // Seitengr”áe zum Drucken
   VAR aCharAttr                  // Attribute fr Strings (GRA_AS_BOX)
   VAR aAreaAttr                  // Attribute fr Fl„chen (GRA_AA_COLOR)
   VAR nPagePos                   // akt. Seitenposition
   VAR nRows                      // Anz. der Zeilen pro Seite
//   METHOD setOrigin               // Ursprung fr Viewport setzen
   METHOD calcScrollBox           // Gr”áe der ScrollBox bei Scrollbars berechnen

   METHOD startDoc                // Drucken beginnen
   METHOD endDoc                  // Drucken beenden

   EXPORTED:
   VAR hScroll    READONLY        // Horizontaler Scrollbar
   VAR vScroll    READONLY        // Vertikaler Scrollbar
   VAR oPagePos                   // Static zum Anzeigen der akt. Seitenposition
   VAR oNextPage                  // Button zum Anzeigen der naechsten Seite
   VAR oPrevPage                  // Button zum Anzeigen der vorigen Seite
   VAR oZoomG
   VAR oZoomK
                                  ** Konfiguration
   VAR drawBlock                  // Codeblock ruft Func zum Zeichnen auf
   VAR printer                    // XbpPrinter
   VAR zoomFactor                 // Zoomfaktor von 1 bis n
   VAR segments                   // Array mit Segment IDs
   VAR segmentsH                  // Array mit Segment IDs der Hintergrundsegmente
   VAR segmentsP                  // Array mit Segment IDs
   VAR segmentsPH                 // Array mit Segment IDs der Hintergrundsegmente

   VAR oParameter                // die Sle-Gruppe im Vorschau-Fenster
   VAR oDaten1                   // ~ in der zweiten TabPage
   VAR aBlatt
   VAR aParam
   VAR cCP
   VAR aSchrift
   VAR Orient                    // Orientierung des Druckers: 1=Portrait, 2=Landscape
   VAR BitRate                   // Aufl”sung fr Vorschau-Grafiken   // 27.02.2006
//////   VAR oBitMap
//////   VAR aBitSize
//////   VAR aBitRect
   VAR autoscale                 // Bitmap automatisch scalieren auf Canvas   16.11.2006 08:25
   VAR lDruckOK                   // Ausgabe auf Drucker ist erfolgt .T.
                                  ** Lebenszyklus
   METHOD init                    //
   METHOD create                  //
   METHOD destroy                 //
                                  ** Anzeige
   METHOD setSize                 // Gr”áe definieren
   METHOD hScroll                 // Horizontal scrollen
   METHOD vScroll                 // Vertical scrollen
   METHOD zoom                    // Zoomen
   METHOD setOrigin               // Ursprung fr Viewport setzen   04.04.2006 (frher protected)
   METHOD presSpace               // Pesentation Space abfragen
   METHOD pageSize                //+ Seitengr”áe abfragen (weil aPageSize=protected)
   METHOD font
   METHOD setViewPort             // Gr”áe vom Viewport einstellen
   METHOD autoscale               // Bitmap automatisch scalieren auf Canvas   16.11.2006 08:25
   METHOD drawPage                // Zeichnen einer Seite
                                  ** Drucken
   METHOD print                   // Ausgeben der Seiten auf dem Drucker
   METHOD printPage                   // Ausgeben der Seiten auf dem Drucker

   METHOD savePage                //+30.10.2008 10:07 speichern der Seite als JPG-File

   METHOD numPages                // Ermitteln der Anzahl der Seiten
   METHOD pageNo                  // Ermitteln der Nummer der akt. Seite

   METHOD drawNextPage            // Zeichnen der n„chsten Seite
   METHOD drawPrevPage            // Zeichnen der vorigen Seite
   METHOD drawPosSize             // rechnet die Lage+Gr”áe der Karte im A4-Blatt aus 24.01.2008 09:40
   METHOD UPDATE                  // Žnderungen wirksam werden lassen
   METHOD ParUpdate
   METHOD BlattSchreiben         //+01.05.2009 18:38 schreibt die BlattFA-SLEs in die Safe_bl.dbf
   METHOD BlattLesen             //+01.05.2009 18:39 liest die BlattFA-SLEs aus der Safe_bl.dbf
   METHOD BlattMailen            //+23.04.2017 10:01 speichert mailt das Vorschaublatt als jpg
ENDCLASS



/*
 * Objekt initialisieren
 */
METHOD XbpPreview:init( oParent, oOwner, aPos, aSize, aPP, lVisible, nOrientierung )
   LOCAL oDlg, oFocus

   //+11.10.2009 12:05 PUBLICs fr Textlage initialisieren:
      nSGl := 0; nSGr := 0; nZGo := 0; nZGu := 0  //+11.10.2009 10:28 Grenzen bedruckten Texts

   ::Orient := nOrientierung
   ::XbpStatic:init( oParent, oOwner, aPos, aSize, aPP, lVisible )
   ::XbpStatic:type  := XBPSTATIC_TYPE_RAISEDRECT

   IF lVor
   ::oView           := XbpDialog():new( self )
   ::oView:cargo     := "ViewArea"                 //+19.11.2008 12:08 fr bl_sym

   ::vScroll         := XbpScrollbar():new( self )
   ::vScroll:type    := XBPSCROLL_VERTICAL
   ::vScroll:cargo   := 0
   ::vScroll:autoTrack := .F.

   ::oPagePos        := XbpPushButton():new( self )
   ::oPagePos:activate := { || MsgBox("Springe zu Seite n (nicht implementiert)") }
   ::oPagePos:helpLink := MagicHelpLabel():New(710)

   ::oNextPage       := XbpPushButton():new( self )
   ::oNextPage:caption := ">"
   ::oNextPage:helpLink := MagicHelpLabel():New(712)
   ::oNextPage:activate := { || ::drawNextPage() }
   ::oPrevPage       := XbpPushButton():new( self )
   ::oPrevPage:caption := "<"
   ::oPrevPage:helpLink := MagicHelpLabel():New(711)
   ::oPrevPage:activate := { || ::drawPrevPage() }

   ::hScroll         := XbpScrollbar():new( self )
   ::hScroll:type    := XBPSCROLL_HORIZONTAL
   ::hScroll:cargo   := 0
   ::hScroll:autoTrack := .F.

   ::oSquare         := XbpStatic():new( self )
   ::oSquare:type    := XBPSTATIC_TYPE_RECESSEDBOX

   ::oZoomG       := XbpPushButton():new( self )
   ::oZoomG:caption := "+"
   ::oZoomG:helpLink := MagicHelpLabel():New(713)
   ::oZoomG:activate := { || ::zoom( ::zoomFactor + 0.05 ) }
   ::oZoomK       := XbpPushButton():new( self )
   ::oZoomK:caption := "-"
   ::oZoomK:helpLink := MagicHelpLabel():New(714)
   ::oZoomK:activate := { || ::zoom( ::zoomFactor - 0.01 ) }

   // Initialisieren des Presentation Space fr die
   // Ausgabe der Vorschau. Um genaue Textausgabe
   // sicherzustellen, wird hier explizit der Modus
   // "hohe Textpr„zision" eingestellt
   ::oPresSpace      := XbpPresSpace():new()
   ::oPresSpaceP      := XbpPresSpace():new()
//   ::oPresSpace:mode := XBPPS_MODE_HIGH_PRECISION
   ::oPresSpace:cargo := self
   ::oPresSpaceP:cargo := self
   ::zoomFactor      := 1
   ::segments        := {}
   ::segmentsH       := {}    //+16.12.2008 14:38
   ::segmentsP       := {}
   ::segmentsPH      := {}    //+16.12.2008 14:38
   ::nPagePos        := 1
   ::nRows           := 0

   // Standard Drucker bereitstellen   // Auswahl fr ALLE seit 23.6.2003:
      IF Empty(cDruckerName) //.OR. Upper(AppName())$"NOLTEX.EXE"   //+28.10.2010 15:13
         oFocus := SetAppFocus() //31.10.2006 11:33 damit nach der Druckerwahl der Focus restauriert wird
         oDlg := XbpPrintDialog():new()
         oDlg:CREATE()
         ::printer := oDlg:DISPLAY()
         cDruckerName := IIf( Empty(::printer), (::PRINTER := XbpPrinter():new():CREATE()):devName, ::printer:devName )
         oDlg:destroy()
         SetAppFocus( oFocus )   //31.10.2006 11:33 hat aber vielleicht nichts gebracht...
         ::PRINTER := XbpPrinter():new()
         ::PRINTER:CREATE(cDruckerName)
         ::PRINTER:setorientation(1)
         ASize := ::printer:paperSize()
         cDruckerName := ::PRINTER:devName
      ELSE
         ::printer := XbpPrinter():new()
         ::PRINTER:CREATE(cDruckerName)
      ENDIF
      ::PRINTER:setorientation(::Orient)
    // Beende Applikation wenn kein Drucker installiert ist.
   IF ::printer:list() == NIL
      MsgBox( "Fehler - Es sind keine Drucker installiert!", "Vorschau" )
      ::cargo := "Fehler"
      RETURN self
   ENDIF
   ENDIF
   ::aBlatt := {}
   ::aParam := {}
   ::cCP    := ""
   ::aSchrift := {}
// 19.03.2006  Grafik in der Vorschau besser sichtbar mit cFarbeBG != "2" (=f09[1])
   ::BitRate := IIf( cFarbeBG == "2", GRA_BLT_BBO_OR, GRA_BLT_BBO_IGNORE )    // 27.02.2006  Grafik in der Vorschau sichtbar
   ::lDruckOK := .F.
   ::autoscale := .T.
RETURN self



/*
 * Systemresourcen anfordern
 */
METHOD XbpPreview:create( oParent, oOwner, aPos, aSize, aPP, lVisible )
//   LOCAL oFont, i, imax, aFontList

   // XbpStatic ist Parent fr alle weiteren XBPs
   ::XbpStatic:create( oParent, oOwner, aPos, aSize, aPP, lVisible )

   IF lVor
   // Printer erzeugen  // siehe INIT : Auswahl fr ALLE seit 23.6.2003:

   // XbpDialog wird ohne Titel angezeigt
   ::oView:minButton := .F.
   ::oView:maxButton := .F.
   ::oView:sysMenu   := .F.
   ::oView:titleBar  := .F.
   ::oView:border    := XBPDLG_THINBORDER
   ::oView:create()

   ::oPagePos:create()
   ::oPagePos:setFontCompoundName( "7.Arial" )
   ::oPagePos:paint  := { || ::oPagePos:setCaption( AllTrim(Str(::pageNo())) +;
                             "/" + AllTrim(Str(::numPages())) ) }

   ::oNextPage:create()
   ::oNextPage:setFontCompoundName( "7.Arial" )
   ::oPrevPage:create()
   ::oPrevPage:setFontCompoundName( "7.Arial" )

   // Scrollbars und Fllquadrat zw. Scrollbars erzeugen
   ::oSquare:create()
   ::hScroll:create()
   ::vScroll:create()

   ::hScroll:scroll := {|mp1,mp2| ::hScroll( mp1, mp2 ) }
   ::vScroll:scroll := {|mp1,mp2| ::vScroll( mp1, mp2 ) }

   ::oZoomG:create()
   ::oZoomG:setFontCompoundName( "7.Arial" )
   ::oZoomK:create()
   ::oZoomK:setFontCompoundName( "7.Arial" )

   // Gr”áe der XBPs wird in :setSize() eingestellt
   ::setSize( ::currentSize() )

   // Gr”áe der Druckseite abzglich nicht bedruckbarer R„nder berechnen
   // Die Einheit ist 1/10 mm
   aSize       := ::printer:paperSize()
//TD>/////////////////////////////////////////////
   IF cLPTSCR $ "T TD A" .OR. cFormular = "J"  //+11.01.2009 18:09 wegen Deckungsgleichheit mit der Grafik:
      ::aPageSize := { aSize[1], aSize[2] }     // beim Trauerdruck keine unbedruckbaren R„nder beim Text
   ELSE
      ::aPageSize := { aSize[5]-aSize[3], aSize[6]-aSize[4] }
   ENDIF
//>TD/////////////////////////////////////////////
   // Presentation Space mit Drucker Device Context verknpfen
   // Der PS bekommt die metrische Einheit 1/10 mm
   ::oPresSpace:create( ::printer, ::aPageSize, GRA_PU_LOMETRIC )
   ::oPresSpaceP:create( ::printer, ::aPageSize, GRA_PU_LOMETRIC )

   IF ::oFont == NIL
      // Default Font bereitstellen -> kleiner Nichtproportionalfont
//      ::oFont := XbpFont():new( ::oPresSpace )
////      ::oFont:familyName := "Courier New"       // oFont wird in BlattDrG gesetzt
////      ::oFont:nominalPointSize := 12
////      ::oFont:generic := .T.
////      ::oFont:create("12.Courier New")
   ENDIF

   // Presentation Space mit Window Device Context verknpfen
   ::oPresSpace:configure( ::oView:drawingArea:winDevice() )

//!*!// Viewport initialisieren ( hier! und nicht unten! , damit der Maástab stimmt! )
   aSize       := ::oView:drawingArea:currentSize()
   ::aViewPort := { 0, 0, aSize[1], aSize[2] }
   ::oPresSpace:setViewPort( ::aViewPort )         // neue Zeile (ak)
//   ::oView:drawingArea:paint := {|| ::drawPage() }
   ::oView:drawingArea:paint := {|| cBKpf := cBriefKopf, ::drawPage() }    //+01.10.2011 20:44 cBKpf:=...

   // Beim Repaint wird alles mit einer weiáen Box bermalt
   ::aCharAttr := Array( GRA_AS_COUNT )
   ::aAreaAttr := Array( GRA_AA_COUNT )
   ::aAreaAttr [ GRA_AA_COLOR ] := GRA_CLR_WHITE
   ::oPresSpace:setAttrArea( ::aAreaAttr )
   ::oPresSpaceP:setAttrArea( ::aAreaAttr )

//   ::oPresSpace:setFont( ::oFont )       // oFont wird in BlattDrG gesetzt

   // Beende Applikation, wenn kein Codeblock zugewiesen wurde
   IF ValType( ::drawBlock ) != "B"
      MsgBox( ":drawBlock ist ungltig!" )
      QUIT
   ENDIF

   // Evaluieren des Codeblocks in ":drawBlock" zum Formatieren
   // der ersten Seite. Dieser muá eine Routine aufrufen, die
   // die Anzeige durchfhrt, siehe Funktion "FormatPage()"
         ::segments := Eval( ::drawBlock,  ;
                                      ::oPresSpace, ;
                                      1,      ;
                                      @::nRows, ;
                                      ::segments,  ;
                                      ::aBlatt, ;
                                      ::cCP,    ;
                                      ::aSchrift, ;
                                      ::Orient, ;
                                      "::create" )		//06.12.2022 18:45 create zum Verfolgen, von wo der drawblock aufgerufen wurde
  ASize( ::segmentsP, ::numPages() )

   ::zoom()
   ENDIF
RETURN self



/*
 * Systemresourcen freigeben
 */
METHOD XbpPreview:destroy
     LOCAL oDC := ::oPresSpace:device() 
     LOCAL oDCP := ::oPresSpaceP:device() 

      IF .NOT. oDC == NIL 
         ::oPresSpace:configure()          // Device-Context vom PS abh„ngen 
         oDC:destroy()            // und freigeben 
      ENDIF 
      IF .NOT. oDCP == NIL 
         ::oPresSpaceP:configure()          // Device-Context vom PS abh„ngen 
         oDCP:destroy()            // und freigeben 
      ENDIF 


//+22.01.2018 21:50:^vvvv-wirkt-wirklich-vvvvvvvvvvvv
   FOR i := 1 TO Len(::segments)
      GraSegDestroy(::oPresSpace,::segments[i])
      GraSegDestroy(::oPresSpaceP,::segments[i])
   NEXT
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

   ::xbpStatic:destroy()
   ::aViewPort := ;
   ::aPageSize := ;
   ::oFont     := NIL
//   ::oParameter:destroy()
RETURN self

/*
Aus der Knowledgebase von alaska-software.com

Open Build: 
Open Date: 
Language: 
1.10.155 
03/25/1998 
(All) 
Closed Build: 
Close Date: 
Platform: 
1.10.155 
03/25/1998 
WIN32 
State: 
Reference PDR ID: 
Hotfix Rollup No.: 
CLOSED 
  
  
Symptom: 
Lifecycle of some Xbase Parts incorrect 
Description: 
Objects of the classes listed below might cause problems by being
freed by the Garbage Collector under certain circumstances:

 o XbpPresSpace
 o XbpClipboard
 o XbpBitmap
 o XbpFileDev
 o XbpPrinter
 o XbpMetaFile
 o XbpHelpLabel

This behaviour may occur when the reference to these objects is lost
because the object was either stored in a scoped variable (LOCAL) and
the scope of this variable is left or when the variable is reset to
something else.


Solution: 
If you create these objects in some function or subroutine, ensure that
every object is properly destroyed by calling its :destroy() method
before returning.

If you might need one of these objects somewhere else from the place
where you created it, make sure you always have a valid reference to the
object to pass around. A subroutine that creates such an object should
return it to the caller directly instead of assuming that it may be
accessed via some other means.

*/



/*
 * Gr”áe von XbpStatic und enthaltenen XBPs „ndern
 */
METHOD XbpPreview:setSize( aSize )
//24.03.2008 18:06 geREMt   LOCAL nV := (AppDesktop():currentSize()[1])/800  
//####   aSize[2] := IIf( ::Orient=2, (aSize[1]-16*nH)/1.414+16*nH, (aSize[1]-16*nV)*1.414+16*nV )

   ::xbpStatic:setSize( aSize )
   aSize := ::currentSize()

   ::oPagePos:setPos ( { 0, 0 } )
   ::oPagePos:setSize( { 40*nH, 16*nV } )
   ::oPrevPage:setPos ( { 40*nH, 0 } )
   ::oPrevPage:setSize( { 20*nH, 16*nV } )
   ::oNextPage:setPos ( { 60*nH, 0 } )
   ::oNextPage:setSize( { 20*nH, 16*nV } )
   ::oZoomG:setPos ( { aSize[1]-16*nH, aSize[2]-20*nV } )
   ::oZoomG:setSize( { 16*nH, 20*nV } )
   ::oZoomK:setPos ( { aSize[1]-16*nH, aSize[2]-40*nV } )
   ::oZoomK:setSize( { 16*nH, 20*nV } )

   ::hScroll:setPos ( { 80*nH, 0 } )
   ::hScroll:setSize( { aSize[1]-16*nH-80*nH, 16*nV } )
   ::vScroll:setPos ( { aSize[1]-16*nH, 16*nV } )
   ::vScroll:setSize( { 16*nH, aSize[2]-16*nV-40*nV } )
   ::oSquare:setPos ( { aSize[1]-16*nH,  0 } )
   ::oSquare:setSize( { 16*nH, 16*nV } )
   ::oView  :setPos ( { 0 , 16*nV } )
   ::oView  :setSize( { aSize[1]-16*nH, aSize[2]-16*nV } )

RETURN self



/*
 * Horizontal scrollen
 */
//METHOD XbpPreview:hScroll( mp1 )
METHOD XbpPreview:hScroll( mp1, mp2 )
   LOCAL nScrollPos := mp1[1]
   LOCAL nCommand   := mp1[2]
   LOCAL nScroll
   DEFAULT mp2 TO .F.

   IF (nScrollPos == 0                               .AND. ;
       ::hScroll:getData() == 0)                     .OR.  ;
      (nScrollPos == ::hScroll:setRange()[2]         .AND. ;
       ::hScroll:getData() == ::hScroll:setRange()[2] )
       RETURN self
   ENDIF

   DO CASE
   CASE nCommand == XBPSB_PREVPOS
      nScroll = ::hScroll:getData() - IIf( mp2, ::hScroll:setScrollBoxSize()/10, ::hScroll:setScrollBoxSize())
      ::hScroll:setData( Max(nScroll, 0) )
      ::setOrigin( ::hScroll:getData(), ::vScroll:getData() )
   CASE nCommand == XBPSB_NEXTPOS
      nScroll = ::hScroll:getData() + IIf( mp2, ::hScroll:setScrollBoxSize()/10, ::hScroll:setScrollBoxSize())
      ::hScroll:setData( Min(nScroll, ::hScroll:setRange()[2]) )
      ::setOrigin( ::hScroll:getData(), ::vScroll:getData() )
   CASE nCommand == XBPSB_PREVPAGE
      ::hScroll:setData( nScrollPos )
      ::setOrigin( ::hScroll:getData(), ::vScroll:getData() )
   CASE nCommand == XBPSB_NEXTPAGE
      ::hScroll:setData( nScrollPos )
      ::setOrigin( ::hScroll:getData(), ::vScroll:getData() )
   CASE nCommand == XBPSB_ENDTRACK
      ::hScroll:setData( nScrollPos )
      ::setOrigin( ::hScroll:getData(), ::vScroll:getData() )
   ENDCASE

RETURN self



/*
 * Vertikal scrollen
 */
//METHOD XbpPreview:vScroll( mp1 )
METHOD XbpPreview:vScroll( mp1, mp2 )
   LOCAL nScrollPos := mp1[1]
   LOCAL nCommand   := mp1[2]
   LOCAL nScroll
   DEFAULT mp2 TO .F.

   IF (nScrollPos == 0                               .AND. ;
       ::vScroll:getData() == 0)                     .OR.  ;
      (nScrollPos == ::vScroll:setRange()[2]         .AND. ;
       ::vScroll:getData() == ::vScroll:setRange()[2] )
       RETURN self
   ENDIF

   DO CASE
   CASE nCommand == XBPSB_PREVPOS
      nScroll = ::vScroll:getData() - IIf( mp2, ::vScroll:setScrollBoxSize()/10, ::vScroll:setScrollBoxSize())
      ::vScroll:setData( Max(nScroll, 0) )
      ::setOrigin( ::hScroll:getData(), ::vScroll:getData() )
   CASE nCommand == XBPSB_NEXTPOS
      nScroll = ::vScroll:getData() + IIf( mp2, ::vScroll:setScrollBoxSize()/10, ::vScroll:setScrollBoxSize())
      ::vScroll:setData( Min(nScroll, ::vScroll:setRange()[2]) )
      ::setOrigin( ::hScroll:getData(), ::vScroll:getData() )
   CASE nCommand == XBPSB_PREVPAGE
      ::vScroll:setData( nScrollPos )
      ::setOrigin( ::hScroll:getData(), ::vScroll:getData() )
   CASE nCommand == XBPSB_NEXTPAGE
      ::vScroll:setData( nScrollPos )
      ::setOrigin( ::hScroll:getData(), ::vScroll:getData() )
   CASE nCommand == XBPSB_ENDTRACK
      ::vScroll:setData( nScrollPos )
      ::setOrigin( ::hScroll:getData(), ::vScroll:getData() )
   ENDCASE

RETURN self



/*
 * Ursprung vom Viewport setzen (nach Scrollen)
 */
METHOD XbpPreview:setOrigin( nX, nY )
   LOCAL aSize       := ::oView:drawingArea:currentSize()
   LOCAL nViewWidth  := aSize[1]
   LOCAL nViewHeight := aSize[2]
   LOCAL nZoomWidth  := aSize[1] * IIf(::orient=1,1,1.41) * ::zoomFactor   //17.08.2006 21:00
   LOCAL nZoomHeight := aSize[2] / IIf(::orient=1,1,1.41) * ::zoomFactor   //17.08.2006 21:00

   // X Ursprung ist immer <= 0
   nX := - Abs( nX )

   IF nZoomWidth <= nViewWidth
      nX := 0
   ELSEIF nViewWidth - nX >= nZoomWidth
      nX := nViewWidth - nZoomWidth
   ENDIF

   ::aViewPort[1] := nX
   ::aViewPort[3] := nX + nZoomWidth

   // Y Ursprung ist immer <= 0
   // Es muá die Differenz zwischen Gesamth”he und
   // sichtbarem Bereich bercksichtigt werden
   nY := Abs( nY ) - ( nZoomHeight - nViewHeight )

   IF nY > 0 .OR. nZoomHeight <= nViewHeight
      nY := 0
   ELSEIF nViewHeight - nY >= nZoomHeight
      nY := nViewHeight - nZoomHeight
   ENDIF

   ::aViewPort[2] := nY
   ::aViewPort[4] := nY + nZoomHeight

   ::setViewPort( ::aViewPort )
   ::drawPage()

RETURN self



/*
 * Gr”áe der ScrollBox und Range fr beide Scrollbars berechnen
 */
METHOD XbpPreview:calcScrollBox()
   LOCAL aSize       := ::oView:drawingArea:currentSize()
   LOCAL nViewWidth  := aSize[1]
   LOCAL nViewHeight := aSize[2]
   LOCAL nZoomWidth  := aSize[1] * IIf(::orient=1,1,1.41) * ::zoomFactor   //17.08.2006 21:00
   LOCAL nZoomHeight := aSize[2] / IIf(::orient=1,1,1.41) * ::zoomFactor   //17.08.2006 21:00

   // Werte fr horizontalen Scrollbar berechnen
   ::hScroll:setRange( { 0, Int(nZoomWidth - nViewWidth) } )
   IF nZoomWidth > nViewWidth
      ::hScroll:setScrollBoxSize( (nZoomWidth-nViewWidth) * (nViewWidth/nZoomWidth) )
   ELSE
      ::hScroll:setScrollBoxSize( nViewWidth )
   ENDIF

   // Werte fr vertikalen Scrollbar berechnen
   ::vScroll:setRange( { 0, Int(nZoomHeight - nViewHeight) } )
   IF nZoomHeight > nViewHeight
      ::vScroll:setScrollBoxSize( (nZoomHeight-nViewHeight) * (nViewHeight/nZoomHeight) )
   ELSE
      ::vScroll:setScrollBoxSize( nViewHeight )
   ENDIF

RETURN self



/*
 * Viewport zoomen
 */
METHOD XbpPreview:zoom( nZoomFactor, nZ2, nZ3 )    //24.01.2008 12:54 nZ2/3 - erh„lt die Lage im Bild
   LOCAL aSize  := ::oView:drawingArea:currentSize()

   DEFAULT nZoomFactor TO ::zoomFactor

   IF ::orient = 1      // 17.08.2006 20:42
      ::zoomFactor := Max( 1, nZoomFactor )
   ELSE
      ::zoomFactor := Max( 0.7, nZoomFactor )
   ENDIF
   // Viewport neu berechnen
   IF ::orient = 1      // 17.08.2006 20:42
      aSize[1] := Int( aSize[1] * nZoomFactor )
      aSize[2] := Int( aSize[2] * nZoomFactor )
   ELSE
      aSize[1] := Int( aSize[1]*1.41 * nZoomFactor )
      aSize[2] := Int( aSize[2]/1.41 * nZoomFactor )
   ENDIF
   ::aViewPort  := {0,0,aSize[1],aSize[2]}
   ::calcScrollBox()
  // damit die Lage der Karte im Bild gleichbleibt:
   IF nZ2 != NIL     //24.01.2008 12:54
      ::hScroll:setData( IIf(ValType(nZ2)=="C", &nZ2, nZ2 ) )
   ENDIF   
   IF nZ3 != NIL     //24.01.2008 12:54
      ::vScroll:setData( IIf(ValType(nZ3)=="C", &nZ3, nZ3 ) )
   ENDIF   
   // Ursprung vom Viewport neu definieren
   ::setOrigin( ::hScroll:getData(), ::vScroll:getData() )

RETURN self



/*
 * Presentation Space abfragen
 */
METHOD XbpPreview:presSpace(n)      //+28.10.2008 18:34: n, damit 2.PresSpace abgefragt werden kann
   IF n == 2
      RETURN ::oPresSpaceP
   ENDIF
RETURN ::oPresSpace

//+28.06.2009 13:24 aPageSize abfragen:
METHOD XbpPreview:PageSize()
RETURN ::aPageSize


/*
 * Font abfragen
 */
METHOD XbpPreview:font
RETURN ::oFont



/*
 * Viewport setzen
 */
METHOD XbpPreview:setViewPort( aViewPort )
   LOCAL aOldViewPort := ::oPresSpace:setViewPort()

   IF Valtype( aViewPort ) == "A"
      ::aViewPort := aViewPort
      ::oPresSpace:setViewPort( aViewPort )
   ENDIF
RETURN aOldViewPort

//16.11.2006 08:27 speziell fr Trauerdruck:
METHOD XbpPreview:autoscale(ASize,oBitmap,cHV)
   LOCAL nAspect
   LOCAL aSource := {0,0,Max(oBitmap:xSize,1),Max(oBitmap:ySize,1)}
   LOCAL aTargetUr := IIf(Len(aSize)=2,{1,1,aSize[1]-2,aSize[2]-2},ASize)
   LOCAL aTarget := AClone(aTargetUr)
   DEFAULT cHV TO "22"     //+22.03.2009 21:59 Art der Ausrichtung des Bilds
   
//+29.09.2008 16:17+////////////////////////////////////////////////////////////////////
      IF ValType(oBitmap:cargo) == "A"       //+ dann hat Bitmap seine Gr”áe huckepack (fr 1:1)
         RETURN { aTarget[3]/2 - oBitmap:cargo[1]/2, ;
                  aTarget[4]/2 - oBitmap:cargo[2]/2, ;
                  aTarget[3]/2 - oBitmap:cargo[1]/2 + oBitmap:cargo[1], ;
                  aTarget[4]/2 - oBitmap:cargo[2]/2 + oBitmap:cargo[2]}
      ENDIF
//++////////////////////////////////////////////////////////////////////
      IF ::autoScale
        /*
         * Bitmap wird auf die Gr”áe von ::oCanvas skaliert
         */
         nAspect    := aSource[3] / aSource[4]
//         IF nAspect > 1
         IF nAspect > (aTarget[3]-aTarget[1]) / (aTarget[4]-aTarget[2])   //21.10.2007 14:14
            aTarget[4] := (aTarget[3]-aTarget[1]) / nAspect + aTarget[2]      //[3]! 21.10.2007 13:19
         ELSE
            aTarget[3] := (aTarget[4]-aTarget[2]) * nAspect + aTarget[1]      //[4]! 21.10.2007 13:19
         ENDIF
      ELSE
         aTarget[3] := aSource[3]
         aTarget[4] := aSource[4]
      ENDIF
     /*
      * Bitmap in ::oCanvas horizontal oder vertikal zentrieren
      */
      IF aTarget[3] < aTargetUr[3]
         nAspect := (aTargetUr[3]-aTarget[3])/2
         IF cHV[1] = "1"
         ELSEIF cHV[1] = "2"
            aTarget[1] += nAspect
            aTarget[3] += nAspect
         ELSEIF cHV[1] = "3"
            aTarget[1] += 2*nAspect
            aTarget[3] += 2*nAspect
         ENDIF
      ENDIF
      IF aTarget[4] < aTargetUr[4]
         nAspect := (aTargetUr[4]-aTarget[4])/2
         IF cHV[2] = "3"
         ELSEIF cHV[2] = "2"
            aTarget[2] += nAspect
            aTarget[4] += nAspect
         ELSEIF cHV[2] = "1"
            aTarget[2] += 2*nAspect
            aTarget[4] += 2*nAspect
         ENDIF
      ENDIF
RETURN aTarget

/*
 * Zeichnen der angegebenen Seite
 */
METHOD XbpPreview:drawPage( nPageNo )
   LOCAL oBitmap, aBitRect, aKPos := {0,0}, aKSize := ::aPageSize //30.11.2006 10:45
   LOCAL lMittellinie := .F., lMittellinie2 := .F.  //21.01.2008 18:11
   LOCAL aAttr := ARRAY( GRA_AA_COUNT )
   LOCAL nRBreite, lDoppelR    //+10.12.2008 18:29 Breite des Rahmens im Trauerdruck
   LOCAL cX, cY, nRx := nRy := nTDRand   //+ x,y sind die unbedruckbaren R„nder

   DEFAULT nPageNo TO ::nPagePos

   IF Len(::segments) == 0
      RETURN self

   ENDIF

   IIf(cVD="n",cBriefKopf:="",cBriefKopf:=cBKpf)  //+10.05.2011 20:16
                                               
   // Zeichnung wird durch Ausgabe einer weiá gefllten Box gel”scht
//Urversion:   GraBox( ::oPresSpace, {0,0}, ::aPageSize, GRA_FILL )
//30.11.2006 11:08 zeichnet das Kartenlayout:
   IF IsMemberVar( oEdit, "cDKT" ) .AND. !oEdit:lVorSuch   //+19.02.2009 15:18
      aAttr[GRA_AA_COLOR] := GRA_CLR_PALEGRAY
      aAttr[GRA_AA_BGMIXMODE] := GRA_BGMIX_OVERPAINT
      GraSetAttrArea( ::oPresSpace, aAttr )
      GraBox( ::oPresSpace, {0,0}, {2970,2970}, GRA_FILL )
      aAttr[GRA_AA_COLOR] := GRA_CLR_BACKGROUND
      GraSetAttrArea( ::oPresSpace, aAttr )
    // ::aPageSize wird bei Trauerdruck auf volle Seite gesetzt ->siehe create()
      GraBox( ::oPresSpace, {0,0}, ::aPageSize, GRA_FILL )
      aAttr[GRA_AA_COLOR] := GRA_CLR_WHITE
      GraSetAttrArea( ::oPresSpace, aAttr )
      ::drawPosSize( @aKPos, @aKSize, @lMittelLinie, @lMittelLinie2 )  // 24.01.2008 09:35 Trauerdruck
   ENDIF
   GraBox( ::oPresSpace, aKPos, aKSize, GRA_OUTLINEFILL )
   IF nPageNo != 0 .AND. nPageNo <= ::numPages() .AND. ValType(::segments) == "A" .AND. Len(::segments) >= nPageNo   //+13.11.2012 16:53
      IF ::segments[nPageNo] == NIL .OR. lVorG   // BS-Geometrie besser, wenn lVorG (f09[5]) 08.05.2007 08:37
         ::segments := Eval( ::drawBlock,  ;
                                      ::oPresSpace, ;
                                      nPageNo,      ;
                                      @::nRows, ;
                                      ::segments,  ;
                                      ::aBlatt, ;
                                      ::cCP,    ;
                                      ::aSchrift, ;
                                      ::Orient, ;
                                      "::drawPage" )		//06.12.2022 18:45 drawPage zum Verfolgen, von wo der drawblock aufgerufen wurde
      ENDIF

      IF ::segments[nPageNo] != 0
//
         oBitmap    := XbpBitmap():new():create( ::oPresSpace )
         IF IsMemVar("cGoX") .AND. Upper(AppName())$"LANGEX.EXE-BLEINX.EXE-MUELLX.EXE-NOLTEX.EXE-VELLX.EXE-GUDDX.EXE-BARTX.EXE-SONNEX.EXE"  //+10.09.2009 19:19 Offset fr Formularpositionierung BleinX
            aBitRect      := { aKPos[1]+Val(cGuX), aKPos[2]+Val(cGuY), ;
                           aKSize[1]+Val(cGoX), aKSize[2]+Val(cGoY) }
         ELSE
   //TD>/// damit cBriefKopf bei TD nur im Kartenbereich gezeichnet wird:
            aBitRect      := { aKPos[1], aKPos[2], aKSize[1], aKSize[2] }  //21.10.2007 22:02
         ENDIF
         IF Len(cBriefKopf)>100      //22.07.2006 11:47 >100 heiát:in cGrafik ist die Grafik
            oBitmap:setbuffer( cBriefKopf )          // Bitmap laden
         ELSE                    //22.07.2006 11:47 <100 heiát:in cGrafik ist der GrafikdateiName
            oBitmap:loadFile( cDatver+IIf("."$cBriefKopf,cBriefKopf,cBriefKopf+".BMP") )  // Bitmap laden   18.11.2008 14:57
         ENDIF
         //+11.12.2008 09:11 damit Verstorbenen-Bilder ihre Proportionen behalten:
         IF IsMemberVar( oEdit, "cDKT" ) .AND. Val(oEdit:aDK[2]) <= -200
            ::autoscale( {Val(oEdit:aDK[3]),Val(oEdit:aDK[4]),Val(oEdit:aDK[5]),Val(oEdit:aDK[6])}, ;
                                    oBitmap )
         ENDIF
// nicht fr cBriefkopf  -->  aBitRect := ::autoscale( {::aPageSize[1],::aPageSize[2]}, oBitmap )   //16.11.2006 08:31

         IF "Kachel"$cBriefKopf .OR. ( oBitmap:xsize + oBitmap:ysize < 500 .AND. oBitmap:xsize + oBitmap:ysize > 100 )
            x := oBitmap:xsize ; y := oBitmap:Ysize
            FOR i := aKPos[1] TO aKSize[1] STEP x
               FOR j := aKPos[2] TO aKSize[2] STEP y
                  oBitmap:draw( ::oPresSpace, {i,j,Min(i+x,aKSize[1]),Min(j+y,aKSize[2])},,, ::BitRate )     // 21.02.2006 +09.12.2008 11:43
               NEXT
            NEXT
         ELSE
            oBitmap:draw( ::oPresSpace, aBitRect,,, ::BitRate )     // 21.02.2006
         ENDIF

         IF IsMemberVar( oEdit, "cDKT" ) .AND. Val(oEdit:aDK[1]) <= -100 .AND. Val(oEdit:aDK[1][4]) > 0 .AND. !oEdit:lVorSuch   //+19.02.2009 15:18  //+19.02.2009 10:23
            IF Val(oEdit:aDK[1][3])<5
               nRBreite := (Val(oEdit:aDK[1][3])+1)*10 * nRahmenFaktor  //+13.04.2009 17:04
               lDoppelR := .F.
            ELSE
               nRBreite := (Val(oEdit:aDK[1][3])-4)*10 * nRahmenFaktor  //+13.04.2009 17:04
               lDoppelR := .T.
            ENDIF
            oBitmap    := XbpBitmap():new():create( ::oPresSpace )
            oBitmap:loadFile( cDatver+"Scans2\Hintergrund\Rahmen"+oEdit:aDK[1][4]+".BMP")   // Bitmap laden
            aKPos[1] += nRx; aKPos[2] += nRy; aKSize[1] -= nRx; aKSize[2] -= nRy   //+16.12.2008 18:25
            IF lMittellinie
               oBitmap:draw( ::oPresSpace, {aKPos[1],aKPos[2],aKPos[1]+nRBreite,aKSize[2]},,, ::BitRate )     // 21.02.2006
               oBitmap:draw( ::oPresSpace, {aKPos[1],aKPos[2],aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx,aKPos[2]+nRBreite},,, ::BitRate )     // 21.02.2006
               oBitmap:draw( ::oPresSpace, {aKPos[1],aKSize[2]-nRBreite,aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx,aKSize[2]},,, ::BitRate )     // 21.02.2006
               oBitmap:draw( ::oPresSpace, {aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx-nRBreite,aKPos[2],aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx,aKSize[2]},,, ::BitRate )     // 21.02.2006
               IF lDoppelR
                  oBitmap:draw( ::oPresSpace, {aKPos[1]+nRBreite+20,aKPos[2]+nRBreite+20,aKPos[1]+nRBreite+30,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( ::oPresSpace, {aKPos[1]+nRBreite+20,aKPos[2]+nRBreite+20,aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx-nRBreite-20,aKPos[2]+nRBreite+30},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( ::oPresSpace, {aKPos[1]+nRBreite+20,aKSize[2]-nRBreite-30,aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( ::oPresSpace, {aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx-nRBreite-30,aKPos[2]+nRBreite+20,aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
               ENDIF
               oBitmap:draw( ::oPresSpace, {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx,aKPos[2],aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx+nRBreite,aKSize[2]},,, ::BitRate )     // 21.02.2006
               oBitmap:draw( ::oPresSpace, {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx,aKPos[2],aKSize[1],aKPos[2]+nRBreite},,, ::BitRate )     // 21.02.2006
               oBitmap:draw( ::oPresSpace, {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx,aKSize[2]-nRBreite,aKSize[1],aKSize[2]},,, ::BitRate )     // 21.02.2006
               oBitmap:draw( ::oPresSpace, {aKSize[1]-nRBreite,aKPos[2],aKSize[1],aKSize[2]},,, ::BitRate )     // 21.02.2006
               IF lDoppelR
                  oBitmap:draw( ::oPresSpace, {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx+nRBreite+20,aKPos[2]+nRBreite+20,aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx+nRBreite+30,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( ::oPresSpace, {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx+nRBreite+20,aKPos[2]+nRBreite+20,aKSize[1]-nRBreite-20,aKPos[2]+nRBreite+30},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( ::oPresSpace, {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx+nRBreite+20,aKSize[2]-nRBreite-30,aKSize[1]-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( ::oPresSpace, {aKSize[1]-nRBreite-30,aKPos[2]+nRBreite+20,aKSize[1]-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
               ENDIF
            ELSE
               oBitmap:draw( ::oPresSpace, {aKPos[1],aKPos[2],aKPos[1]+nRBreite,aKSize[2]},,, ::BitRate )     // 21.02.2006
               oBitmap:draw( ::oPresSpace, {aKPos[1],aKPos[2],aKSize[1],aKPos[2]+nRBreite},,, ::BitRate )     // 21.02.2006
               oBitmap:draw( ::oPresSpace, {aKPos[1],aKSize[2]-nRBreite,aKSize[1],aKSize[2]},,, ::BitRate )     // 21.02.2006
               oBitmap:draw( ::oPresSpace, {aKSize[1]-nRBreite,aKPos[2],aKSize[1],aKSize[2]},,, ::BitRate )     // 21.02.2006
               IF lDoppelR
                  oBitmap:draw( ::oPresSpace, {aKPos[1]+nRBreite+20,aKPos[2]+nRBreite+20,aKPos[1]+nRBreite+30,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( ::oPresSpace, {aKPos[1]+nRBreite+20,aKPos[2]+nRBreite+20,aKSize[1]-nRBreite-20,aKPos[2]+nRBreite+30},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( ::oPresSpace, {aKPos[1]+nRBreite+20,aKSize[2]-nRBreite-30,aKSize[1]-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( ::oPresSpace, {aKSize[1]-nRBreite-30,aKPos[2]+nRBreite+20,aKSize[1]-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
               ENDIF
            ENDIF
         ENDIF
         IIf(lMittellinie,GraLine( ::oPresSpace, ;
                  {aKPos[1]+(aKSize[1]-aKPos[1])/2,aKPos[2]}, {aKPos[1]+(aKSize[1]-aKPos[1])/2,aKSize[2]} ), )
         IIf(lMittellinie2,GraLine( ::oPresSpace, ;
                  {aKPos[1],aKPos[2]+(aKSize[2]-aKPos[2])/2}, {aKSize[1],aKPos[2]+(aKSize[2]-aKPos[2])/2} ), )
         //+15.02.2009 09:17 zeichnet die Umrisse der Fotos:
         IF IsMemberVar( oEdit, "aFK" ) .AND. Val(oEdit:aFK[1,4]) > 5 .AND. !oEdit:lVorSuch   //+19.02.2009 15:18
            FOR i := 1 TO Len(oEdit:aFK)
               IF Val(oEdit:aFK[i,4]) > 5     
                  GraLine( ::oPresSpace, {VAL(oEdit:aFK[i,2]),VAL(oEdit:aFK[i,3])}, {VAL(oEdit:aFK[i,2]),VAL(oEdit:aFK[i,5])} )
                  GraLine( ::oPresSpace, {VAL(oEdit:aFK[i,2]),VAL(oEdit:aFK[i,3])}, {VAL(oEdit:aFK[i,4]),VAL(oEdit:aFK[i,3])} )
                  GraLine( ::oPresSpace, {VAL(oEdit:aFK[i,2]),VAL(oEdit:aFK[i,5])}, {VAL(oEdit:aFK[i,4]),VAL(oEdit:aFK[i,5])} )
                  GraLine( ::oPresSpace, {VAL(oEdit:aFK[i,4]),VAL(oEdit:aFK[i,3])}, {VAL(oEdit:aFK[i,4]),VAL(oEdit:aFK[i,5])} )
               ENDIF
            NEXT
            //+18.10.2009 19:06 Position des Symbols bei TextKarten:
            IF "BRF"$Upper(oEdit:aDK[64])
               aAttr := ARRAY( GRA_AL_COUNT )
               aAttr[GRA_AL_TYPE] := GRA_LINETYPE_DOT
               GraSetAttrLine( ::oPresSpace, aAttr )
               GraLine( ::oPresSpace, {VAL(oEdit:aDK[3])+VAL(oEdit:aDK[7]),VAL(oEdit:aDK[4])+VAL(oEdit:aDK[8])}, {VAL(oEdit:aDK[3])+VAL(oEdit:aDK[7]),VAL(oEdit:aDK[6])+VAL(oEdit:aDK[8])} )
               GraLine( ::oPresSpace, {VAL(oEdit:aDK[3])+VAL(oEdit:aDK[7]),VAL(oEdit:aDK[4])+VAL(oEdit:aDK[8])}, {VAL(oEdit:aDK[5])+VAL(oEdit:aDK[7]),VAL(oEdit:aDK[4])+VAL(oEdit:aDK[8])} )
               GraLine( ::oPresSpace, {VAL(oEdit:aDK[3])+VAL(oEdit:aDK[7]),VAL(oEdit:aDK[6])+VAL(oEdit:aDK[8])}, {VAL(oEdit:aDK[5])+VAL(oEdit:aDK[7]),VAL(oEdit:aDK[6])+VAL(oEdit:aDK[8])} )
               GraLine( ::oPresSpace, {VAL(oEdit:aDK[5])+VAL(oEdit:aDK[7]),VAL(oEdit:aDK[4])+VAL(oEdit:aDK[8])}, {VAL(oEdit:aDK[5])+VAL(oEdit:aDK[7]),VAL(oEdit:aDK[6])+VAL(oEdit:aDK[8])} )
               aAttr[GRA_AL_TYPE] := GRA_LINETYPE_SOLID
               GraSetAttrLine( ::oPresSpace, aAttr )
            ENDIF
         ENDIF

         GraSegDraw( ::presSpace(), ::segments[nPageNo] )
      ENDIF
   ENDIF
RETURN self


/*
 * Speichern der angegebenen Seite     30.10.2008 10:00
 * cBild wird per Referenz bergeben und vom aufrufenden Programm gespeichert
 */
METHOD XbpPreview:savePage( nPageNo, cBild, cFileName, nZoom )    //+05.06.2009 18:20 nZoom
   LOCAL oBitmap, aBitRect, aVP  //02.10.2006 17:07 aVP = Viewport
   LOCAL aKPos := {0,0}, aKSize := IIf(Upper(AppName())$"NOLTEX.EXE", {2100,2970},::aPageSize) //09.09.2023 21:24
   LOCAL lMittellinie := .F., lMittellinie2 := .F.  //30.01.2008 16:15
   LOCAL cTime := Time()      //+29.10.2008 11:48
//+ ist doch schon PRIVATE   LOCAL l180 := IIf( ::Orient>2, .T., .F. )   //+23.11.2008 16:39 fr gedrehten Ausdruck 3,4 statt 1,2
   LOCAL cX, cY, nRx := nRy := nTDRand   //+ x,y sind die unbedruckbaren R„nder

   LOCAL aAttr := ARRAY( GRA_AA_COUNT )
   LOCAL nSegment
//   LOCAL aPrinterPS
   LOCAL aPaper
   LOCAL aFont
   LOCAL i := 0, j := 0
   LOCAL loPS //:= XbpPresSpace():New():Create( ::printer, ::aPageSize, GRA_PU_LOMETRIC )
//   LOCAL dummy2 := GraSegDrawMode( loPS, GRA_DM_DRAWANDRETAIN )
   LOCAL aPrinterPS //:= { loPS, PrinterPS(cDruckerName,::Orient) }
   LOCAL loBmp //:= XbpBitmap():New():Create(aPrinterPS[1])

//	nSegment := GraSegOpen( aPrinterPS[1], GRA_SEG_MODIFIABLE )
   aPaper := PrinterPS(cDruckerName,::Orient):DEVICE():paperSize()
//         aPaper := {2100,2970,50,50,2050,2920}	//+04.06.2019 20:55

//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvTEST
			loPS := XbpPresSpace():New():Create(  ::oView:drawingArea:winDevice() , ::aPageSize, GRA_PU_LOMETRIC )
   // Presentation Space mit Window Device Context verknpfen
			aPrinterPS := { loPS, PrinterPS(cDruckerName,::Orient) }
			GraSegDrawMode( aPrinterPS[1], GRA_DM_DRAWANDRETAIN )
								loBmp := XbpBitmap():New():Create(aPrinterPS[1])
			               loBMP:PresSpace(aPrinterPS[1])    // Bind the presentation space to the BMP
								loBmp:Make( aPaper[1], aPaper[2],,24 )  // Set the size that you want it to be.
			nSegment := GraSegOpen( aPrinterPS[1], GRA_SEG_MODIFIABLE )
         aAttr[GRA_AA_COLOR] := GRA_CLR_WHITE
         aAttr[GRA_AA_BACKCOLOR] := GRA_CLR_BLACK
         GraSetAttrArea( aPrinterPS[1], aAttr )
         GraBox( aPrinterPS[1], {0,0}, {aPaper[1],aPaper[2]}, GRA_OUTLINEFILL )
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^			
	   aFont := { XbpFont():new(aPrinterPS[1]), XbpFont():new(aPrinterPS[2]) }
	   aPrinterPS[1]:cargo := self   //+24.08.2010 17:50

   DEFAULT nPageNo TO ::nPagePos
   DEFAULT cFilename TO StrX(1->auftrnr,6) + SubStr(cdru,3) + ;
                           IIf("BL_ALB"$Upper(cdru),"-"+Trim(cTkurz0),"") + "-"+DtoS(DATE()) + "-" + ;
                           SubStr(cTime,1,2) + SubStr(cTime,4,2) + SubStr(cTime,7,2)+".JPG"   //+29.10.2008 11:51
			
   IF Len(::segments) == 0    //+ wenn schon garnichts in der Vorschau ist
      RETURN self
   ENDIF
   IF !Upper(cDru)$"BL_TERM-BL_BRF0-BL_BRF1-BL_BRF2-BL_FOTO-BL_KAS-BL_KAST-BL_KASK-BL_KATX"	//+27.06.2020 11:48 damit bei Trauerdruck der Briefkopf nicht gedruckt wird
		::ParUpdate()		//+13.07.2019 09:01 damit die folgenden Zeilen Briefkopf/Formular mitdrucken bei ::savepage -> Mail
	//12.07.2019 19:03 geremt erstmal   IIf(cVD="n",cBriefKopf:="",cBriefKopf:=cBKpf)  //+10.05.2011 20:16
		IIf(Upper(AppName())$"NOLTEX.EXE-MUELLX.EXE-BLEINX.EXE-KLUCKX.EXE-SONNEX.EXE-VELLX.EXE" .AND. Len(cVD)>0 .AND. cVD[1]$"jbn", cVD := "j",)	//+12.07.2019 19:06
		IIf(Upper(AppName())$"NOLTEX.EXE-MUELLX.EXE-BLEINX.EXE-KLUCKX.EXE-SONNEX.EXE-VELLX.EXE" .AND. Len(cBriefKopf)>0 .AND. cBriefKopf[1]$"j_n", cBriefKopf := "_bl_fbk",)	//+09.07.2019 11:58
	ENDIF
		                                               
   GraSegDrawMode( aPrinterPS[1], GRA_DM_RETAIN )
      //+ Seite zuerst weiá machen: (bei Trauerdruck A4-Seite:grau und Karte:weiá)
      IF IsMemberVar( oEdit, "cDKT" ) .AND. !oEdit:lVorSuch  // = Trauerdruck
//////         //+ Symbol-Offset retten und neu setzen:
//////         cX := cGOx ; cY := cGOy            //+15.12.2008 19:00
//////         cGOx := Str(Val(cGOx)+nTDGeoX,4)   //+15.12.2008 19:14
//////         cGOy := Str(Val(cGOy)+nTDGeoY,4)   //+15.12.2008 19:00
         //+ zwar PUBLICs, sollen aber nur fr printpage() wirken:
//////         ::drawPosSize( @aKPos, @aKSize, @lMittelLinie, @lMittelLinie2, nTDGeoX, nTDGeoY )      
         ::drawPosSize( @aKPos, @aKSize, @lMittelLinie, @lMittelLinie2 )      

         aAttr[GRA_AA_COLOR] := GRA_CLR_WHITE
         aAttr[GRA_AA_BGMIXMODE] := GRA_BGMIX_OVERPAINT
         GraSetAttrArea( aPrinterPS[1], aAttr )
         GraBox( aPrinterPS[1], {0,0}, {2970,2970}, GRA_FILL )
         aAttr[GRA_AA_COLOR] := GRA_CLR_WHITE
         GraSetAttrArea( aPrinterPS[1], aAttr )
       // ::aPageSize wird bei Trauerdruck auf volle Seite gesetzt ->siehe create()
         GraBox( aPrinterPS[1], {0,0}, ::aPageSize, GRA_OUTLINEFILL )
         aAttr[GRA_AA_COLOR] := GRA_CLR_WHITE
         GraSetAttrArea( aPrinterPS[1], aAttr )
         GraBox( aPrinterPS[1], aKPos, aKSize, GRA_OUTLINEFILL )
      ELSE
         aAttr[GRA_AA_COLOR] := GRA_CLR_WHITE
         GraSetAttrArea( aPrinterPS[1], aAttr )
         IF Upper(AppName())$"NOLTEX.EXE"		//09.09.2023 21:24
	         GraBox( aPrinterPS[1], {0,0}, {aKSize[1],aKSize[2]}, GRA_OUTLINEFILL )
	      ELSE
	         GraBox( aPrinterPS[1], {0,0}, {::aPageSize[1],::aPageSize[2]}, GRA_OUTLINEFILL )
	      ENDIF
      ENDIF

      //+ Briefkopf kommt bei ::savePage() VOR dem Seiteninhalt:
         oBitmap    := XbpBitmap():new():create( aPrinterPS[1] )
         aBitRect      := { aKPos[1], aKPos[2], aKSize[1], aKSize[2] }  //24.01.2008 09:35
         IF Len(cBriefKopf)>100      //22.07.2006 11:47 >100 heiát:in cGrafik ist die Grafik
            oBitmap:setbuffer( cBriefKopf )          // Bitmap laden
         ELSE                    //22.07.2006 11:47 <50 heiát:in cGrafik ist der GrafikdateiName
            oBitmap:loadFile( cDatver+IIf("."$cBriefKopf,cBriefKopf,cBriefKopf+".BMP") )  // Bitmap laden   18.11.2008 14:58
         ENDIF

         IF "Kachel"$cBriefKopf .OR. ( oBitmap:xsize + oBitmap:ysize < 500 .AND. oBitmap:xsize + oBitmap:ysize > 100 )
            x := oBitmap:xsize ; y := oBitmap:Ysize
            FOR i := aKPos[1] TO aKSize[1] STEP x
               FOR j := aKPos[2] TO aKSize[2] STEP y
                  oBitmap:draw( aPrinterPS[1], {i,j,Min(i+x,aKSize[1]),Min(j+y,aKSize[2])},,, ::BitRate )     // 21.02.2006 +09.12.2008 11:43
               NEXT
            NEXT
         ELSE
            oBitmap:draw( aPrinterPS[1], aBitRect,,, ::BitRate )
         ENDIF

         //+ auch die R„nder kommen vor dem Inhalt:
         IF IsMemberVar( oEdit, "cDKT" ) .AND. Val(oEdit:aDK[1]) <= -100 .AND. Val(oEdit:aDK[1][4]) > 0 .AND. !oEdit:lVorSuch
            IF Val(oEdit:aDK[1][3])<5
               nRBreite := (Val(oEdit:aDK[1][3])+1)*10 * nRahmenFaktor  //+13.04.2009 17:04
               lDoppelR := .F.
            ELSE
               nRBreite := (Val(oEdit:aDK[1][3])-4)*10 * nRahmenFaktor  //+13.04.2009 17:04
               lDoppelR := .T.
            ENDIF
            oBitmap    := XbpBitmap():new():create( aPrinterPS[1] )
            oBitmap:loadFile( cDatver+"Scans2\Hintergrund\Rahmen"+oEdit:aDK[1][4]+".BMP")   // Bitmap laden
            aKPos[1] += nRx; aKPos[2] += nRy; aKSize[1] -= nRx; aKSize[2] -= nRy   //+16.12.2008 18:25
            IF lMittellinie
               oBitmap:draw( aPrinterPS[1], {aKPos[1],aKPos[2],aKPos[1]+nRBreite,aKSize[2]},,, ::BitRate )     // 21.02.2006
               oBitmap:draw( aPrinterPS[1], {aKPos[1],aKPos[2],aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx,aKPos[2]+nRBreite},,, ::BitRate )     // 21.02.2006
               oBitmap:draw( aPrinterPS[1], {aKPos[1],aKSize[2]-nRBreite,aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx,aKSize[2]},,, ::BitRate )     // 21.02.2006
               oBitmap:draw( aPrinterPS[1], {aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx-nRBreite,aKPos[2],aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx,aKSize[2]},,, ::BitRate )     // 21.02.2006
               IF lDoppelR
                  oBitmap:draw( aPrinterPS[1], {aKPos[1]+nRBreite+20,aKPos[2]+nRBreite+20,aKPos[1]+nRBreite+30,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( aPrinterPS[1], {aKPos[1]+nRBreite+20,aKPos[2]+nRBreite+20,aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx-nRBreite-20,aKPos[2]+nRBreite+30},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( aPrinterPS[1], {aKPos[1]+nRBreite+20,aKSize[2]-nRBreite-30,aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( aPrinterPS[1], {aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx-nRBreite-30,aKPos[2]+nRBreite+20,aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
               ENDIF
               oBitmap:draw( aPrinterPS[1], {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx,aKPos[2],aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx+nRBreite,aKSize[2]},,, ::BitRate )     // 21.02.2006
               oBitmap:draw( aPrinterPS[1], {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx,aKPos[2],aKSize[1],aKPos[2]+nRBreite},,, ::BitRate )     // 21.02.2006
               oBitmap:draw( aPrinterPS[1], {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx,aKSize[2]-nRBreite,aKSize[1],aKSize[2]},,, ::BitRate )     // 21.02.2006
               oBitmap:draw( aPrinterPS[1], {aKSize[1]-nRBreite,aKPos[2],aKSize[1],aKSize[2]},,, ::BitRate )     // 21.02.2006
               IF lDoppelR
                  oBitmap:draw( aPrinterPS[1], {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx+nRBreite+20,aKPos[2]+nRBreite+20,aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx+nRBreite+30,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( aPrinterPS[1], {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx+nRBreite+20,aKPos[2]+nRBreite+20,aKSize[1]-nRBreite-20,aKPos[2]+nRBreite+30},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( aPrinterPS[1], {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx+nRBreite+20,aKSize[2]-nRBreite-30,aKSize[1]-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( aPrinterPS[1], {aKSize[1]-nRBreite-30,aKPos[2]+nRBreite+20,aKSize[1]-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
               ENDIF
            ELSE
               oBitmap:draw( aPrinterPS[1], {aKPos[1],aKPos[2],aKPos[1]+nRBreite,aKSize[2]},,, ::BitRate )     // 21.02.2006
               oBitmap:draw( aPrinterPS[1], {aKPos[1],aKPos[2],aKSize[1],aKPos[2]+nRBreite},,, ::BitRate )     // 21.02.2006
               oBitmap:draw( aPrinterPS[1], {aKPos[1],aKSize[2]-nRBreite,aKSize[1],aKSize[2]},,, ::BitRate )     // 21.02.2006
               oBitmap:draw( aPrinterPS[1], {aKSize[1]-nRBreite,aKPos[2],aKSize[1],aKSize[2]},,, ::BitRate )     // 21.02.2006
               IF lDoppelR
                  oBitmap:draw( aPrinterPS[1], {aKPos[1]+nRBreite+20,aKPos[2]+nRBreite+20,aKPos[1]+nRBreite+30,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( aPrinterPS[1], {aKPos[1]+nRBreite+20,aKPos[2]+nRBreite+20,aKSize[1]-nRBreite-20,aKPos[2]+nRBreite+30},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( aPrinterPS[1], {aKPos[1]+nRBreite+20,aKSize[2]-nRBreite-30,aKSize[1]-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( aPrinterPS[1], {aKSize[1]-nRBreite-30,aKPos[2]+nRBreite+20,aKSize[1]-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
               ENDIF
            ENDIF
         ENDIF
      //++//+begin+///////////////////////////////////////////////////////////////
//         aPrinterPS := { loPS, PrinterPS(cDruckerName,::Orient) } //+23.11.2008 16:52
//         aPaper := {2100,2970,50,50,2050,2920}	//+04.06.2019 20:55
////         aPaper := aPrinterPS[2]:DEVICE():paperSize() //, aPoSZ := {0,0}   20.09.2006 17:43
//         aFont := { XbpFont():new(aPrinterPS[1]), XbpFont():new(aPrinterPS[2]) }

//         aAttr[GRA_AA_COLOR] := GRA_CLR_WHITE
//         GraSetAttrArea( aPrinterPS[1], aAttr )
//         GraBox( aPrinterPS[1], {0,0}, {::aPageSize[1],::aPageSize[2]}, GRA_OUTLINEFILL )

      /* stattdessen:
      //   IF nPageNo != 0 .AND. nPageNo <= ::numPages()
      //      IF ::segmentsP[nPageNo] == NIL .OR. "/"$cDup    //01.03.2008 21:34
               ::segmentsP := Eval( ::drawBlock,  ;
                                            loPS, ;
                                            nPageNo,      ;
                                            @::nRows, ;
                                            ::segmentsP,  ;
                                            ::aBlatt, ;
                                            ::cCP,    ;
                                            ::aSchrift, ;
                                            ::Orient )
      //      ENDIF
      */
         //+ hier wird die VorschauAusgabe() nachgebaut:
//         nSegment := GraSegOpen( aPrinterPS[1] )
         aPoSZ[1] := 0 ; aPoSZ[2] := 0 // 20.09.2006 17:43  aPoSZ ist Public
         aFont[1]:CREATE("24.COURIER NEW")
         aFont[2]:CREATE("24.COURIER NEW")
         ASize( ::segmentsP, 0 )
         nAnz := IIf( !Empty(cAnz), Val( cAnz ), nAnzahl )
         ////******************************
         // 22.01.2022 Bemerkung: wenn nFSave=1, dann ist die Schriftgr”áe fr die Email-PDFs zu klein
         //	Der optimale Faktor scheint 2.8 zu sein und wird in FDRG() gebraucht.
         // Mich irritiert heute (22.01.2022), wieso ich damals die EPSON-Drucker ausgenommen habe
         // dabei ist es per Definition, dass 0,353 mm 1 pt sind und somit 1 mm = 2,835 pt
         // bei der Ausgabe in eine Grafik-Datei muss daher der Umrechnungsfaktor 2,8... verwendet werden:
//         PRIVATE nFSave := 2.835	//IIf("EPSON"$Upper(cDruckername),1,2.8)  //Int(loPS:setViewPort()[4]/::oPresSpace:setViewPort()[4])
         PRIVATE nFSave := IIf("EPSON"$Upper(cDruckername),1,2.8)  //Int(loPS:setViewPort()[4]/::oPresSpace:setViewPort()[4])
         ////*****************************
//         PRIVATE nFSave := Round(loPS:setViewPort()[4]/::oPresSpace:setViewPort()[4],1)
         ////*****************************
//03.06.2019 11:10         Blatt_Aufbau( aPrinterPS, aFont, aPaper, aPoSZ, ::aSchrift, ::aBlatt, ::cCP, ::SegmentsP, @nSegment   )
         Blatt_Aufbau( aPrinterPS, aFont, aPaper, aPoSZ, ::aSchrift, ::aBlatt, ::cCP, @::SegmentsP, @nSegment, loBMP, @cFileName )	//03.06.2019 11:11
         GraSegClose( aPrinterPS[1] )
         AAdd( ::SegmentsP, nSegment )
      // aSeitZ[1]=len(aSegments) / aSeitZ[2]=aPoSZ / aSeitZ[3]=TEXT / aSeitZ[4]=FONT :
         IF !Empty( aSeitZ )     // GesamtSeitenZahl - Seitenzahlen bei Statistik-Drucken
            FOR i := 1 TO j := aSeitZ[1]  // aSeitZ[1] = Anzahl Segmente
               GraSegOpen( aPrinterPS[1], GRA_SEG_MODIFIABLE, ::SegmentsP[i] )
               FdrG( aPrinterPS, aFont, aPaper, AClone(aSeitZ[2]), ;
                              Trim( aSeitZ[3] ), aSeitZ[4], aSchrift )
               GraSegClose( aPrinterPS[1] )
            NEXT
         ENDIF
      //++//+end+///////////////////////////////////////////////////////////////

         //+ damit die Mittellinien in der Grafik deutlich zu sehen sind:
         IIf(lMittellinie,GraLine( aPrinterPS[1], ;
                  {aKPos[1]+(aKSize[1]-aKPos[1])/2,aKPos[2]}, {aKPos[1]+(aKSize[1]-aKPos[1])/2,aKSize[2]} ), )
         IIf(lMittellinie2,GraLine( aPrinterPS[1], ;
                  {aKPos[1],aKPos[2]+(aKSize[2]-aKPos[2])/2}, {aKSize[1],aKPos[2]+(aKSize[2]-aKPos[2])/2} ), )

         //+19.02.2009 10:53 zeichnet die Umrisse der Fotos:
         IF IsMemberVar( oEdit, "aFK" ) .AND. Val(oEdit:aFK[1,4]) > 5 .AND. !oEdit:lVorSuch .AND. !"karten"$cFilename  //+11.05.2009 11:42 wenn als Karte abgespeichert wird
            FOR i := 1 TO Len(oEdit:aFK)
               IF Val(oEdit:aFK[i,4]) > 5     
                  GraLine( aPrinterPS[1], {VAL(oEdit:aFK[i,2]),VAL(oEdit:aFK[i,3])}, {VAL(oEdit:aFK[i,2]),VAL(oEdit:aFK[i,5])} )
                  GraLine( aPrinterPS[1], {VAL(oEdit:aFK[i,2]),VAL(oEdit:aFK[i,3])}, {VAL(oEdit:aFK[i,4]),VAL(oEdit:aFK[i,3])} )
                  GraLine( aPrinterPS[1], {VAL(oEdit:aFK[i,2]),VAL(oEdit:aFK[i,5])}, {VAL(oEdit:aFK[i,4]),VAL(oEdit:aFK[i,5])} )
                  GraLine( aPrinterPS[1], {VAL(oEdit:aFK[i,4]),VAL(oEdit:aFK[i,3])}, {VAL(oEdit:aFK[i,4]),VAL(oEdit:aFK[i,5])} )
               ENDIF
            NEXT
         ENDIF
                                               
      //+ gibts hier eigentlich nicht! (wenn der Ausdruck um 180ø gedreht sein soll:)
//         IF l180     // .T., wenn nOrientierung = 3/4, statt 1/2
//            aVP := loPS:setviewport()          
//            loPS:setviewport( {aVP[3], aVP[4], aVP[1], aVP[2] } )
//         ENDIF                                 
                                               
//         GraSegDraw( ::presSpace(), ::segments[nPageNo] )
////         GraSegDraw( loPS, ::segmentsP[nPageNo] )
         //GraSegDraw( aPrinterPS[2], ::segmentsP[2] )
   IF ValType(cBild) == "C"
      //+23.05.2009 19:24 zus„tzlich als Datei abspeichern
      IF cBild == "S" .AND. "\"$cFilename
         IF !FExists(SubStr(cFilename,1,RAt("\",cFilename)-1),"D")
            RunShell( "/C MD "+SubStr(cFilename,1,RAt("\",cFilename)-1),, .T. )
            DO WHILE !FExists(SubStr(cFilename,1,RAt("\",cFilename)-1),"D")
            ENDDO
         ENDIF
         IF ":"$cFilename
            FErase(cFilename)
            loBmp:SaveFile( cFilename , XBPBMP_FORMAT_JPG, XBPBMP_DEF_COMPRESSION)
         ELSE
            FErase(cDatver+cFilename)        
            loBmp:SaveFile( cDatver+cFilename , XBPBMP_FORMAT_JPG, XBPBMP_DEF_COMPRESSION)
         ENDIF
      ENDIF
      //+23.05.2009 19:24 zus„tzlich als Miniatur-Datei abspeichern
      IF cBild == "S" .AND. "\"$cFilename
         //+ Grafik wird verkleinert und auf A5 beschr„nkt:
//         loBmp := GraSaveScreen( loPS, aKPos, {loBmp:xsize-aKPos[1]*2,loBmp:ysize-aKPos[2]}, 0.2 )
         loBmp := GraSaveScreen( aPrinterPS[1], aKPos, {aKSize[1]-aKPos[1],aKSize[2]-aKPos[2]}, 0.2 )
         cFilename := Stuff(cFilename,RAt("\",cFilename),1,"\M\")
         IF !FExists(SubStr(cFilename,1,RAt("\",cFilename)-1),"D")
            RunShell( "/C MD "+SubStr(cFilename,1,RAt("\",cFilename)-1),, .T. )
            DO WHILE !FExists(SubStr(cFilename,1,RAt("\",cFilename)-1),"D")
            ENDDO
         ENDIF
         IF ":"$cFilename
            FErase(cFilename)
            loBmp:SaveFile( cFilename , XBPBMP_FORMAT_JPG, XBPBMP_DEF_COMPRESSION)
         ELSE
            FErase(cDatver+cFilename)        
            loBmp:SaveFile( cDatver+cFilename , XBPBMP_FORMAT_JPG, XBPBMP_DEF_COMPRESSION)
         ENDIF
      ELSE
         //+ Grafik wird verkleinert:
         loBmp := GraSaveScreen( aPrinterPS[1], {0,0}, {loBmp:xsize,loBmp:ysize}, 0.2 )
      ENDIF
      cBild := loBmp:setbuffer()
      //+ cBild wurde per Ref bergeben und vom aufrufenden Programm in ->bild gespeichert
   ELSEIF ":"$cFilename
      FErase(cFilename)
      loBmp:SaveFile( cFilename , XBPBMP_FORMAT_JPG, XBPBMP_DEF_COMPRESSION)
   ELSEIF ValType(cFilename)=="A" .OR. "\"$cFilename  //08.07.2019 21:09 ValType() //+11.05.2009 09:25 damit das Verzeichnis bestimmbar ist
//     FErase(cDatver+cFilename)        
//     loBmp:SaveFile( cDatver+cFilename , XBPBMP_FORMAT_JPG, XBPBMP_DEF_COMPRESSION)
   ELSE                                        
     FErase(cDatver+"scans\"+cFilename)        
     loBmp:SaveFile( cDatver+"scans\"+cFilename , XBPBMP_FORMAT_JPG, XBPBMP_DEF_COMPRESSION)
   ENDIF                                       
   GraSegDrawMode( aPrinterPS[1], GRA_DM_DRAWANDRETAIN ) //+ berflssig??
   
   //+30.06.2019 13:25 Zusammenfassung der einzelnen Seiten zu einer PDF-Datei
   IF ValType(cFilename) == "A"
   	cFN := cDatver + cFilename[1]
   	FOR i:=2 TO Len(cFilename)
   		cFN += "," + cDatver + cFilename[i]
   	NEXT
   	IF "BL_ALBR"$Upper(cDru)		//+09.01.2020 18:58 wegen bl_albr
	   	cPDFile := cDatver+"\scans\dokumente\"+StrX(1->auftrnr,E)+"\"+cDru+"\" + StrX(1->auftrnr,E) + cDru + "-" + AllTrim(5->verskz) + "-"+Trim(Substr(oEdit:aTxBd[1],2)) + ".PDF"
	   ELSEIF Upper(cDru)=="BL_V"		//+09.01.2020 20:41
	   	cPDFile := cDatver+"\scans\dokumente\"+StrX(1->auftrnr,E)+"\"+cDru+"\" + StrX(1->auftrnr,E) + cDru + "-" + AllTrim(12->verskz) + ".PDF"
	   ELSEIF Upper(cDru)=="BL_BLUM"	//12.09.2020 09:45 damit das auch in ein eigenes BL_BLUM-Verzeichnis geht:
	   	cBlumbest := SubStr(cFileName[1],RAt("\",cFileName[1])+1)
	   	cBlumbest := SubStr(cBlumbest,1,RAt("65536",cBlumbest)-1)
	   	cPDFile := cDatver+"\scans\dokumente\"+StrX(1->auftrnr,E)+"\"+cDru+"\" + cBlumbest + ".PDF"
         IF !FExists(cDatver+"\scans\dokumente\"+StrX(1->auftrnr,E)+"\"+cDru,"D")
            RunShell( "/C MD "+cDatver+"\scans\dokumente\"+StrX(1->auftrnr,E)+"\"+cDru,, .T. )
            IF !FExists(cDatver+"\scans\dokumente\"+StrX(1->auftrnr,E)+"\"+cDru,"D")
            	Sleep(100)
            ENDIF
         ENDIF
	   ELSE
	   	cPDFile := cDatver+"\scans\dokumente\"+StrX(1->auftrnr,E)+"\"+cDru+"\" + StrX(1->auftrnr,E) + cDru + ".PDF"
	   ENDIF
   	RunShell( " " + "/multipdf=(" + cPDFile + "," + cFN + ") /killmesoftly", cDatver+"iview\i_view32.exe", .F. ) 
   ENDIF
RETURN self


//////////
////////////+10.02.2010 08:40 Bild mit einem externen Programm bearbeiten
////////////+ entwickelt fr IrfanView 4.25
//////////METHOD DialogFF:BildExtProg(cExtProg,cBefehl,cFileErg)
//////////   LOCAL cFileNeu := Stuff(oEdit:oView:File,At(".",oEdit:oView:File),0,cFileErg)
//////////   DEFAULT cExtProg TO "c:\Programme\IrfanView\i_view32.exe"
//////////   DEFAULT cBefehl TO "/rotate_r /convert="
//////////   DEFAULT cFileErg TO "-R"
//////////   
//////////   RunShell( oEdit:oView:FILE + " " + cBefehl + cFileNeu, cExtProg, .F. )
//////////   oEdit:oView:FILE := cFileNeu
//////////
//////////RETURN self
//////////
//////////


/*                                             
 * Drucken der angegebenen Seite               
 */                                            
METHOD XbpPreview:printPage( nPageNo )         
   LOCAL oBitmap, aBitRect, aVP  //02.10.2006 17:07 aVP = Viewport
   LOCAL aKPos := {0,0}, aKSize := ::aPageSize //30.01.2008 16:15
   LOCAL lMittellinie := .F., lMittellinie2 := .F.  //30.01.2008 16:15
   LOCAL cTime := Time()      //+29.10.2008 11:48
   LOCAL cX, cY, nRx := nRy := nTDRand   //+ x,y sind die unbedruckbaren R„nder
   LOCAL aMat := GraInitMatrix()             //+15.12.2008 20:36
//   LOCAL oPresSpacePH      := XbpPresSpace():new()
//   oPresSpacePH:create( ::printer, ::aPageSize, GRA_PU_LOMETRIC )
//   oPresSpacePH:setAttrArea( ::aAreaAttr )
//   oPresSpacePH:setViewPort( ::oPresSpaceP:setviewport() )

//   LOCAL cFilename := StrX(1->auftrnr,6) + SubStr(cdru,3) + "-"+DtoS(DATE()) + "-" + ;
//                              SubStr(cTime,1,2) + SubStr(cTime,4,2) + SubStr(cTime,7,2)   //+29.10.2008 11:51
   DEFAULT nPageNo TO ::nPagePos               
                                               
   IF Len(::segmentsP) == 0                    
      RETURN self                              
   ENDIF                                       
   
   IIf(cVD="n",cBriefKopf:="",cBriefKopf:=cBKpf)  //+10.05.2011 20:16
                                               
//+ 16.12.2008 08:47 neue Gestaltung:
//+ 1. Text- und Grafik-Inhalte und 2. Hintergrund+Rahmen
//+ 3. Druck mit GraSegDraw, nachdem die Segmente umgedreht wurden,
//+ damit der Inhalt nach dem Hintergrund gedruckt wird:
   IF nPageNo != 0 .AND. nPageNo <= ::numPages()
         IF IsMemberVar( oEdit, "cDKT" )  // 24.01.2008 09:35 Trauerdruck
            //+ Symbol-Offset retten und neu setzen:
            cX := cGOx ; cY := cGOy            //+15.12.2008 19:00
            cGOx := Str(Val(cGOx)+nTDGeoX,5)   //+15.12.2008 19:14   04.06.2010 22:20 =5
            cGOy := Str(Val(cGOy)+nTDGeoY,5)   //+15.12.2008 19:00   04.06.2010 22:20 =5
            //+ zwar PUBLICs, sollen aber nur fr printpage() wirken:
            ::drawPosSize( @aKPos, @aKSize, @lMittelLinie, @lMittelLinie2, nTDGeoX, nTDGeoY )      
         ENDIF                                    
   //+ Beim ersten Mal werden mit Blatt_Aufbau() der Text und die Grafiken 
   //+ aller Seiten erzeugt :
   //+ Ab dem zweiten Mal wird nur noch erzeugt, wenn die Seite fehlt:
      IF ::segmentsP[nPageNo] == NIL .OR. "/"$cDup    //01.03.2008 21:34
         ::segmentsP := Eval( ::drawBlock,  ;  
                                      ::oPresSpaceP, ;
                                      nPageNo,      ;
                                      @::nRows, ;
                                      ::segmentsP,  ;
                                      ::aBlatt, ;
                                      ::cCP,    ;
                                      ::aSchrift, ;
                                      ::Orient, ;
                                      "::printPage" )		//06.12.2022 18:45 printPage zum Verfolgen, von wo der drawblock aufgerufen wurde
         ASize(::segmentsPH,Len(::segmentsP))   //+16.12.2008 14:39 Hintergrund
      ENDIF                                    

      //+ Hintergrundsegment erzeugen und fllen: 
      IF Len(::segmentsPH) >= nPageNo .AND. ;      //+22.02.2010 16:34
               ::segmentsPH[nPageNo] == NIL .OR. "/"$cDup    //01.03.2008 21:34
         //+ 16.12.2008 14:17 GRA_DM_RETAIN muSS(!) sein, weil sonst bei Rotate
         //+ ZWEI (2) Bilder angezeigt werden, dasjenige beim Aufbau als unteres.
         GraSegDrawMode( ::oPresSpaceP, GRA_DM_RETAIN )
         nHSegment := GraSegOpen( ::oPresSpaceP, GRA_SEG_MODIFIABLE )  //, , ::segmentsP[nPageNo] )
         AAdd(::segmentsPH,nHSegment)
                                                  
         IF ::segmentsP[nPageNo] != 0             
            oBitmap    := XbpBitmap():new():create( ::oPresSpaceP )
//            aBitRect      := { 0, 0, ::aPageSize[1], ::aPageSize[2] }
            IF IsMemVar("cGoX") .AND. Upper(AppName())$"LANGEX.EXE-BLEINX.EXE-MUELLX.EXE-NOLTEX.EXE-VELLX.EXE-GUDDX.EXE-BARTX.EXE-SONNEX.EXE"  //+10.09.2009 19:19 Offset fr Formularpositionierung BleinX
               aBitRect      := { aKPos[1]+Val(cGuX), aKPos[2]+Val(cGuY), ;
                              aKSize[1]+Val(cGoX), aKSize[2]+Val(cGoY) }
            ELSE
      //TD>/// damit cBriefKopf bei TD nur im Kartenbereich gezeichnet wird:
               aBitRect      := { aKPos[1], aKPos[2], aKSize[1], aKSize[2] }  //24.01.2008 09:35
            ENDIF
            IF Len(cBriefKopf)>100      //22.07.2006 11:47 >100 heiát:in cGrafik ist die Grafik
               oBitmap:setbuffer( cBriefKopf )          // Bitmap laden
            ELSE                    //22.07.2006 11:47 <50 heiát:in cGrafik ist der GrafikdateiName
               oBitmap:loadFile( cDatver+IIf("."$cBriefKopf,cBriefKopf,cBriefKopf+".BMP") )  // Bitmap laden   18.11.2008 14:58
            ENDIF                                 
         //+10.12.2008 13:22 Hintergrund als Kachel oder als Grafik:
            IF "Kachel"$cBriefKopf .OR. ( oBitmap:xsize + oBitmap:ysize < 500 .AND. oBitmap:xsize + oBitmap:ysize > 100 )
               x := oBitmap:xsize ; y := oBitmap:Ysize
               FOR i := aKPos[1] TO aKSize[1] STEP x
                  FOR j := aKPos[2] TO aKSize[2] STEP y
                     oBitmap:draw( ::oPresSpaceP, {i,j,Min(i+x,aKSize[1]),Min(j+y,aKSize[2])},,, ::BitRate )     // 21.02.2006 +09.12.2008 11:43
                  NEXT                            
               NEXT                               
            ELSE
//               IF Upper(AppName())$cAc .AND. "PDF"$cDruckerName    //+03.06.2017 20:36
//                  aBitRect[1] += 10
//                  aBitRect[2] += 42
//                  aBitRect[3] -= 10
//                  aBitRect[4] -= 42
//               ENDIF                                  
               oBitmap:draw( ::oPresSpaceP, aBitRect,,, ::BitRate )     // 21.02.2006
            ENDIF                                 
                                                  
            IF IsMemberVar( oEdit, "cDKT" ) .AND. Val(oEdit:aDK[1]) <= -100 .AND. Val(oEdit:aDK[1][4]) > 0 .AND. !oEdit:lVorSuch
               IF Val(oEdit:aDK[1][3])<5          
                  nRBreite := (Val(oEdit:aDK[1][3])+1)*10 * nRahmenFaktor  //+13.04.2009 17:04
                  lDoppelR := .F.                 
               ELSE                               
                  nRBreite := (Val(oEdit:aDK[1][3])-4)*10 * nRahmenFaktor  //+13.04.2009 17:04
                  lDoppelR := .T.                 
               ENDIF                              
               oBitmap:loadFile( cDatver+"Scans2\Hintergrund\Rahmen"+oEdit:aDK[1][4]+".BMP")   // Bitmap laden
               aKPos[1] += nRx; aKPos[2] += nRy; aKSize[1] -= nRx; aKSize[2] -= nRy   //+16.12.2008 18:25
               IF lMittellinie   //+ gefaltete Karte?
                  oBitmap:draw( ::oPresSpaceP, {aKPos[1],aKPos[2],aKPos[1]+nRBreite,aKSize[2]},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( ::oPresSpaceP, {aKPos[1],aKPos[2],aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx,aKPos[2]+nRBreite},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( ::oPresSpaceP, {aKPos[1],aKSize[2]-nRBreite,aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx,aKSize[2]},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( ::oPresSpaceP, {aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx-nRBreite,aKPos[2],aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx,aKSize[2]},,, ::BitRate )     // 21.02.2006
                  IF lDoppelR
                     oBitmap:draw( ::oPresSpaceP, {aKPos[1]+nRBreite+20,aKPos[2]+nRBreite+20,aKPos[1]+nRBreite+30,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                     oBitmap:draw( ::oPresSpaceP, {aKPos[1]+nRBreite+20,aKPos[2]+nRBreite+20,aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx-nRBreite-20,aKPos[2]+nRBreite+30},,, ::BitRate )     // 21.02.2006
                     oBitmap:draw( ::oPresSpaceP, {aKPos[1]+nRBreite+20,aKSize[2]-nRBreite-30,aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                     oBitmap:draw( ::oPresSpaceP, {aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx-nRBreite-30,aKPos[2]+nRBreite+20,aKPos[1]+(aKSize[1]-aKPos[1])/2-nRx-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                  ENDIF
                  oBitmap:draw( ::oPresSpaceP, {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx,aKPos[2],aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx+nRBreite,aKSize[2]},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( ::oPresSpaceP, {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx,aKPos[2],aKSize[1],aKPos[2]+nRBreite},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( ::oPresSpaceP, {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx,aKSize[2]-nRBreite,aKSize[1],aKSize[2]},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( ::oPresSpaceP, {aKSize[1]-nRBreite,aKPos[2],aKSize[1],aKSize[2]},,, ::BitRate )     // 21.02.2006
                  IF lDoppelR
                     oBitmap:draw( ::oPresSpaceP, {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx+nRBreite+20,aKPos[2]+nRBreite+20,aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx+nRBreite+30,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                     oBitmap:draw( ::oPresSpaceP, {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx+nRBreite+20,aKPos[2]+nRBreite+20,aKSize[1]-nRBreite-20,aKPos[2]+nRBreite+30},,, ::BitRate )     // 21.02.2006
                     oBitmap:draw( ::oPresSpaceP, {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRx+nRBreite+20,aKSize[2]-nRBreite-30,aKSize[1]-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                     oBitmap:draw( ::oPresSpaceP, {aKSize[1]-nRBreite-30,aKPos[2]+nRBreite+20,aKSize[1]-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                  ENDIF
//                  oBitmap:draw( ::oPresSpaceP, {aKPos[1],aKPos[2],aKPos[1]+nRBreite,aKSize[2]},,, ::BitRate )     // 21.02.2006
//                  oBitmap:draw( ::oPresSpaceP, {aKPos[1],aKPos[2],aKPos[1]+(aKSize[1]-aKPos[1])/2,aKPos[2]+nRBreite},,, ::BitRate )     // 21.02.2006
//                  oBitmap:draw( ::oPresSpaceP, {aKPos[1],aKSize[2]-nRBreite,aKPos[1]+(aKSize[1]-aKPos[1])/2,aKSize[2]},,, ::BitRate )     // 21.02.2006
//                  oBitmap:draw( ::oPresSpaceP, {aKPos[1]+(aKSize[1]-aKPos[1])/2-nRBreite,aKPos[2],aKPos[1]+(aKSize[1]-aKPos[1])/2,aKSize[2]},,, ::BitRate )     // 21.02.2006
//                  IF lDoppelR                     
//                     oBitmap:draw( ::oPresSpaceP, {aKPos[1]+nRBreite+20,aKPos[2]+nRBreite+20,aKPos[1]+nRBreite+30,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
//                     oBitmap:draw( ::oPresSpaceP, {aKPos[1]+nRBreite+20,aKPos[2]+nRBreite+20,aKPos[1]+(aKSize[1]-aKPos[1])/2-nRBreite-20,aKPos[2]+nRBreite+30},,, ::BitRate )     // 21.02.2006
//                     oBitmap:draw( ::oPresSpaceP, {aKPos[1]+nRBreite+20,aKSize[2]-nRBreite-30,aKPos[1]+(aKSize[1]-aKPos[1])/2-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
//                     oBitmap:draw( ::oPresSpaceP, {aKPos[1]+(aKSize[1]-aKPos[1])/2-nRBreite-30,aKPos[2]+nRBreite+20,aKPos[1]+(aKSize[1]-aKPos[1])/2-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
//                  ENDIF                           
//                  oBitmap:draw( ::oPresSpaceP, {aKPos[1]+(aKSize[1]-aKPos[1])/2,aKPos[2],aKPos[1]+(aKSize[1]-aKPos[1])/2+nRBreite,aKSize[2]},,, ::BitRate )     // 21.02.2006
//                  oBitmap:draw( ::oPresSpaceP, {aKPos[1]+(aKSize[1]-aKPos[1])/2,aKPos[2],aKSize[1],aKPos[2]+nRBreite},,, ::BitRate )     // 21.02.2006
//                  oBitmap:draw( ::oPresSpaceP, {aKPos[1]+(aKSize[1]-aKPos[1])/2,aKSize[2]-nRBreite,aKSize[1],aKSize[2]},,, ::BitRate )     // 21.02.2006
//                  oBitmap:draw( ::oPresSpaceP, {aKSize[1]-nRBreite,aKPos[2],aKSize[1],aKSize[2]},,, ::BitRate )     // 21.02.2006
//                  IF lDoppelR                     
//                     oBitmap:draw( ::oPresSpaceP, {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRBreite+20,aKPos[2]+nRBreite+20,aKPos[1]+(aKSize[1]-aKPos[1])/2+nRBreite+30,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
//                     oBitmap:draw( ::oPresSpaceP, {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRBreite+20,aKPos[2]+nRBreite+20,aKSize[1]-nRBreite-20,aKPos[2]+nRBreite+30},,, ::BitRate )     // 21.02.2006
//                     oBitmap:draw( ::oPresSpaceP, {aKPos[1]+(aKSize[1]-aKPos[1])/2+nRBreite+20,aKSize[2]-nRBreite-30,aKSize[1]-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
//                     oBitmap:draw( ::oPresSpaceP, {aKSize[1]-nRBreite-30,aKPos[2]+nRBreite+20,aKSize[1]-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
//                  ENDIF                           
               ELSE                               
                  oBitmap:draw( ::oPresSpaceP, {aKPos[1],aKPos[2],aKPos[1]+nRBreite,aKSize[2]},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( ::oPresSpaceP, {aKPos[1],aKPos[2],aKSize[1],aKPos[2]+nRBreite},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( ::oPresSpaceP, {aKPos[1],aKSize[2]-nRBreite,aKSize[1],aKSize[2]},,, ::BitRate )     // 21.02.2006
                  oBitmap:draw( ::oPresSpaceP, {aKSize[1]-nRBreite,aKPos[2],aKSize[1],aKSize[2]},,, ::BitRate )     // 21.02.2006
                  IF lDoppelR                     
                     oBitmap:draw( ::oPresSpaceP, {aKPos[1]+nRBreite+20,aKPos[2]+nRBreite+20,aKPos[1]+nRBreite+30,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                     oBitmap:draw( ::oPresSpaceP, {aKPos[1]+nRBreite+20,aKPos[2]+nRBreite+20,aKSize[1]-nRBreite-20,aKPos[2]+nRBreite+30},,, ::BitRate )     // 21.02.2006
                     oBitmap:draw( ::oPresSpaceP, {aKPos[1]+nRBreite+20,aKSize[2]-nRBreite-30,aKSize[1]-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                     oBitmap:draw( ::oPresSpaceP, {aKSize[1]-nRBreite-30,aKPos[2]+nRBreite+20,aKSize[1]-nRBreite-20,aKSize[2]-nRBreite-20},,, ::BitRate )     // 21.02.2006
                  ENDIF                           
               ENDIF                              
            ENDIF                                 
            GraSegClose( ::oPresSpaceP )                                               
            //+16.12.2008 14:25 wenn der Ausdruck um 180ø gedreht sein soll:  
            IF l180     // .T., wenn nOrientierung = 3/4, statt 1/2
               IF ::Orient == 1  //+ d.h. Hochformat
                  GraRotate( ::oPresSpaceP, aMat, 180, {1050,1485}, GRA_TRANSFORM_REPLACE ) //+15.12.2008 20:36
               ELSE
                  GraRotate( ::oPresSpaceP, aMat, 180, {1485,1050}, GRA_TRANSFORM_REPLACE ) //+15.12.2008 20:36
               ENDIF
               aMat := GraInitMatrix() //+17.07.2010 18:52 intialisieren fr folgendes GraSegDraw()
            ENDIF
         ENDIF
         //+ auf Vorrat: damit soll man auch verschieben k”nnen:
         //   GraScale( ::oPresSpaceP, aMat, {-1,-1}, {1050,1485} ) //+15.12.2008 20:36
         GraSegDraw( ::oPresSpaceP, nHsegment, aMat )   //+16.12.2008 09:10
         GraSegDraw( ::oPresSpaceP, ::segmentsP[nPageNo], aMat )   //+14.12.2008 17:43

   /*15.12.2008 18:48 vorbergehend auáer Betrieb nehmen:
            IF "TEST"$Upper(AppName()) .OR. IsMemVar("xDemo")
   //            oBitmap:load( , 1020 )           
               oBitmap:load( "MUSTER.DLL", 1020 )  //10.09.2006 13:52
               oBitmap:draw( ::oPresSpaceP, aBitRect,,, ::BitRate )
               GraSegDraw( ::oPresSpaceP, ::segmentsP[nPageNo] )
            ENDIF                                 
   */
      ENDIF                                    
   ENDIF                                       
      IF IsMemberVar( oEdit, "cDKT" )  // 15.12.2008 18:48
         //+ Symbol-Offset wieder zurckgesetzt
         cGOx := cX ; cGOy := cY
      ENDIF
                                               
RETURN self                                    

//+16.01.2009 13:16 das Problem der Verschiebung nTDGeoX/Y wurde anders gel”st:
//+                  hier und in BlattDrVGw fr Text und Grafik
////////+ aus Alaska_Samp3: 14.12.2008 17:44 
//////         FUNCTION Geometrie(oSourcePS)
//////         LOCAL aPos, ASize
//////         LOCAL  nWidth, nHeight, nX, nY, oBmp, oTargetPs, lOk
//////         
//////         aPos := {0-nTDGeoX,0-nTDGeoY}
//////         aSize := oSourcePS:setPageSize()
//////
//////         nX        := aPos[01]
//////         nY        := aPos[02]
//////         nWidth    := aSize[1,01]
//////         nHeight   := aSize[1,02]
//////         
//////         oBmp      := XbpBitmap():new():create(oSourcePS)
//////         oTargetPS := XbpPresSpace():new():create()
//////         oBmp:presSpace(oTargetPS)
//////         if     !oBmp:make(nWidth, nHeight,,24)
//////                lOk := .f.
//////         elseif !GraBitBlt(oTargetPS, oSourcePS, {0, 0, nWidth, nHeight},;
//////                                                 {nX, nY, ((nX + nWidth)    - 1),;
//////                                                          ((nY + nHeight) - 1)},;
//////                                      GRA_BLT_ROP_SRCCOPY,;
//////                                      GRA_BLT_BBO_OR)
////////                                      GRA_BLT_ROP_SRCPAINT,GRA_BLT_BBO_IGNORE )
//////                 lOk := .f.
//////         else
//////                 lOk := .t.
//////         endif
//////         if !lOk .OR. (oBmp:xsize == 0 .AND. oBmp:ysize == 0)
//////            oBmp:destroy()
//////            oBmp := NIL
//////         endif
//////         RETURN oBmp
                                               
/*                                             
 * Druckausgabe beginnen                       
 * - Der Presentation Space wird mit dem Print Device Context assoziiert
 */                                            
METHOD XbpPreview:startDoc                     
                                               
   ::oPresSpaceP:configure( ::printer )        
    ::oPresSpaceP:setAttrArea( ::aAreaAttr )   
    ::oPresSpaceP:setAttrString( ::aCharAttr ) 
                                               
   // Ab jetzt wird die Ausgabe in :oPresSpace auf den Spooler umgeleitet
   ::printer:startDoc()                        
                                               
RETURN self                                    
                                               
                                               
                                               
/*                                             
 * Druckausgabe beenden                        
 * - Der Presentation Space wird wieder mit dem Window Device Context assoziiert
 */                                            
METHOD XbpPreview:endDoc(nPageNo)              
                                               
   // Spooler schlieáen                        
   ::printer:endDoc()                          
                                               
RETURN self                                    
                                               
                                               
                                               
/*                                             
 * Ausgabe aller Seiten auf dem Drucker        
 */                                            
METHOD XbpPreview:print( nPageNo, x )          
   LOCAL i
   
   IF AppKeyState(65553)=1    //+15.04.2016 15:30 mit Strg-Taste kein Druck, sondern nur Speichern
      RETURN self
   ENDIF
   
   IF !Empty(x)   // 18.6.2005   fr Ende+Druck
      xR := x                                  
   ENDIF                                       
                                               
   IF Len(::segments) == 0                     
      RETURN self                              
   ENDIF                                       
   ::startDoc()                                
                                               
   IF !Empty(nPageNo)                          
      ::printPage( nPageNo )                   
   ELSE                                        
      FOR i:=1 TO ::numPages()                 
        ::printPage( i )                       
                                               
        IF i +1 <= ::numPages()                
           ::printer:newPage()                 
        ENDIF                                  
      NEXT                                     
   ENDIF                                       
                                               
   ::endDoc(nPageNo)                           
   ::lDruckOK := .T. //09.10.2006 15:24 Ausgabe auf Drucker ist erfolgt
                                               
RETURN self                                    
                                               
                                               
                                               
/*                                             
 * Ermitteln der Seitenanzahl                  
 */                                            
METHOD XbpPreview:numPages()                   
RETURN Len( ::segments )                       
                                               
                                               
/*                                             
 * Ermitteln der Nummer der akt. Seite         
 */                                            
METHOD XbpPreview:pageNo()                     
RETURN ::nPagePos                              
/*                                             
 * Anzeigen der n„chsten Seite                 
 */                                            
METHOD XbpPreview:drawNextPage()               
   IF ::nPagePos +1 <= ::numPages()            
      ::nPagePos++                             
      ::drawPage()                             
      ::oPagePos:invalidateRect()              
   ENDIF                                       
RETURN self                                    
                                               
                                               
                                               
/*                                             
 * Anzeigen der vorhergehenden Seite           
 */                                            
METHOD XbpPreview:drawPrevPage()               
   IF ::nPagePos -1 > 0                        
      ::nPagePos--                             
      ::drawPage()                             
      ::oPagePos:invalidateRect()              
   ENDIF                                       
RETURN self                                    
                                               
//24.01.2008 09:30 rechnet Position und Gr”áe der Karte innerhalb des A4-Blatts aus:
METHOD XbpPreview:drawPosSize(aKPos,aKSize,lMittelLinie,lMittelLinie2, ;
                              nTDGeoX, nTDGeoY )
   LOCAL nAnf, nEnd
   //+ eigentlich zwei PUBLICs, sollen aber nur fr printpage() wirken:
   DEFAULT nTDGEoX TO 0, nTDGeoY TO 0     //+15.12.2008 18:00
   PRIVATE cKPos, cKSize                       
      DO CASE                                  
         CASE "A5-"$oEdit:cDKT                 
            aKPos := {308+nTDGeoX,870+nTDGeoY}                 
            aKSize := {1793+nTDGeoX,2970+nTDGeoY}              
            lMittelLinie := IIf(Right(Trim(oEdit:cDKT),1)=="+",.T.,.F.)
            lMittelLinie2 := IIf(Right(Trim(oEdit:cDKT),1)=="-",.T.,.F.)
         CASE "A5q-"$oEdit:cDKT                
            aKPos := {870+nTDGeoX,308+nTDGeoY}                 
            aKSize := {2970+nTDGeoX,1793+nTDGeoY}              
            lMittelLinie := IIf(Right(Trim(oEdit:cDKT),1)=="+",.T.,.F.)
            lMittelLinie2 := IIf(Right(Trim(oEdit:cDKT),1)=="-",.T.,.F.)
         CASE "A5qu-"$oEdit:cDKT               
            aKPos := {0+nTDGeoX,308+nTDGeoY}                   
            aKSize := {2100+nTDGeoX,1793+nTDGeoY}              
            lMittelLinie := IIf(Right(Trim(oEdit:cDKT),1)=="+",.T.,.F.)
            lMittelLinie2 := IIf(Right(Trim(oEdit:cDKT),1)=="-",.T.,.F.)
         CASE "A6-"$oEdit:cDKT                 
            aKPos := {525+nTDGeoX,1485+nTDGeoY}                
            aKSize := {1575+nTDGeoX,2970+nTDGeoY}              
         CASE "A6q-"$oEdit:cDKT                
            aKPos := {1485+nTDGeoX,525+nTDGeoY}                
            aKSize := {2970+nTDGeoX,1575+nTDGeoY}              
            lMittelLinie := IIf(Right(Trim(oEdit:cDKT),1)=="+",.T.,.F.)
            lMittelLinie2 := IIf(Right(Trim(oEdit:cDKT),1)=="-",.T.,.F.)
         CASE "A6qu-"$oEdit:cDKT               
            aKPos := {0+nTDGeoX,525+nTDGeoY}                   
            aKSize := {1485+nTDGeoX,1575+nTDGeoY}              
            lMittelLinie := IIf(Right(Trim(oEdit:cDKT),1)=="+",.T.,.F.)
            lMittelLinie2 := IIf(Right(Trim(oEdit:cDKT),1)=="-",.T.,.F.)
         CASE "SPEZ-"$Upper(oEdit:cDKT)   //17.10.2007 09:07 spezielle Formate als Namensteil in '{}{}'
            nAnf := At("{",oEdit:cDKT)         
            nEnd := At("}",oEdit:cDKT)         
            cKPos := SubStr(oEdit:cDKT,nAnf,nEnd-nAnf+1)
            aKPos := &(cKPos)
            aKPos := {aKPos[1]+nTDGeoX,aKPos[2]+nTDGeoY}
            lMittelLinie := IIf(oEdit:cDKT[nEnd+1]=="+",.T.,.F.)  // + zwischen den Klammern oder...
            lMittelLinie2 := IIf(oEdit:cDKT[nEnd+1]=="-",.T.,.F.)  // - zwischen den Klammern oder...
            nAnf := At("{",oEdit:cDKT,nEnd)    
            nEnd := At("}",oEdit:cDKT,nAnf)    
            cKSize := SubStr(oEdit:cDKT,nAnf,nEnd-nAnf+1)
            aKSize := &(cKSize)
            aKSize := {aKSize[1]+nTDGeoX,aKSize[2]+nTDGeoY}
            lMittelLinie := IIf(Right(Trim(oEdit:cDKT),1)=="+",.T.,lMittelLinie) // ... + am Ende
            lMittelLinie2 := IIf(Right(Trim(oEdit:cDKT),1)=="-",.T.,lMittelLinie2) // ... - am Ende
      //+23.11.2008 10:13 A4 testweise auch setzen:
         CASE "A4-"$oEdit:cDKT                 
            aKPos := { 0+nTDGeoX, 0+nTDGeoY}                 
            aKSize := {2100+nTDGeoX,2970+nTDGeoY}              
            lMittelLinie := IIf(Right(Trim(oEdit:cDKT),1)=="+",.T.,.F.)
            lMittelLinie2 := IIf(Right(Trim(oEdit:cDKT),1)=="-",.T.,.F.)
         CASE "A4q-"$oEdit:cDKT                
            aKPos := {  0+nTDGeoX, 0+nTDGeoY }                 
            aKSize := {2970+nTDGeoX,2100+nTDGeoY}              
            lMittelLinie := IIf(Right(Trim(oEdit:cDKT),1)=="+",.T.,.F.)
            lMittelLinie2 := IIf(Right(Trim(oEdit:cDKT),1)=="-",.T.,.F.)
         CASE "A4qu-"$oEdit:cDKT               
            aKPos := { 0+nTDGeoX, 0+nTDGeoY }                   
            aKSize := {2970+nTDGeoX,2100+nTDGeoY}              
            lMittelLinie := IIf(Right(Trim(oEdit:cDKT),1)=="+",.T.,.F.)
            lMittelLinie2 := IIf(Right(Trim(oEdit:cDKT),1)=="-",.T.,.F.)
         OTHERWISE                             
            aKPos := { 0+nTDGeoX , 0+nTDGeoY}                 
            aKSize := {2100+nTDGeoX,2970+nTDGeoY}              
            lMittelLinie := IIf(Right(Trim(oEdit:cDKT),1)=="+",.T.,.F.)
            lMittelLinie2 := IIf(Right(Trim(oEdit:cDKT),1)=="-",.T.,.F.)
      ENDCASE                                  
RETURN self
                                               
// wird aufgerufen durch :killInputFocus der Vorschau-Editierfelder
METHOD XbpPreview:UPDATE( nPageno )            
   LOCAL oBitmap, aBitRect, aKPos := {0,0}, aKSize := ::aPageSize //24.01.2008 09:23
   LOCAL i, aBlattZ, nAktuelleSeite := ::nPagePos //12.07.2007 16:55
   LOCAL aAktuelleSeite := {::nPagePos,::zoomfactor,::hScroll:getData(),::vScroll:getData()}
   LOCAL cTime := Time()      //+29.10.2008 11:48
   LOCAL cFilename := StrX(1->auftrnr,6) + SubStr(cdru,3) + "-"+DtoS(DATE()) + "-" + ;
                              SubStr(cTime,1,2) + SubStr(cTime,4,2) + SubStr(cTime,7,2)   //+29.10.2008 11:51
   DEFAULT nPageNo TO ::nPagePos               

   IIf(cVD="n",cBriefKopf:="",cBriefKopf:=cBKpf)  //+10.05.2011 20:16
                                              
//   wie Gather( aEditcontrols ) :             
   FOR i := 1 TO len( ::oParameter:Editcontrols ) - ::oParameter:LeditC
      IF ValType( ::oParameter:Editcontrols[i+::oParameter:LeditC] ) == "O"
         IF ::oParameter:aNa[i] == "t"         
            ::oParameter:aText[i] := ::oParameter:Editcontrols[i+::oParameter:LeditC]:getdata()
            cF := ::oParameter:aFeld[i]        
            IF !Empty( cF ) // d.h. wenn in aText[i] der Inhalt der "Variablen in aFeld[i]" steht...
               &cF := Trim( ::oParameter:aText[i] ) //...wird der ge„nderte Text der Variablen zugewiesen
            ENDIF                              
         ELSEIF ::oParameter:aNa[i] == "v"   //18.04.2006 17:50
            IF IsMemVar("p")  // wird gesetzt, wenn Parameter1/2-Eintrag ge„ndert wird
               cF := SubStr(::oParameter:aText[i],1,At(":=",::oParameter:aText[i])-1)
               IF !Empty(cF) .AND. cF != "IIf"  // wenn in aText[i] eine Gleichung steht
                  &cF := &(SubStr(::oParameter:aText[i],At(":=",::oParameter:aText[i])+2)) // Gleichung aufl”sen
               ELSE                            
                  cF := ::oParameter:aText[i]   // Ausdruck ausfhren
               ENDIF                           
               IF !Empty(cF) .AND. &cF == NIL      /*28.06.2008 14:22*/ //+24.05.2009 14:04
                  ::oParameter:Editcontrols[i+::oParameter:LeditC]:setdata("")
               ELSEIF !Empty(cF)                            
                  ::oParameter:Editcontrols[i+::oParameter:LeditC]:setdata(&cF)
               ENDIF                           
            ENDIF                              
            ::oParameter:aFeld[i] := ::oParameter:Editcontrols[i+::oParameter:LeditC]:getdata()
               cF := SubStr(::oParameter:aText[i],1,At(":=",::oParameter:aText[i])-1)  //17.05.2006 11:47
               IF !Empty(cF) .AND. cF != "IIf"  // wenn in aText[i] eine Gleichung steht
                  &cF := ::oParameter:aFeld[i] // 17.05.2006 11:46   Variable editiert
               ENDIF                           
         ELSEIF ::oParameter:aNa[i] == "M"     
            IF IsMemVar("p") .AND. !Empty(::oParameter:aText[i])  // wird gesetzt, wenn Parameter1/2-Eintrag ge„ndert wird
               cF := SubStr(::oParameter:aText[i],1,At(":=",::oParameter:aText[i])-1)
               IF !Empty(cF) .AND. cF != "IIf"  // wenn in aText[i] eine Gleichung steht
                  &cF := &(SubStr(::oParameter:aText[i],At(":=",::oParameter:aText[i])+2)) // Gleichung aufl”sen
               ELSE                            
                  cF := ::oParameter:aText[i]   // Ausdruck ausfhren
               ENDIF                           
               ::oParameter:Editcontrols[i+::oParameter:LeditC]:setdata(&cF)
            ENDIF                              
                                               
            ::oParameter:aFeld[i] := ::oParameter:Editcontrols[i+::oParameter:LeditC]:getdata()
            cF := SubStr(::oParameter:aText[i],1,At(":=",::oParameter:aText[i])-1)  //13.07.2006 21:59
            IF !Empty(cF) .AND. cF != "IIf"  // wenn in aText[i] eine Gleichung steht
               &cF := ::oParameter:aFeld[i] // 17.05.2006 11:46   Variable editiert
            ELSE                               
//               cF := ::oParameter:aFeld[i]        // 18.12.2005 Test
//               cF := &cF                     
            ENDIF                              
         ELSEIF ::oParameter:aNa[i] == "X"     
            cF := ::oParameter:aFeld[i]        // 13.07.2006 19:10 Test
            cF := &cF                          
         ELSE                                  
            ::oParameter:aFeld[i] := ::oParameter:Editcontrols[i+::oParameter:LeditC]:getdata()
         ENDIF                                 
         ::oParameter:aBlatt[i] := { ::oParameter:aSeite[i], ::oParameter:aNa[i], ::oParameter:aPrompt[i], ;
                  ::oParameter:aText[i], ::oParameter:aTFont[i], ::oParameter:aBereich[i], ;
                  ::oParameter:aFeld[i], ::oParameter:aFFont[i], ::oParameter:aZei[i], ::oParameter:aSpa[i] }
      ENDIF                                    
   NEXT                                        
   ::aBlatt := ::oParameter:aBlatt             
   //+29.12.2008 14:02 fr den Fall, dass Satzsperren gesetzt wurden: (in bl_chec bei WernerX)
   IF Len(DbRLockList()) > 0
      DbRUnlock()
   ENDIF
   IF !lVor                                    
      RETURN self                              
   ENDIF                                       
         ::segments := Eval( ::drawBlock,  ;   
                                      ::oPresSpace, ;
                                      nPageNo,      ;
                                      @::nRows, ;
                                      ::segments,  ;
                                      ::aBlatt, ;
                                      ::cCP,    ;
                                      ::aSchrift, ;
                                      ::Orient, ;
                                      "::UPDATE" )		//06.12.2022 18:45 UPDATE zum Verfolgen, von wo der drawblock aufgerufen wurde
      ASize( ::segmentsP, ::numPages() )       
      AFill( ::segmentsP, NIL )                
////                                           
      IF IsMemberVar( oEdit, "cDKT" )  // 24.01.2008 09:35 Trauerdruck
         ::drawPosSize( @aKPos, @aKSize )      
      ENDIF                                    
////                                           
      FOR nPageNo := 1 TO ::numPages()         
         GraBox( ::oPresSpace, {0,0}, ::aPageSize, GRA_FILL )
         oBitmap    := XbpBitmap():new():create( ::oPresSpace )
//         aBitRect      := { 0, 0, ::aPageSize[1], ::aPageSize[2] }
         aBitRect      := { aKPos[1], aKPos[2], aKSize[1], aKSize[2] }  //24.01.2008 09:35
         IF Len(cBriefKopf)>100      //22.07.2006 11:47 >100 heiát:in cGrafik ist die Grafik
            oBitmap:setbuffer( cBriefKopf )          // Bitmap laden
         ELSE                    //22.07.2006 11:47 <100 heiát:in cGrafik ist der GrafikdateiName
            oBitmap:loadFile( cDatver+IIf("."$cBriefKopf,cBriefKopf,cBriefKopf+".BMP") )  // Bitmap laden   18.11.2008 14:58
         ENDIF                                 
         oBitmap:draw( ::oPresSpace, aBitRect,,, ::BitRate )
         GraSegDraw( ::presSpace(), ::segments[nPageNo] )
      NEXT                                     
      IF IsMemVar("cGia")     //16.09.2007 17:22 damit bl_b1/2-Statistiken auf letzter Seite landen
         ::nPagePos := nPageNo - 1             
      ELSE                                     
         ::nPagePos := aAktuelleSeite[1]       
         ::zoomfactor := aAktuelleSeite[2]     
         ::hScroll:setData( aAktuelleSeite[3] )
         ::vScroll:setData( aAktuelleSeite[4] )
         ::zoom( ::zoomfactor )                
      ENDIF                                    
//      IF IsMemVar("xF")                      
//         SegmentSpeichern( ::presSpace(), {0,0}, {2098,2970}, cFilename )
//      ENDIF                                  
      ::oPagePos:paint()                       
      ::oPagePos:invalidateRect()
      
	   IF Upper(AppName())$"MUELLX.EXE-BLEINX.EXE" .AND. TYPE("cMwStJN") == "C" .AND. cMwStJN[1]$"yY"
	      // Rechnung als Html-Datei
	      cFileR := "R"+StrX(1->auftrnr)+".html"
	      nHandle_RG := FCreate(cFileR)
	     // cRText := cHtml + ConvToAnsiCP(t_Html) + '</div></body></html>'
	      cRText := cHtml + t_Html + '</div></body></html>'	// in cHtml ist der HEAD aus BlattDrVGw.prg
	      FWrite( nHandle_RG, cRText )
	      FClose(nHandle_RG)
	      sleep(200)
	      Tone(300)
			//15.03.2026 18:39 Rechnung als Text-Datei
		   // "_Rechnung"-Verzeichnis fr den Auftrag wird erzeugt:
		      IF !FExists(cDatver + "Scans\Dokumente\"+StrX(1->auftrnr,E,0)+"\_Rechnung","D")
		         RunShell( "/C MD "+cDatver + "Scans\Dokumente\"+StrX(1->auftrnr,E,0)+"\_Rechnung",, .T. )
			   	sleep(100)
		      ENDIF
	      cFileR := cDatver + "Scans\Dokumente\"+StrX(1->auftrnr,E,0)+"\_Rechnung\"+"R"+StrX(1->auftrnr)+".rdr"
	      nHandle_RG := FCreate(cFileR)
	     // cRText := cHtml + ConvToAnsiCP(t_Html) + '</div></body></html>'
	     // cRText := cHtml + t_Html + '</div></body></html>'	// in cHtml ist der HEAD aus BlattDrVGw.prg
	     // FWrite( nHandle_RG, cRText )
	      FWrite( nHandle_RG, t_rdr )
	      FClose(nHandle_RG)
	      sleep(200)
	      Tone(600)
		ENDIF      
                    
RETURN self                                    
                                               
METHOD XbpPreview:ParUPDATE( nPageno )         
   LOCAL i, aBlattZ                            
   DEFAULT nPageNo TO ::nPagePos               
   PRIVATE cF, cT
   cZweiseitjn := "a"      //+05.06.2010 13:46
//   wie Gather( aEditcontrols ) :             
   FOR i := 1 TO ::oParameter:LeditC           
      IF ValType( ::oParameter:Editcontrols[i] ) == "O"
         IF ::oParameter:aNaP[i] == "t"        
            ::oParameter:aTextP[i] := ::oParameter:Editcontrols[i]:getdata()
            cF := ::oParameter:aFeldP[i] ; cT := ::oParameter:aTextP[i]
            IF !Empty( cF )                    
               &cF := IIf(cT="&",&(SubStr(cT,2)),Trim( cT ))   //23.07.2006 19:26
               IF cF = "cBriefKopf" //+16.05.2011 12:44
                  cBKpf := &cF
               ENDIF
            ENDIF                              
//            IF cF = "cAnz"                   
//               oSpin:setData( Val(cT) )      
//            ENDIF                            
         ELSEIF Upper(::oParameter:aSeiteP[i]) != "V"       // wozu ist das(5.2.04)? 
            ::oParameter:aFeldP[i] := ::oParameter:Editcontrols[i]:getdata()
         ENDIF                                 
         ::oParameter:aParam[i] := { ::oParameter:aSeiteP[i], ::oParameter:aNaP[i], ::oParameter:aPromptP[i], ;
                  ::oParameter:aTextP[i], ::oParameter:aTFontP[i], ::oParameter:aBereichP[i], ;
                  ::oParameter:aFeldP[i], ::oParameter:aFFontP[i], ::oParameter:aZeiP[i], ::oParameter:aSpaP[i] }
      ENDIF                                    
   NEXT                                        
   cBrNe5 := PadR(cBrNe5,1)      //29.06.2007 13:52
   ::aParam := ::oParameter:aParam             
RETURN self                                    

//-----------------------------------------------------------------------
//+01.05.2009 19:16 schreibt bei Ende+Druck die Blattdaten in den Safe:
METHOD XbpPreview:BlattSchreiben()
   LOCAL cString, nOldArea := SELECT(), i, xS, cS, cM
   IF Upper(AppName())$"SANDERX.EXE-RUDOX.EXE-BUCKX.EXE"      //+22.01.2010 13:30
      RETURN self
   ENDIF
   IF Upper(AppName())$"NOLTEX.EXE-SONNEX.EXE" // 30.08.2015 12:39  .AND. !Upper(cDru)$"BL_FRMD"
      RETURN self
   ENDIF
   IF Upper(cDru)$"BL_ALBR-BL_ALB2-BL_6WA-BL_V-BL_VOLL"    //+28.05.2009 12:10+03.07.2009 12:44
      RETURN self
   ENDIF
   DbUseArea(.T., "FOXCDX", "SAFE_BL", "bs", .F. ) //+ EXCLUSIVE !
   OrdListAdd("SAFE_BL")
   IF !DbSeek( PadR(StrX(1->auftrnr,E)+cDru,16), .F. )
      DbAppend()
      bs->aufblatt := PadR(StrX(1->auftrnr,E)+cDru,16)
   ENDIF
   cString := '{'
   FOR i := 1 TO Len(::oParameter:singleZeile)
      xS := ::oParameter:singleZeile[i]:getData()
      cS := IIf( ValType(xS)=="N", "+"+Str(xS), IIf(ValType(xS)=="D", "*" + DtoC(xS), xS ) )
      cString += '[' + cS + ']' + IIf(i=Len(::oParameter:singleZeile),' ',', ')
   NEXT
   bs->single := cString + '}'
   cString := '{'
   FOR i := 1 TO Len(::oParameter:multiZeile)
      cM := ::oParameter:multiZeile[i]:getData()
      DO WHILE (j := At(CRLF,cM)) > 0
         cM := Stuff(cM,j,2,"õõ")
      ENDDO
      cString += '[' + cM + ']' + IIf(i=Len(::oParameter:multiZeile),[ ],[, ])
   NEXT
   bs->multi := cString + '}'
   DbCloseArea()
   SELECT &nOldArea
RETURN self

//+01.05.2009 18:07 liest die Blattdaten aus dem Safe, die vorher gespeichert wurden:
METHOD XbpPreview:BlattLesen()
   LOCAL nOldArea := SELECT(), i, xS, cS, cM
   PRIVATE aP, aB
   DbUseArea(.T., "FOXCDX", "SAFE_BL", "bs" )
   OrdListAdd("SAFE_BL")
   IF DbSeek( PadR(StrX(1->auftrnr,E)+cDru,16), .F. )
      aP := bs->single
      FOR i := 1 TO Len(&aP)
         cS := &aP[i]
         xS := IIf( Len(cS) > 0, IIf( cS[1]="+", Val(cS), ;
                                             IIf( cS[1]="*", CtoD(cS), cS) ), cS )
         ::oParameter:singleZeile[i]:setData(xS)
         ::oParameter:singleZeile[i]:getData()
      NEXT
      aB := bs->multi
      FOR i := 1 TO Len(&aB)
         cM := &aB[i]
         DO WHILE (j := At("õõ",cM)) > 0
            cM := Stuff(cM,j,2,CRLF)
         ENDDO
         ::oParameter:multiZeile[i]:setData(cM)
         ::oParameter:multiZeile[i]:getData()
      NEXT
   ENDIF
   DbCloseArea()
   SELECT &nOldArea
RETURN self

//+23.04.2017 09:29 speichert wie Strg_F2 und mailt an Empf„nger mit Anhang
METHOD XbpPreview:BlattMailen(cEmpfaenger, cBetreff, cBody)
   LOCAL p := 2, cMailAnhang, cNotiz, cTxtDatei, IndTagName		//+08.07.2019 21:42
   DEFAULT cEmpfaenger TO "roman.dembinski@t-online.de"
   DEFAULT cBetreff TO "Blumenbestellung / "+Trim(1->vorname)+" "+Trim(1->name)
   DEFAULT cBody TO ConvToAnsiCP("Sehr geehrte Damen und Herren," + CRLF + ;
                    "hiermit bestellen wir Blumen gem„á dem Auftrag im Anhang." + CRLF + ;
                    "Mit freundlichen Gráen" + CRLF + ;
                    "Beerdigungsinstitut" + CRLF + ;
                    "Gebr. Nolte GmbH")

		//+28.06.2020 12:05 damit bei Trauerdruck nicht gemailt wird: "BL_BRF0-BL_BRF1-BL_BRF2-BL_FOTO"
		IF Upper(cDru)$"BL_TERM-BL_BRF0-BL_BRF1-BL_BRF2-BL_FOTO-BL_KAS-BL_KAST-BL_KASK-BL_KATX"	//+11.09.2020 12:05
			RETURN .F.
		ENDIF

   // Verzeichnis fr den Auftrag wird erzeugt:
      IF !FExists(cDatver + "Scans\Dokumente\"+StrX(1->auftrnr,E,0),"D")
         RunShell( "/C MD "+cDatver + "Scans\Dokumente\"+StrX(1->auftrnr,E,0),, .T. )
	   	sleep(100)
      ENDIF
      IF Upper(cDru) == "BL_BLUM"	//+30.06.2019 14:43

//               nP := oVorschau:numPages()
//               FOR p := 1 TO nP  //+24.08.2010 18:21 Bemerkung: mehrere Seiten speichern klappt noch nicht! 24.08.2010 18:21
//                  oVorschau:savepage(p,,"\scans\dokumente\"+StrX(auftrnr,E)+"\"+StrX(auftrnr,E)+cDru+StrX(p,2,0)+DtoS(Date())+Left(Time(),2)+Substr(time(),4,2)+Right(time(),2)+".jpg" )
   // Seite wird als jpg-Datei in das Auftragsverzeichnis gespeichert:
	      cMailAnhang := "\scans\dokumente\"+StrX(1->auftrnr,E)+"\"+Upper(cDru)+"\"+StrX(1->auftrnr,E)+Upper(cDru)+StrX(p,2,0)+DtoS(Date())+Left(Time(),2)+Substr(time(),4,2)+Right(time(),2)
	      ::savepage(p,,cMailAnhang+".jpg")
	      Sleep(100)
	      cMailAnhang += +".PDF"
//               NEXT

   	ELSE
	   // Verzeichnis fr den Druck wird erzeugt:
	      IF !FExists(cDatver + "Scans\Dokumente\"+StrX(1->auftrnr,E,0)+"\"+Upper(cDru),"D")
	         RunShell( "/C MD "+cDatver + "Scans\Dokumente\"+StrX(1->auftrnr,E,0) + "\" + Upper(cDru),, .T. )
		   	sleep(100)
	      ENDIF
	      
	      // hier k”nnte cBetreff und cBody aufgebaut werden ...
			//+08.07.2019 16:56: Texte holen ...  aus s_.tak:
			//{"Mitteilung an Adresse suchen",{|| area:=5,oBest:TabDaten(),oEdit:TextSuchen(oAEDA,"Texte","s_best",982,989,'at',StrX(1->auftrnr,E,0)+cE+"!mitteilun",{10*nH,30*nV},{500*nH,175*nV}),BlattDrG("BL_ALBR",,oAEDA,,,"P","O",@nAnz,@nt) } }
			oBest:TabDaten()
//			cTxtDatei := "Textfrei"
//			cIndTagName := "ta"
//	      24->(DbUseArea(,"FOXCDX",cTxtDatei))
//	      24->(OrdListAdd(cTxtDatei,cIndTagName))
//			oBest:TextSuchen(oVODA,"Textfrei","s_best",972,979,'ta',"!"+PadR(Upper(cDru),9," ")+StrX(1->auftrnr,E,0),{10*nH,30*nV},{500*nH,175*nV},,,24)
		
//			cBetreff := ConvToAnsiCP(oBest:TxBd0)
			aBetreff :=	{{"BL_V","Versicherungs-Anschreiben"},;
							{"BL_R","Rechnung"},;
							{"BL_R1","Rechnung"},;
							{"BL_R2","Aufstellung"},;
							{"BL_R3","Nachtragsrechnung"},;
							{"BL_A","Abrechnung"},;
							{"BL_A1","Abrechnung"},;
							{"BL_A2","Abrechnung"},;
							{"BL_VR","Angebot"},;
							{"BL_VR1","Angebot"},;
							{"BL_VR1E","Angebot"},;
							{"BL_VOR","Bestattungsvorvertrag"},;
							{"BL_TRH","Treuhandvertrag"},;
							{"BL_RA","Rechnung"},;
							{"BL_RE","Rechnung"},;
							{"BL_CHEC","Checkliste"},;
							{"BL_BLUM","Blumenbestellung"},;
							{"BL_GRKR","Grabkreuz"},;
							{"BL_SFA","Sterbefallanzeige"},;
							{"BL_SFA2","Sterbefallanzeige"},;
							{"BL_SFAN","Sterbefallanzeige"},;
							{"BL_SFN","Sterbefallanzeige"},;
							{"BL_ARNS","Sterbefallanzeige"},;
							{"BL_HERD","Sterbefallanzeige"},;
							{"BL_PETR","Sterbefallanzeige"},;
							{"BL_PTRI","Sterbefallanzeige"},;
							{"BL_SUND","Sterbefallanzeige"},;
							{"BL_JOHA","Sterbefallanzeige"},;
							{"BL_ERKL","Erkl„rung zur Ein„scherung"},;
							{"BL_KRWE","Ein„scherungsauftrag"},;
							{"BL_KREM","Ein„scherungsauftrag"},;
							{"BL_HELL","Antrag auf Aush„ndigung der Urne"},;
							{"BL_LETZ","Letzter Wille"},;
							{"BL_FEU","Mitteilung"},;
							{"BL_GRUE","Mitteilung"},;
							{"BL_GRUN","Mitteilung"},;
							{"BL_FRIE","Mitteilung"},;
							{"BL_ORD","Mitteilung"},;
							{"BL_FIRM","Mitteilung"},;
							{"BL_RENT","Rentenabmeldung"},;
							{"BL_VOLL","Vollmacht"},;
							{"BL_VOLN","Vollmacht"},;
							{"BL_ALBR","Anschreiben"},;
							{"BL_ALB2","Anschreiben"},;
							{"BL_6WA","Sechswochenamtsbrief"},;
							{"BL_BRKO","Firmenbriefkopf"},;
							{"BL_PRSB","Postrentenantrag"}}

			i := AScan(aBetreff,Upper(cDru))
			IF i==0
				msgbox("Dieser Druck kann nicht per Mail versandt werden!")
				RETURN .F.
			ENDIF
			
			IF AppKeyState(65553)=1 .AND. "BL_R"$Upper(cDRU) 	//Ctrl-Taste bei Klick auf Knopf 'Mail'
				IF Upper(cMwStJN) = "Y" .AND. xZUGFeRD(DtoC(DATE()),"Z")		// Fkt xZUGFeRD wird aufgerufen
					Sleep(1000)
					cBetreff := ConvToAnsiCP( "Rechnung zum Sterbefall " + Verstorbener())
					cBody := ConvToAnsiCP(SehrGeehrte() +CRLF+;
								"im Anhang erhalten Sie unsere Rechnung zum Sterbefall " + Verstorbener(,.T.) + ", mit der Bitte um Kenntnisnahme." +CRLF+;
								"Mit freundlichen Gráen" +CRLF+CRLF+;
								cBU1 + CRLF + cBU2)
		
					cMailAnhang := "scans\dokumente\" + StrX(1->auftrnr,E) + "\_Rechnung" + "\R" + StrX(1->auftrnr,E) + "_zug.pdf"
					cEmpfaenger := AllTrim(1->ansp_email)
				ELSE
					RETURN .F.
				ENDIF
			ELSE 
			
			 
				cBetreff := ConvToAnsiCP(aBetreff[i,2] + " zum Sterbefall ") + Verstorbener()
				cBody := ConvToAnsiCP("Sehr geehrte Damen und Herren," +CRLF+;
							"im Anhang erhalten Sie ein Schreiben zum Sterbefall " + Verstorbener(,.T.) + ", mit der Bitte um Kenntnisnahme." +CRLF+;
							"Mit freundlichen Gráen" +CRLF+CRLF+;
							cBU1 + CRLF + cBU2)
	
				cMailAnhang := "scans\dokumente\" + StrX(1->auftrnr,E) + "\" + Upper(cDru) + "\" + StrX(1->auftrnr,E) + Upper(cDru)
				IF "BL_ALB"$Upper(cDru) 	// = bl_albr und bl_alb2
					IF Empty(cBetreff)
						cBetreff := cSF+" "+hSF+", "+IIf(Len(Trim(cSD))>5, cSD, "")
					ENDIF
					cBody := hAN2+CRLF+ConvToAnsiCP(oEdit:TxBd0+CRLF+"Mit feundlichen Gráen"+CRLF+CRLF+cBU1+CRLF+cBU2+CRLF+CRLF+"siehe Anhang")
					IF Upper(cDru) == "BL_ALB2"
						cMailAnhang := Stuff(cMailAnhang,RAt("\",cMailAnhang)+1,30,StrX(1->auftrnr,E)+Upper(cDru)+Trim(Substr(oEdit:aTxBd[1],2)))
					ELSE
						//+09.01.2020 19:25 erg„nzt um die verskz
						cMailAnhang := Stuff(cMailAnhang,RAt("\",cMailAnhang)+1,30,StrX(1->auftrnr,E)+Upper(cDru)+"-"+AllTrim(5->verskz)+"-"+Trim(Substr(oEdit:aTxBd[1],2)))
					ENDIF
				ENDIF
				IF !Upper(cDru)$"BL_A-BL_A1-BL_A2-BL_R-BL_RA" .AND. Upper(cDru)$"BL_ALBR-BL_RENT-BL_ORD-BL_FIRM"
					cEmpfaenger := AllTrim(5->email)
				ELSEIF Upper(cDru)=="BL_V"
					5->(DbSeek(12->verskz,.F.))
					cEmpfaenger := AllTrim(5->email)
					//+09.01.2020 19:25 erg„nzt um die verskz
					cMailAnhang := Stuff(cMailAnhang,RAt("\",cMailAnhang)+1,30,StrX(1->auftrnr,E)+Upper(cDru)+"-"+AllTrim(12->verskz))
				ELSEIF Len(Trim(cMailadresse)) > 0 .AND. Len(Trim(cMailadresse)) < 6		// in bl_-Datei angegeben
					5->(DbSeek(Trim(cMailadresse),.F.))
					cEmpfaenger := AllTrim(5->email)
				ELSEIF Len(Trim(cMailadresse)) > 5 .AND. "@"$cMailadresse
					cEmpfaenger := AllTrim(cMailadresse)
				ELSE
					cEmpfaenger := AllTrim(oBest:aBP[9])
				ENDIF
				IIf(Empty(cEmpfaenger),cEmpfaenger := "bitte@vonHand.eingeben",)
		      
				IF !FExists(cDatver + cMailAnhang + ".PDF") .OR. ;
		         ConfirmBox( oCB, IIf(SET(43)==0,ConvToAnsiCP("Formular erneuern mit <JA>"), ;
		                     "Formular erneuern mit <JA>"), ;
		                     IIf(SET(43)==0,ConvToAnsiCP("Email wurde schon erstellt!"), ;
		                     "Email wurde schon erstellt!"), ;
		                     XBPMB_YESNO, ;
		                     XBPMB_WARNING, ;
		                     XBPMB_DEFBUTTON2 ) ;
		                     =  XBPMB_RET_YES
				      ::savepage(p,,cMailAnhang+".jpg")
				      Sleep(100)
				ENDIF
		      cMailAnhang += ".PDF"
		   ENDIF
		ENDIF	      
   // mailen per Thunderbird
      IF oEdit:MailExtProg(cEmpfaenger,cBetreff,cBody,{cDatver+cMailAnhang},cDatver+"ThunderbirdPortable\ThunderbirdPortable.exe")
	         cNotiz := 1->notiz + CRLF + DtoC(DATE())+": " + Trim(cBetreff) + " an " + Trim(cEmpfaenger) + " gemailt."
	         1->(Satzsp(oCB))
	         FOR i:=1 TO Len(oBest:multizeile)       // direkte Anzeige auch bei cAc
	            oBest:multizeile[i]:setData( 1->notiz := cNotiz )
	         NEXT
	         1->(DbRUnlock())
      ENDIF
      ::segmentsP := {NIL}
RETURN self
//-----------------------------------------------------------------------
                                               
/*                                             
   oXbp := XbpPushButton():new( oStatic,, {114,12}, {152,22} )
   oXbp:caption  := "Bitmap"                   
   oXbp:activate := {|| GetBitmapFile( oBitmapRef ) }
   oXbp:group    := XBP_END_GROUP              
   oXbp:create()                               
   oDlg:addKeyControl( oXbp )                  
                                               
//   oBitmapRef := BitmapRef():new( drawingArea,, {310,27}, {295,238} )
   oBitmapRef := BitmapRef():new( drawingArea,, {310,27}, {690,650} )
   oBitmapRef:dataLink := {|x| IIf( x== NIL, BMPIMAGE, BMPIMAGE := x ) }
   oBitmapRef:create():setData()               
   oDlg:addEditControl( oBitmapRef )           
   AAdd( aStatic, oBitmapRef )                 
                                               
   AEval( aStatic, {|o| o:rbDown := bContextMenu } )
*/                                             
                                               
/*>>>>>>>>>>>>>>> siehe BitView-Klasse in AKDialogVH
 * Bitmap Datei in Datenbankfeld bertragen    
 */                                            
FUNCTION GetBitmapFile( oBmpRef )              
   STATIC scPath                               
   LOCAL  oDlg, cCurDir := CurDrive() + ":\" + CurDir() + "\"
                                               
   IF scPath == NIL                            
      scPath := cCurDir                        
   ENDIF                                       
                                               
   oDlg := XbpFileDialog():new():create()      
   cFile := oDlg:open( scPath + "*.BMP" )      
                                               
   oDlg:destroy()                              
                                               
   IF cFile <> NIL                             
      scPath := SubStr( cFile, 1, Rat( "\", cFile ) )
      oBmpRef:loadFile( cFile )                
      oBmpRef:draw()                           
   ENDIF                                       
                                               
   CurDir( cCurDir )                           
RETURN cFile                                   
                                               
                                               
                                               
/* Siehe dazu auch BitView-Klasse in AKDialogVH.prg !!
 * Klasse zur Verwaltung eines Datenbankfeldes, das bitmapdaten speichert
 */                                            
CLASS BitmapRef FROM XbpStatic, DataRef        
   PROTECTED:                                  
   VAR oBmp                                    
   VAR oPS                                     
   VAR lIsEmpty                                
                                               
   EXPORTED:                                   
   VAR autoScale                               
   METHOD init, create, destroy                
   METHOD setdata, getdata, editbuffer, draw, loadFile
ENDCLASS                                       
                                               
                                               
                                               
/*                                             
 * Objekt initialisieren                       
 */                                            
METHOD BitmapRef:init( oParent, oOwner, aPos, aSize, aPresParem, lVisible )
   ::dataRef:init()                            
   ::xbpStatic:init( oParent, oOwner, aPos, aSize, aPresParem, lVisible )
   ::xbpStatic:type := XBPSTATIC_TYPE_RAISEDBOX
   ::autoScale := .T.                          
   ::lIsEmpty  := .T.                          
   ::oPS       := XbpPresSpace():new()         
   ::oBmp      := XbpBitmap():new()            
RETURN self                                    
                                               
                                               
                                               
/*                                             
 * Systemresourcen anfordern und Farbe fr die Anzeige eines 
 * leeren Datenbankfeld definieren             
 */                                            
METHOD BitmapRef:create( oParent, oOwner, aPos, aSize, aPresParem, lVisible )
   LOCAL aAttr[ GRA_AA_COUNT ]                 
   ::xbpStatic:create( oParent, oOwner, aPos, aSize, aPresParem, lVisible )
                                               
   ::oPS:create( ::xbpStatic:winDevice() )     
   ::oBmp:create( ::oPS )                      
                                               
   aAttr[ GRA_AA_COLOR ] := GRA_CLR_PALEGRAY   
   ::oPS:setAttrArea( aAttr )                  
   ::xbpStatic:paint := {|aClip| ::draw(aClip) }
RETURN self                                    
                                               
                                               
                                               
/*                                             
 * Systemresourcen freigeben                   
 */                                            
METHOD BitmapRef:destroy                       
   ::oBmp:destroy()                            
   ::oPS:destroy()                             
   ::xbpStatic:paint := NIL                    
   ::xbpStatic:destroy()                       
RETURN self                                    
                                               
                                               
                                               
/*                                             
 * Bitmapdaten aus Feld in Puffer bertragen   
 */                                            
METHOD BitmapRef:setdata( cBuffer )            
   IF cBuffer == NIL                           
      cBuffer := Eval( ::dataLink )            
   ENDIF                                       
                                               
   IF ! Empty( cBuffer )                       
      ::oBmp:setBuffer( cBuffer, XBPBMP_FORMAT_WIN3X )
      ::lIsEmpty := .F.                        
   ELSE                                        
      ::lIsEmpty := .T.                        
   ENDIF                                       
   ::changed :=  .F.                           
   ::draw()                                    
RETURN cBuffer                                 
                                               
                                               
                                               
/*                                             
 * Gepufferte Bitmap in Feld bertragen        
 */                                            
METHOD BitmapRef:getdata                       
   LOCAL cBuffer := ::oBmp:setBuffer()         
                                               
   IF Valtype( ::dataLink ) == "B" .AND. .NOT. ::lIsEmpty
      Eval( ::dataLink, cBuffer )              
   ENDIF                                       
RETURN cBuffer                                 
                                               
                                               
METHOD BitmapRef:editbuffer                    
RETURN ::oBmp:setBuffer()                      
                                               
                                               
                                               
/*                                             
 * Bitmap zeichnen                             
 */                                            
METHOD BitmapRef:draw( aClip )                 
   LOCAL aSize    := ::currentSize()           
   LOCAL aTarget, aSource, nAspect, lRet       
                                               
   /*                                          
    * Clip Bereich vorbereiten                 
    */                                         
   DEFAULT aClip TO { 1, 1, aSize[1]-1, aSize[2]-1 }
   GraPathBegin( ::oPS )                       
   GraBox( ::oPS, { aClip[1]-1, aClip[2]-1 }, { aClip[3]+1, aClip[4]+1 }, GRA_OUTLINE )
   GraPathEnd( ::oPS )                         
   GraPathClip( ::oPS, .T. )                   
                                               
   GraBox( ::oPS, {1,1}, {aSize[1]-2,aSize[2]-2}, GRA_FILL )
                                               
   IF ::lIsEmpty                               
      RETURN .F.                               
   ENDIF                                       
                                               
   aSource := {0,0,::oBmp:xSize,::oBmp:ySize}  
   aTarget := {1,1,aSize[1]-2,aSize[2]-2}      
                                               
   IF ::autoScale                              
      nAspect    := aSource[3] / aSource[4]    
      IF nAspect > 1                           
         aTarget[4] := aTarget[3] / nAspect    
      ELSE                                     
         aTarget[3] := aTarget[4] * nAspect    
      ENDIF                                    
   ELSE                                        
      aTarget[3] := aSource[3]                 
      aTarget[4] := aSource[4]                 
   ENDIF                                       
                                               
   IF aTarget[3] < aSize[1]-2                  
      nAspect := ( aSize[1]-2-aTarget[3] ) / 2 
      aTarget[1] += nAspect                    
      aTarget[3] += nAspect                    
   ENDIF                                       
                                               
   IF aTarget[4] < aSize[2]-2                  
      nAspect := ( aSize[2]-2-aTarget[4] ) / 2 
      aTarget[2] += nAspect                    
      aTarget[4] += nAspect                    
   ENDIF                                       
                                               
   lRet := ::oBmp:draw( ::oPS, aTarget, aSource, , GRA_BLT_BBO_IGNORE )
                                               
   GraPathClip( ::oPS, .F. )                   
                                               
RETURN lRet                                    
                                               
                                               
                                               
/*                                             
 * Externe Bitmap Datei laden                  
 */                                            
METHOD BitmapRef:loadFile( cBitmap )           
   IF ( ::changed := ::oBmp:loadFile( cBitmap ) )
      ::lIsEmpty := .F.                        
   ENDIF                                       
RETURN ::changed                               
