////////////////////////////////////////

#include "Appevent.ch"
#include "Xbp.ch"
#include "Common.ch"
#include "Gra.ch"
#include "Xbp.ch"
#include "Font.ch"
#include "FileIO.ch"
#include "Directry.ch"
#include "\bestatt\aaa\prgx\Ezscan.ch"
//#include 'bap.ch'
#include "\bestatt\aaa\prgx\eztw32.ch"    //+25.12.2008 22:15


#define BYTE    CHR(0)
#define WORD    BYTE+BYTE
#define DWORD   WORD+WORD
#define LONG    DWORD+DWORD
#define NULL    0

/*
 * Im Programm werden benutzerdefinierte Ereignisse verwendet
 */
#define  xbeDS_DirChanged           xbeP_User + 100
#define  xbeFS_FileMarked           xbeP_User + 101
#define  xbeFS_FileSelected         xbeP_User + 102

/*
 * Die Direktive berechnet eine zentrierte Position
 */
#xtrans  CenterPos( <aSize>, <aRefSize> ) => ;
         { Int( (<aRefSize>\[1] - <aSize>\[1]) / 2 ) ;
         , Int( (<aRefSize>\[2] - <aSize>\[2]) / 2 ) }



//+22.07.2008 11:41 geREMt: Static oDlg

/* 23.06.2008 18:50 geREMt, weil doppelt:
FUNCTION AppSys()
Return(Nil)
geREMt   */

function ausgang()
   if nEztwDll # 0
      eztw32_UnLoadDll()
   endif
   PostAppEvent(xbeP_Close)
return (Nil)

function dummy()
return .f.

/*PROCEDURE Main umbenannt 23.06.2008 18:52 */
//+05.02.2010 18:26 cBildDateiF, damit der volle Name zurckgegeben werden kann
PROCEDURE Scan(cScanArt,cBildDatei,cBildDateiF) //+22.07.2008 09:55 cScanArt oder cBildDatei wird vorgegeben
   LOCAL nEvent, mp1, mp2, oXbp
   LOCAL oMenuBar, oSubMenu
//   LOCAL bBlock := {|| ausgang() }
   LOCAL cTime := Time(), nA := SELECT()      //+22.07.2008 09:59
   PRIVATE oDlg := SetAppWindow()            //+26.09.2008 21:04
   PRIVATE cANr := StrX(1->auftrnr)          //+26.09.2008 21:03
//   PRIVATE oDlg := IIf(ValType(cScanArt)=="C",oScrap:BEArea[1]:cargo, ;
//                     IIf(ValType(cBildDatei)=="C",oScan:BEArea[1]:cargo,SetAppWindow() ) )   //+22.07.2008 11:16
   PRIVATE nEztwDll := 0, nDibHnd := 0    //+22.07.2008 11:16 vorher Public

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+06.06.2010 22:20 Scannen mit externem Programm i_view32.exe
   IF FILE(cDatver+"iview","D")
      cBildDateiF := AllTrim(cBildDatei)+".jpg" //+ komplett mit Pfad - zum Zurckgeben
      oBest:ScanExtProg( cDatver+"iview\i_view32.exe", "/scan", cANr+AllTrim(cBildDatei)+".jpg" )
//      oBest:ScanExtProg( cDatver+"iview\i_view32.exe", "/scan", StrX(1->auftrnr)+"-"+AllTrim(oScan:cScan2)+".jpg" )  //+12.06.2010 12:16

      IF Upper(AppName())$"NOLTEX.EXE"
         AlertBox( , "Sie k”nnen jetzt das Dokument entnehmen!"        + ;
                    ";", ;
                    { "_OK" }  , ;
                    XBPSTATIC_SYSICON_ICONWARNING    , ;
                    "Der Scanner ist jetzt fertig!" )    //+15.11.2009 17:41
      ELSE
         MsgBox( IIf(SET(43)==0,ConvToAnsiCP("Sie k”nnen jetzt das Dokument entnehmen!"), ;
                     "Sie k”nnen jetzt das Dokument entnehmen!"), "Der Scanner ist fertig!" )  //+22.07.2008 10:10
      ENDIF
      RETURN
   ENDIF
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//////   set excl OFF
//////   SET TALK OFF
//////   set cons OFF
//////   set conf on
//////   set exac OFF
//////   set scor OFF
//////   set inte on
//////   set dele on
//////   set date GERM
//////   set epoch to 1980
//////   set century on

   nEztwDll := eztw32_LoadDll()
   if nEztwDll == 0
  // could not load the eztw32.dll
     return
   endif
   
   eztw32_RegisterApp(1,0,TWLG_GER,TWCY_GERMANY,"1.0 Beta","OK","xBase++","EZTWAIN xBase++ Wrapper")
   eztw32_SetAppTitle("EZTWAIN xBase++ Wrapper")

//   JpegAvailable()

   DO CASE
//////      CASE ValType(cScanArt)=="C" .AND. "AV"$Upper(cScanArt)
//////         IF Len(Trim((nA)->ausw_art[1]))>0
//////            IF FILE( cDatver+"Scans\"+cANr+"A"+1->ausw_art[1]+"????????"+"V"+".*" )
//////               IF ConfirmBox( oCB, "<JA> = trotzdem scannen", ;
//////                        IIf(SET(43)==0,ConvToAnsiCP("Es existiert bereits schon eine Scandatei!"), ;
//////                        "Es existiert bereits schon eine Scandatei!"), ;
//////                        XBPMB_YESNO, ;
//////                        XBPMB_CRITICAL, ;
//////                        XBPMB_DEFBUTTON2 ) ;
//////                        =  XBPMB_RET_NO
//////                  RETURN
//////               ENDIF
//////            ENDIF
//////            Satzsp(oCB)
//////            cBildDatei := cANr+"A"+(nA)->ausw_art[1]+DtoS((nA)->ausw_scn_v:=DATE())+"V"
//////            DbRUnlock(RecNo())
//////         ELSE
//////            cBildDatei := BildDateiName("AV")
//////            IF Len(cBildDatei) = 0
//////               RETURN
//////            ENDIF
//////         ENDIF
//////         austofile( cBildDateiF := cDatver+"Scans\"+cBildDatei )      //+05.02.2010 18:24
//////      CASE ValType(cScanArt)=="C" .AND. "AR"$Upper(cScanArt)
//////         IF Len(Trim((nA)->ausw_art[1]))>0
//////            IF FILE( "Scans\"+cANr+"A"+1->ausw_art[1]+"????????"+"R"+".*" )
//////               IF ConfirmBox( oCB, "<JA> = trotzdem scannen", ;
//////                        IIf(SET(43)==0,ConvToAnsiCP("Es existiert bereits schon eine Scandatei!"), ;
//////                        "Es existiert bereits schon eine Scandatei!"), ;
//////                        XBPMB_YESNO, ;
//////                        XBPMB_CRITICAL, ;
//////                        XBPMB_DEFBUTTON2 ) ;
//////                        =  XBPMB_RET_NO
//////                  RETURN
//////               ENDIF
//////            ENDIF
//////            Satzsp(oCB)
//////            cBildDatei := cANr+"A"+(nA)->ausw_art[1]+DtoS((nA)->ausw_scn_r:=DATE())+"R"
//////            DbRUnlock(RecNo())
//////         ELSE
//////            cBildDatei := BildDateiName("AR")
//////            IF Len(cBildDatei) = 0
//////               RETURN
//////            ENDIF
//////         ENDIF
//////         austofile( cBildDateiF := cDatver+"Scans\"+cBildDatei )      //+05.02.2010 18:24
//////      CASE ValType(cScanArt)=="C" .AND. "VV"$Upper(cScanArt)
//////            IF FILE( "Scans\"+cANr+"V"+1->voll_art[1]+"????????"+".*" )
//////               IF ConfirmBox( oCB, "<JA> = trotzdem scannen", ;
//////                        IIf(SET(43)==0,ConvToAnsiCP("Es existiert bereits schon eine Scandatei!"), ;
//////                        "Es existiert bereits schon eine Scandatei!"), ;
//////                        XBPMB_YESNO, ;
//////                        XBPMB_CRITICAL, ;
//////                        XBPMB_DEFBUTTON2 ) ;
//////                        =  XBPMB_RET_NO
//////                  RETURN
//////               ENDIF
//////            ENDIF
//////         IF Len(Trim((nA)->voll_art[1]))>0
//////            Satzsp(oCB)
//////            cBildDatei := cANr+"V"+(nA)->voll_art[1]+DtoS((nA)->voll_scn_v:=DATE())
//////            DbRUnlock(RecNo())
//////         ELSE
//////            cBildDatei := BildDateiName("VV")
//////            IF Len(cBildDatei) = 0
//////               RETURN
//////            ENDIF
//////         ENDIF
//////            austofile( cBildDateiF := cDatver+"Scans\"+cBildDatei )   //+05.02.2010 18:24
//////      CASE ValType(cScanArt)=="C" .AND. "UI"$Upper(cScanArt)
//////         Satzsp(oCB)
//////         cBildDatei := cANr+"UIDN"+DtoS((nA)->uidn_scn_v:=DATE())
//////         DbRUnlock(RecNo())
//////         austofile( cBildDateiF := cDatver+"Scans\"+cBildDatei )   //+05.02.2010 18:24
      //+13.12.2008 16:38 'BILD' scannt Bilder ins Bilder-Verzeichnis:
      CASE ValType(cBildDatei) == "C" .AND. cBildDatei = "-2"
         cBildDatei := IIf( Len(AllTrim(cBildDatei))>0, cANr+AllTrim(cBildDatei), ;
                          cANr + "_" + DtoS(DATE()) + "_" + ;
                          SubStr(cTime,1,2)+SubStr(cTime,4,2)+SubStr(cTime,7,2) )
         austofile( cDatver+"Scans2\Bilder\"+cBildDatei )
      //+13.12.2008 16:38 'SCAN' scannt ins eingestellte File-View-Verzeichnis:
      CASE ValType(cBildDatei) == "C"
         cBildDatei := IIf( Len(AllTrim(cBildDatei))>0, cANr+AllTrim(cBildDatei), ;
                          cANr + "_" + DtoS(DATE()) + "_" + ;
                          SubStr(cTime,1,2)+SubStr(cTime,4,2)+SubStr(cTime,7,2) )
//         austofile( cDatver+"Scans2\"+cBildDatei )
//         austofile( cBildDateiF := cDatver+"Scans2\"+cBildDatei )  //+05.02.2010 18:24
         austofile( cBildDateiF := oEdit:oDirs:CurDir() +"\"+ cBildDatei ) //+21.11.2010 12:19
      OTHERWISE   //+ wenn keine cBildDatei angegeben wurde:
         cBildDatei := cANr+"-"+DtoS(DATE())+"-"+SubStr(cTime,1,2)+SubStr(cTime,4,2)+SubStr(cTime,7,2)
//         austofile( cDatver+"Scans2\"+cBildDatei )
//         austofile( cBildDateiF := cDatver+"Scans2\"+cBildDatei )  //+05.02.2010 18:25
         austofile( cBildDateiF := oEdit:oDirs:CurDir() +"\"+ cBildDatei ) //+21.11.2010 12:21
   ENDCASE
   MsgBox( "Sie k”nnen jetzt das Dokument entnehmen!", "Der Scanner ist fertig!" )  //+22.07.2008 10:10
RETURN

//* Automatische Bilddatei erzeugen, ggf mit Sondernamen.
FUNCTION BildDateiName(cScanArt)
   LOCAL cTime := Time()
   LOCAL cBildDatei := "_"+DtoS(DATE())+"-"+SubStr(cTime,1,2)+SubStr(cTime,4,2)+SubStr(cTime,7,2)
   LOCAL Wahl := ConfirmBox( oCB, ;
                           IIf(SET(43)==0,ConvToAnsiCP("M”chten Sie die Daten automatisch komplettieren?"), ;
                           "M”chten Sie die Daten automatisch komplettieren?")+CRLF+ ;
                           IIf(SET(43)==0,ConvToAnsiCP("<JA> damit ein richtiger Dateiname entsteht: Scannen!"), ;
                           "<JA> damit ein richtiger Dateiname entsteht: Scannen!")+CRLF+ ;
                           IIf(SET(43)==0,ConvToAnsiCP("<Nein> der Dateiname ist jetzt nicht wichtig: Scannen!"), ;
                           "<Nein> der Dateiname ist jetzt nicht wichtig: Scannen!")+CRLF+ ;
                           IIf(SET(43)==0,ConvToAnsiCP("<ESC> Scannen abbrechen und erst Daten eingeben"), ;
                           "<ESC> Scannen abbrechen und erst Daten eingeben"), ;
                           IIf(SET(43)==0,ConvToAnsiCP("Es fehlen noch Eingaben!"), ;
                           "Es fehlen noch Eingaben!"), ;
                           XBPMB_YESNOCANCEL, ;
                           XBPMB_QUESTION )

         IF Wahl == XBPMB_RET_YES
            DO CASE
               CASE cScanArt == "AV"
                  Satzsp(oCB)
                  1->ausw_art := "Ausweis"
                  cBildDatei := cANr+"A"+1->ausw_art[1]+DtoS(1->ausw_scn_v:=DATE())+"V"
                  DbRUnlock(RecNo())
               CASE cScanArt == "AR"
                  Satzsp(oCB)
                  1->ausw_art := "Ausweis"
                  cBildDatei := cANr+"A"+1->ausw_art[1]+DtoS(1->ausw_scn_v:=DATE())+"R"
                  DbRUnlock(RecNo())
               CASE cScanArt == "VV"
                  Satzsp(oCB)
                  1->voll_art := "Brief"
                  cBildDatei := cANr+"V"+1->voll_art[1]+DtoS(1->voll_scn_v:=DATE())
                  DbRUnlock(RecNo())
               ENDCASE
         ELSEIF Wahl == XBPMB_RET_CANCEL
            cBildDatei := ""
         ENDIF
            
RETURN cBildDatei


PROCEDURE DerRestVonMain()
   oDlg := XbpDialog():new( AppDesktop(), , {0,20}, {800,580}, , .F.)
   oDlg:taskList := .T.
   oDlg:title := "Samples for EZTWAIN xBase++ Wrapper"
   oDlg:drawingArea:new( , ,{0,20}, {800,540}, , .F.)
   oDlg:create()


   eztw32_RegisterApp(1,0,TWLG_GER,TWCY_GERMANY,"1.0 Beta","OK","xBase++","EZTWAIN xBase++ Wrapper")
   eztw32_SetAppTitle("EZTWAIN xBase++ Wrapper")

//   eztw32_TestParam()
//   eztw32_GetVersion()
//   eztw32_IsTwainAvailable()
//   eztw32_GetMultiTransfer()
//   eztw32_GetTwainState()
//  eztw32_GetSourceName()
//  eztw32_IsJpegAvailable()
//  eztw32_GetSaveFormat()
//  eztw32_GetSourceList()
//   austofile()

   oMenuBar := oDlg:MenuBar()

   oSubMenu := XbpMenu():new():create()
   oSubMenu:cargo := {}
   oSubMenu:title := '~File'

   oSubMenu:addItem({ 'Select Image Source',  {|| selectds() } })
   oSubMenu:addItem({ 'Acquire from Source',  {|| acqfromds() } } )
   oSubMenu:addItem({ 'Acquire und Save to File',  {|| austofile() } } )
   oSubMenu:addItem({ 'Acquire to Clipboard',  {|| austoclip() } } )
   oSubMenu:addItem({ 'Save to File',  {|| savetofile() } } )
   oSubMenu:addItem({ 'ViewFile',  {|| fileview() } } )
   oSubMenu:addItem({ 'E~xit', bBlock } )

   oMenuBar:addItem( { oSubMenu, NIL } )

   oSubMenu := XbpMenu():new():create()
   oSubMenu:cargo := {}
   oSubMenu:title := '~Utils'

   oSubMenu:addItem({ '~Self Test' , {|| selftest() } } )
   oSubMenu:addItem({ '~EZTWAIN Version' , {|| ezversion() } } )
   oSubMenu:addItem({ '~Build name' , {|| ezbname() } } )
   oSubMenu:addItem({ '~Parameter test' , {|| parmtest() } } )
   oSubMenu:addItem({ '~Test if twain available' , {|| TwainAvailable() } } )
   oSubMenu:addItem({ '~Test if Jpeg available' , {|| JpegAvailable() } } )
   oSubMenu:addItem({ '~Status of Twain' , {|| Twainstat() } } )
   oSubMenu:addItem({ '~Current DS' , {|| currentds() } } )
   oSubMenu:addItem({ '~Default DS' , {|| defaultds() } } )
   oSubMenu:addItem({ '~Enable Logfile' , {|| elogfile() } } )
   oSubMenu:addItem({ '~Disable Logfile' , {|| dlogfile() } } )

   oMenuBar:addItem( { oSubMenu, NIL } )

   oSubMenu := XbpMenu():new():create()
   oSubMenu:cargo := {}
   oSubMenu:title := '~?'

   oSubMenu:addItem({ '~Function List Part one'  , {|| showfunctionlist("FUNCTION.NO1","function list of eztwain wrapper Part 1") } } )
   oSubMenu:addItem({ '~Function List Part two'  , {|| showfunctionlist("FUNCTION.NO2","function list of eztwain wrapper Part 1") } } )
   oSubMenu:addItem({ '~Functions not ported'  , {|| showfunctionlist("FUNCTION.NOT","functions not ported") } } )
   oSubMenu:addItem({NIL, NIL, XBPMENUBAR_MIS_SEPARATOR, 0  } )
   oSubMenu:addItem({ '~Info'      , {|| infomsg() } } )

   oMenuBar:addItem( { oSubMenu, NIL } )

   oDlg:show()

   setAppWindow(oDlg)
   setAppFocus(oDlg)
//   eztw32_SelectImageSource()

   nEvent := 0
   DO WHILE nEvent <> xbeP_Close
      nEvent := AppEvent( @mp1, @mp2, @oXbp )
      oXbp:HandleEvent( nEvent, mp1, mp2 )
   ENDDO
   oDlg:destroy()    //23.06.2008 22:27
RETURN


static procedure infomsg
msgbox("Samples for EZTWAIN xBase++ Wrapper")
return

*+
static procedure selftest
local lResult := eztw32_selftest()
msgbox("self test was "+iif(lResult,"successful","failed"))
return

static procedure ezversion
msgbox("EZTWAIN Version: "+str(eztw32_GetVersion()/100,4,2))
return

static procedure ezbname
local psName := space(255)
eztw32_GetBuildName(@psname)
msgbox("build name of eztwain: "+psName)
return

static procedure parmtest
eztw32_TestParam()
return

static procedure TwainAvailable
local lResult := eztw32_IsTwainAvailable()
msgbox("twain available ? "+iif(lResult,"YES","NO"))
return

static procedure JpegAvailable
local lResult := eztw32_IsJpegAvailable()
msgbox("Jpeg available ? "+iif(lResult,"YES","NO")+chr(10)+;
       iif(lResult,"Jpeg quality: "+str(eztw32_GetJpegQuality()),""))
return

static procedure TwainStat
local nResult := eztw32_GetTwainState()
msgbox("Twain State: "+statemsg(nResult))
return

static procedure currentds
msgbox(eztw32_GetSourceName())
return

static procedure defaultds
msgbox(eztw32_GetDefaultSourceName())
return

static procedure elogfile
eztw32_LogFile(ENABLE_LOGFILE)
return

static procedure dlogfile
eztw32_LogFile(DISABLE_LOGFILE)
return

*+
static procedure selectds
//eztw32_SelectImageSource(oDlg:getHWND())
if !eztw32_SelectImageSource()
msgbox("can't select image source")
endif
return

static procedure acqfromds
local cdefsourec := eztw32_GetDefaultSourceName()
nDibHnd := eztw32_Acquire(oDlg:getHWND())
return

*+
static procedure savetofile
eztw32_DIB_WriteToBmp(nDibHnd,"MYTEST.BMP")
eztw32_FreeNative(nDibHnd)
return

*+
static procedure austofile( cDateiName )  /*29.06.2008 17:28*/
local nStatus
local cdefsourec := eztw32_GetDefaultSourceName()
local cFileExt := ""
// Get current Jpeg quality
//if eztw32_IsJpegAvailable()
//   eztw32_GetJpegQuality()
//   // Set Jpeg quality to 60
//   eztw32_SetJpegQuality(60)
//   // Set save format to Jpeg
//   eztw32_SetSaveFormat(TWFF_JFIF)
//  // acquire from source and save it to current save format
//  cFileExt := "JPG"
//else
   eztw32_SetSaveFormat(TWFF_BMP)
  cFileExt := "BMP"
//endif
nStatus := eztw32_AcquireToFilename(oDlg:getHWND(),cDateiName+"."+cFileExt) /*29.06.2008 17:29*/
IF nStatus # 0
   dis_err_msg(nStatus)
endif
return

*+
static procedure austoclip
eztw32_GetDefaultSourceName()
if eztw32_AcquireToClipboard(oDlg:getHWND(),TWAIN_ANYTYPE)
   nDibHnd := eztw32_DIB_GetFromClipboard()
   eztw32_DIB_WriteToBmp(nDibHnd,"MYTEST.BMP")
   eztw32_FreeNative(nDibHnd)
else
   msgbox("Error - code is: "+str(eztw32_LastErrorCode()),"TWAIN Error")
endif
return

*+

static procedure dis_err_msg(nStatus)
do case
   case nStatus = -1
      msgbox("the Acquire failed.")
   case nStatus = -2
      msgbox("file open error (invalid path or name, or access denied)")
   case nStatus = -3
      msgbox("invalid DIB, or image incompatible with file format, or...")
   case nStatus = -4
      msgbox("writing failed, possibly output device is full.")
   case nStatus = -10
      msgbox("user cancelled File Save dialog")
   otherwise
      msgbox("Error code: "+str(nStatus))
endcase
return

static function statemsg(state)
local smsg
do case
   case state == 1
      smsg := "source manager not loaded"
   case state == 2
      smsg := "source manager loaded"
   case state == 3
      smsg := "source manager open"
   case state == 4
      smsg := "source open but not enabled"
   case state == 5
      smsg := "source enabled to acquire"
   case state == 6
      smsg := "image ready to transfer"
   case state == 7
      smsg := "image in transit"
   otherwise
      smsg := str(state)
endcase
return smsg

/*
 * Die Main Prozedur erzeugt den Image View Dialog
 */
PROCEDURE fileview( oParent, oOwner, oDirs, oFiles, oView )
   LOCAL nEvent, mp1, mp2, oXbp1, olast
   LOCAL oDlg1, drawingArea, aSize := IIf(ValType(oOwner)="O",oOwner:currentsize(),{590,360})
   LOCAL aPos  := IIf(ValType(oOwner)="O",{0,0},CenterPos( aSize, AppDesktop():currentSize() ))
//   LOCAL oDirs, oFiles, oView
   LOCAL oRadio1, oRadio2, endestat := .f.
   DEFAULT oParent TO AppDeskTop()
   
   CurDir("\bestatt\scrapx\scans2")
   oDlg1 := XbpDialog():new( oParent, oOwner, aPos, aSize, , .F. )
   oDlg1:taskList := .T.
   oDlg1:maxButton := .F.
   oDlg1:titlebar := .F.
   oDlg1:border   := XBPDLG_DLGBORDER
   oDlg1:title    := "EZSCAN Samples"
   oDlg1:close    := {|| endestat := .t. }
   oDlg1:create()
   olast := SetAppWindow( oDlg1 )

   drawingArea := oDlg1:drawingArea
   drawingArea:setFontCompoundName( FONT_HELV_SMALL )

   oDirs  := DirSelector():new ( drawingArea, , {5 ,5}, {aSize[1]*0.3,aSize[2]-10} )
   oDirs:tabStop := .T.
   oDirs:startDir := curdrive()+":\"+curdir()
   oDirs:create()

   oFiles := FileSelector():new( drawingArea, , {aSize[1]*0.3+10,5}, {aSize[1]*0.3,aSize[2]-10} )
   oFiles:tabStop := .T.
   oFiles:create()

   oFiles:setFilesTo( oDirs:curDir(), { "*.JPG", "*.EMF", "*.GIF", "*.BMP", "*.PNG", "*.BMP *.EMF *.GIF *.JPG *.PNG"  } )

   oView := ImageView():new( drawingArea, , {aSize[1]*0.6+20,96}, {aSize[1]*0.3,aSize[2]-10} ):create()

   oRadio1 := XbpRadioButton():new( drawingArea, , {387,60}, {72,24} )
   oRadio1:caption   := "Scaled"
   oRadio1:tabStop   := .T.
   oRadio1:selection := oView:autoScale
   oRadio1:create()
   oRadio1:selected  := {|| oRadio2:SetData(.F.), oRadio1:SetData(.T.), ;
                            oView:autoScale := .T., oView:display() }

   oRadio2 := XbpRadioButton():new( drawingArea, , {487,60}, {72,24} )
   oRadio2:caption   := "Normal"
   oRadio2:tabStop   := .T.
   oRadio2:selection := ! oView:autoScale
   oRadio2:create()
   oRadio2:selected  := {|| oRadio1:SetData(.F.), oRadio2:SetData(.T.), ;
                            oView:autoScale := .F., oView:display() }

   oXbp1 := XbpStatic():new( drawingArea, , {372,48}, {204,2} )
   oXbp1:type := XBPSTATIC_TYPE_RAISEDLINE
   oXbp1:create()

   oXbp1 := XbpPushButton():new( drawingArea, , {375,12}, {68,24} )
   oXbp1:caption  := "FullView"
   oXbp1:tabStop  := .T.
   oXbp1:create()
   oXbp1:activate := {|| FullView( oView:file ) }

   oXbp1 := XbpPushButton():new( drawingArea, , {445,12}, {68,24} )
   oXbp1:caption  := "Print"
   oXbp1:tabStop  := .T.
   oXbp1:create()
   oXbp1:activate := {|| DokDruck( oView:file )  }

   oXbp1 := XbpPushButton():new( drawingArea, , {515,12}, {68,24} )
   oXbp1:caption  := "End"
   oXbp1:tabStop  := .T.
   oXbp1:create()
   oXbp1:activate := {|| endestat := .t.  }

   oDlg1:show()
   SetAppFocus( oDirs:dirTree )

   DO WHILE !endestat

      nEvent := AppEvent( @mp1, @mp2, @oXbp1 )

      IF nEvent == xbeDS_DirChanged
         oFiles:setFilesTo( mp1 )

      ELSEIF nEvent == xbeFS_FileMarked
         oView:load( mp1 )
         oView:display()

      ELSE
          oXbp1:handleEvent( nEvent, mp1, mp2 )
      ENDIF
   ENDDO
oDlg1:destroy()
SetAppWindow( olast )
//oDlg:show()
RETURN



/*
 * Die Prozedur zeigt eine Bilddatei in einem eigenen Fenster an
 */
PROCEDURE FullView( cFile )
   LOCAL oDlg1, oImage, oPS, aSize, aPos, oXbp, mp1, mp2, nEvent

  /*
   * Es werden nur Bitmap und Metadateien untersttzt
   */
   IF cFile <> NIL            .AND. ;
     ( ".BMP" $ Upper( cFile ) .OR. ;
       ".EMF" $ Upper( cFile ) .OR. ;
       ".GIF" $ Upper( cFile ) .OR. ;
       ".JPG" $ Upper( cFile ) .OR. ;       
       ".PNG" $ Upper( cFile ) .OR. ;
       ".MET" $ Upper( cFile )      )

     /*
      * Dialog versteckt erzeugen
      */
      oDlg1 := XbpDialog():new( AppDesktop(),,,{100,100} )
//      oDlg1 := XbpDialog():new( aThrdFenster[1],,,{100,100} )
      oDlg1:taskList := .F.
      oDlg1:visible  := .F.
      oDlg1:title    := cFile
      oDlg1:close    := {|mp1,mp2,obj| obj:destroy() }
      oDlg1:create()


     /*
      * Presentation Space erzeugen, der mit dem Device-Kontext der
      * drawingArea verknpft wird
      */
      oPS := XbpPresSpace():new():create( oDlg1:drawingArea:winDevice() )

      IF ".BMP" $ Upper( cFile ) .OR. ;
         ".GIF" $ Upper( cFile ) .OR. ;
         ".JPG" $ Upper( cFile ) .OR. ;       
         ".PNG" $ Upper( cFile )

        /*
         * Datei enth„lt eine Bitmap. Die Gr”áe des Fensters wird
         * begrenzt auf 16x16 Pixel und die Bildschirmaufl”sung
         */
         oImage   := XbpBitmap():new():create( oPS )
         oImage:loadFile( cFile )

         aSize    := { oImage:xSize, oImage:ySize }
         aSize[1] := Max( 16, Min( aSize[1], AppDeskTop():currentSize()[1] ) )
         aSize[2] := Max( 16, Min( aSize[2], AppDeskTop():currentSize()[2]-30 ) )
//*14.07.2008 11:26         aSize    := oDlg1:calcFrameRect( {0,0, aSize[1], aSize[2]} )
         aSize    := autoscale( {0,0, aSize[1], aSize[2]}, oImage )

         oDlg1:setSize( {aSize[3], aSize[4]} )

         /*
          * Das Fenster muá auf xbeP_Paint reagieren und
          * die Bitmap neu anzeigen
          */
         oDlg1:drawingarea:paint := {|x,y,obj| x:=obj:currentSize(), ;
                                     oImage:draw( oPS, {0, 0, x[1], x[2]}, ;
                                     {0, 0, oImage:xSize, oImage:ySize},,;
                                     GRA_BLT_BBO_IGNORE), Sleep(0.1) }
      ELSE
        /*
         * Metadatei anzeigen. Sie haben keine feste Gr”áendefinition
         */
         oImage := XbpMetafile():new():create()
         oImage:load( cFile )
         aSize := { 600, 400 }
         oDlg1:setSize( aSize )
         oDlg1:drawingarea:paint := {|| oImage:draw( oPS, XBPMETA_DRAW_SCALE ), Sleep(0.1) }

      ENDIF


     /*
      * Fenster zentriert auf dem Desktop anzeigen
      */
//*      aPos:= CenterPos( oDlg1:currentSize(), AppDesktop():currentSize() )
      aPos := {0,30}
      oDlg1:setPos( aPos )
      oDlg1:show()
      SetAppFocus( oDlg1 )
      nEvent := 0
      DO WHILE nEvent <> xbeP_Close
         nEvent := AppEvent( @mp1, @mp2, @oXbp )
         oXbp:HandleEvent( nEvent, mp1, mp2 )
      ENDDO
   ENDIF
RETURN

//*14.07.2008 11:27 damit das Gr”áenverh„ltniss stimmt:
FUNCTION autoscale(ASize,oBitmap)
   LOCAL nAspect, nKorrektur := 0.6
   LOCAL aSource := {0,0,Max(oBitmap:xSize*nKorrektur,1),Max(oBitmap:ySize,1)}
   LOCAL aTargetUr := IIf(Len(aSize)=2,{1,1,aSize[1]-2,aSize[2]-2},ASize)
   LOCAL aTarget := AClone(aTargetUr)
//      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
         aTarget[1] += nAspect
         aTarget[3] += nAspect
      ENDIF
      IF aTarget[4] < aTargetUr[4]
         nAspect := (aTargetUr[4]-aTarget[4])/2
         aTarget[2] += nAspect
         aTarget[4] += nAspect
      ENDIF
RETURN aTarget
/////////////////////////////////////////////////////////////////////


///////*22.11.2008 11:07: verschoben nach AAA\PRGX\BitDirFile.PRG
////// * Klasse zum Anzeigen von Bitmaps oder Metadateien
////// */
//////CLASS ImageView FROM XbpStatic
//////   PROTECTED:
//////   VAR oFrame
//////   VAR oCanvas
//////   VAR oPS
//////   VAR oBitmap
//////   VAR oMetafile
//////   VAR nMode
//////
//////   EXPORTED:
//////   VAR autoScale
//////   VAR FILE
//////   VAR Resolution       //+29.09.2008 15:10 tats„chliche Aufl”sung in Px/m
//////   VAR aPhysSize        //+29.09.2008 15:10 tats„chliche Abmessung in 1/10 mm {h,v}
//////   
//////   METHOD init, create, load, DISPLAY, autoscale
//////ENDCLASS
//////
//////
//////
///////*
////// * Objekt initialisieren. Self ist Parent fr zwei XbpStatic Objekte
////// */
//////METHOD ImageView:init( oParent, oOwner, aPos, aSize, aPresParam, lVisible )
//////   ::xbpStatic:init( oParent, oOwner, aPos, aSize, aPresParam, lVisible )
//////   ::xbpStatic:type := XBPSTATIC_TYPE_RAISEDRECT
//////
//////   ::oFrame         := XbpStatic():new( self )
//////   ::oFrame:type    := XBPSTATIC_TYPE_RECESSEDRECT
//////
//////   ::oCanvas        := XbpStatic():new( self )
//////   ::autoScale      := .T.
//////   ::nMode          := 0
//////   ::oPS            := XbpPresSpace():new()
//////   ::file  := ""
//////RETURN self
//////
//////
//////
///////*
////// * Systemresourcen anfordern. Self ist der „uáere Rahmen, ::oFrame ist der
////// * innere Rahmen und in ::oCanvas wird das Bild gezeichnet
////// */
//////METHOD ImageView:create( oParent, oOwner, aPos, aSize, aPresParam, lVisible )
//////   LOCAL aAttr[ GRA_AA_COUNT ]
//////
//////   ::xbpStatic:create( oParent, oOwner, aPos, aSize, aPresParam, lVisible )
//////   aSize    := ::currentSize()
//////   aSize[1] -= 8
//////   aSize[2] -= 8
//////
//////   ::oFrame:create(self,, {4,4}, aSize )
//////
//////   aSize[1] -= 2
//////   aSize[2] -= 2
//////
//////   ::oCanvas:create(::oFrame,, {1,1}, aSize )
//////
//////  /*
//////   * Presentation Space mit dem Device Kontext von XbpStatic verbinden
//////   */
//////   ::oPS:create( ::oCanvas:winDevice() )
//////   aAttr[ GRA_AA_COLOR ] := GRA_CLR_BACKGROUND
//////   ::oPS:setAttrArea( aAttr )
//////   ::oCanvas:paint := {| aClip | ::display( aClip ) }
//////
//////RETURN self
//////
//////
//////
///////*
////// * Bilddatei laden
////// */
//////METHOD ImageView:load( cFile )
//////   LOCAL lSuccess := .F.
//////   LOCAL nHandle, cBuffer := Space(50)
//////
//////   IF Valtype( cFile ) <> "C" .OR. ! File( cFile )
//////      RETURN lSuccess
//////   ENDIF
//////
//////   ::nMode := 0
//////   ::file  := ""
//////
//////   IF ".BMP" $ Upper( cFile ) .OR. ;
//////      ".GIF" $ Upper( cFile ) .OR. ;
//////      ".JPG" $ Upper( cFile ) .OR. ;       
//////      ".PNG" $ Upper( cFile )
//////
//////      IF ::oBitmap == NIL
//////         ::oBitmap := XbpBitmap():New():create( ::oPS )
//////      ENDIF
//////
//////      IF ( lSuccess := ::oBitmap:loadFile( cFile ) )
//////         ::nMode := 1
//////         ::file := cFile
//////       //+29.09.2008 15:14: Resolution und Abmessung bestimmen:
//////         nHandle := FOpen(::FILE,FO_READ)
//////         IF FRead(nHandle,@cBuffer,50) == 50
//////            ::Resolution := Max(Bin2I(SubStr(cBuffer,39,4)),1)     //+ Aufl”sung in Px/m (1m=10000* 1/10mm)
//////            ::aPhysSize  := {::oBitmap:xsize * 10000 / ::Resolution, ;
//////                             ::oBitmap:ysize * 10000 / ::Resolution }   //+ Gr”áe in 1/10 mm
//////            FClose(nHandle)
//////         ENDIF
//////      ENDIF
//////
//////   ELSEIF ".EMF" $ Upper( cFile ) .OR. ".MET" $ Upper( cFile )
//////      IF ::oMetafile == NIL
//////         ::oMetafile := XbpMetafile():New():create()
//////      ENDIF
//////
//////      IF ( lSuccess := ::oMetafile:load( cFile ) )
//////         ::nMode := 2
//////         ::file := cFile
//////      ENDIF
//////   ENDIF
//////
//////RETURN lSuccess
//////
//////
//////
///////*
////// * Bilddatei anzeigen
////// */
//////METHOD ImageView:display( aClip )
//////   LOCAL lSuccess := .F.
//////   LOCAL aSize    := ::oCanvas:currentSize()
//////   LOCAL aTarget, aSource, nAspect
//////
//////   /*
//////    * 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, {0,0}, aSize, GRA_FILL )
//////
//////   DO CASE
//////   CASE ::nMode == 1
//////     /*
//////      * Eine Bitmap Datei ist geladen
//////      */
//////      aSource := {0,0,::oBitmap:xSize,::oBitmap:ySize}
//////      aTarget := {1,1,aSize[1]-2,aSize[2]-2}
//////
//////      IF ::autoScale
//////        /*
//////         * Bitmap wird auf die Gr”áe von ::oCanvas skaliert
//////         */
//////         aTarget := ::autoscale( aTarget, ::oBitmap )
//////////////         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]
//////
//////
//////     /*
//////      * Bitmap in ::oCanvas horizontal oder vertikal zentrieren
//////      */
//////      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
//////      ENDIF
//////
//////      ::oBitmap:draw( ::oPS, aTarget, aSource, , GRA_BLT_BBO_IGNORE )
//////      Sleep(1)
//////
//////   CASE ::nMode == 2
//////     /*
//////      * Eine Metadatei ist geladen
//////      */
//////      IF ::autoScale
//////         ::oMetafile:draw( ::oPS, XBPMETA_DRAW_SCALE )
//////      ELSE
//////         ::oMetafile:draw( ::oPS, XBPMETA_DRAW_DEFAULT )
//////      ENDIF
//////
//////   ENDCASE
//////
//////   GraPathClip( ::oPS, .F. )
//////
//////RETURN lSuccess
//////
////////+ gibt es doch schon als Function hier im PRG-File (s.o.)
//////METHOD ImageView:autoscale(ASize,oBitmap)
//////   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)
//////      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
//////         aTarget[1] += nAspect
//////         aTarget[3] += nAspect
//////      ENDIF
//////      IF aTarget[4] < aTargetUr[4]
//////         nAspect := (aTargetUr[4]-aTarget[4])/2
//////         aTarget[2] += nAspect
//////         aTarget[4] += nAspect
//////      ENDIF
//////RETURN aTarget
//////



/*
 * Klasse zur auswahl von Laufwerken und Verzeichnissen
 */
CLASS DirSelector FROM XbpStatic
   PROTECTED:
   VAR aDrives
   VAR oItem

   EXPORTED:
   VAR startDir
   VAR dirTree
   VAR driveList

   METHOD init, create, fillTree, curDir
ENDCLASS



/*
 * Objekt initialisieren
 */
METHOD DirSelector:init( oParent, oOwner, aPos, aSize, aPresParam, lVisible )

   ::xbpStatic:init( oParent, oOwner, aPos, aSize, aPresParam, lVisible )
   ::xbpStatic:type    := XBPSTATIC_TYPE_RAISEDRECT

   ::dirTree           := XbpTreeView():new( self )
   ::dirTree:tabStop   := .T.
   ::dirTree:hasLines  := .T.
   ::dirTree:hasButtons:= .T.

   ::driveList         := XbpComboBox():new( self )
   ::driveList:tabStop := .T.
   ::driveList:type    := XBPCOMBO_DROPDOWNLIST

   ::startDir          := CurDrive() + ":\" + CurDir()
RETURN self



/*
 * Systemresourcen anfordern und Daten fr das aktuelle Verzeichnis
 * in die Treeview eintragen
 */
METHOD DirSelector:create( oParent, oOwner, aPos, aSize, aPresParam, lVisible )
   ::xbpStatic:create( oParent, oOwner, aPos, aSize, aPresParam, lVisible )

   aSize := ::currentSize()

  /*
   * Die Treeview erzeugt ein benutzerdefiniertes Ereignis und
   * fgt das gew„hlte Verzeichnis als ersten Message-Parameter hinzu
   */
   ::dirTree:create  (,, {4, 30}, {aSize[1]-8, aSize[2]-30-4 } )
   ::dirTree:itemSelected := {|oItem| ::fillTree( oItem ) }
   ::dirTree:itemMarked   := {|oItem| PostAppEvent( xbeDS_DirChanged, oItem:getData() ) }

   ::dirTree:rootItem:setData( ::startDir )

   ::driveList:create(,, {4, 30-4-24-96}, {aSize[1]-8, 24+96 } )

   ::aDrives := AvailDrives()
   AEval( ::aDrives, {|c| ::driveList:xbpListBox:addItem( c+":" ) } )

   IF At( ":", ::startDir ) == 2
      ::driveList:xbpListBox:setData( { AScan( ::aDrives, Left(::startDir,1) ) } )
   ELSE
      ::driveList:xbpListBox:setData( { AScan( ::aDrives, CurDrive() ) } )
   ENDIF
   ::driveList:xbpListBox:itemSelected := {|| ::fillTree() }

   ::fillTree( ::dirTree:rootItem )
RETURN self



/*
 * Treeview mit den Daten des gew„hlten Verzeichnisses aufbauen.
 * Jedes XbpTreeViewItem enth„lt eine Zeichenkette mit dem Verzeichnis,
 * das es anzeigt
 */
METHOD DirSelector:fillTree( oItem )
   LOCAL aItems    := ::dirTree:rootItem:getChildItems()
   LOCAL cDrive    := AllTrim( ::driveList:xbpSLE:getData() )
   LOCAL cDir, aDir, i, imax, nLen, oParent, oTemp, cTemp, oNewParent

   IF oItem <> NIL .AND. ::isVisible() .AND. Len( Directory( oItem:getData() + "\*.", "D" ) ) == 2
      Tone(1000)
      RETURN self
   ENDIF

   ::dirTree:LockUpdate( .T. )

   AEval( aItems, {|obj| ::dirTree:rootItem:delItem(obj) } )
   cDir    := cDrive

  /*
   * Die Treeview beginnt mit dem Laufwerksbuchstaben
   */
   oParent := ::dirTree:rootItem:addItem( cDrive, ICON_DRIVE, ICON_DRIVE, ICON_DRIVE,, cDrive )

   IF oItem == NIL
      oItem := oParent
   ENDIF

   ::oItem := oItem

  /*
   * Fr jedes Unterverzeichnis wird ein XbpTreeviewItem erzeugt
   */
   DO WHILE Upper(cDir) <> Upper(oItem:getData())
      cTemp := SubStr( oItem:getData(), Len(cDir)+2 )
      nLen := At( "\", cTemp ) - 1
      IF nLen < 0
          nLen := len(cTemp)
      ENDIF
      cTemp := SubStr( cTemp, 1, nLen)

      aDir := Directory( cDir + "\", "D" )
      imax := Len( aDir )
      FOR i:=1 TO imax
         IF "D" $ aDir[i,F_ATTR]        .AND. ;
            .NOT. aDir[i,F_NAME] == "." .AND. ;
            .NOT. aDir[i,F_NAME] == ".."
            oTemp := oParent:addItem( aDir[i,F_NAME]   , ;
                                      ICON_CLOSEDFOLDER, ;
                                      ICON_CLOSEDFOLDER, ;
                                      ICON_OPENFOLDER  , ;
                                      NIL              , ;
                                      cDir + "\" + aDir[i,F_NAME] )
            IF Upper( cDir + "\" + aDir[i,F_NAME] ) == Upper( SubStr( oItem:getData(), 1, Len(cDir + "\" + cTemp) ) )
               oNewParent := oTemp
            ENDIF
         ENDIF
      NEXT
      cDir += "\" + cTemp
      oParent:expand(.T.)
      IF oNewParent <> NIL
         oParent := oNewParent
      ENDIF
   ENDDO


  /*
   * XbpTreeViewItems fr die Dateien im untersten Verzeichnis erzeugen
   */
   aDir := Directory( cDir + "\", "D" )

   imax := Len( aDir )
   FOR i:=1 TO imax
      IF "D" $ aDir[i,F_ATTR]        .AND. ;
         .NOT. aDir[i,F_NAME] == "." .AND. ;
         .NOT. aDir[i,F_NAME] == ".."

         oParent:addItem( aDir[i,F_NAME]   , ;
                          ICON_CLOSEDFOLDER, ;
                          ICON_CLOSEDFOLDER, ;
                          ICON_OPENFOLDER  , ;
                          NIL              , ;
                          cDir + "\" + aDir[i,F_NAME] )
      ENDIF
   NEXT

   oParent:expand( .T. )
   ::dirTree:SetData( oParent )

   ::dirTree:LockUpdate( .F. )
   ::dirTree:InvalidateRect()

   PostAppEvent( xbeDS_DirChanged, oParent:getData() )   
RETURN self   



/*
 * Aktuelles ausgew„hltes Verzeichnis zurckgeben
 */
METHOD DirSelector:curDir
RETURN ::oItem:getData()



/*
 * Klasse zur Auswahlt von Dateien mit bestimmten Erweiterungen
 */
CLASS FileSelector FROM XbpStatic
   PROTECTED:
   VAR aFiles
   VAR aExtensions
   VAR oItem
   VAR cDir

   EXPORTED:
   VAR fileList
   VAR extList

   METHOD init, create, setFilesTo, fillFileList, fileMarked, fileSelected
ENDCLASS



/*
 * Objekt initialisieren
 */
METHOD FileSelector:init( oParent, oOwner, aPos, aSize, aPresParam, lVisible )

   ::xbpStatic:init( oParent, oOwner, aPos, aSize, aPresParam, lVisible )
   ::xbpStatic:type := XBPSTATIC_TYPE_RAISEDRECT

   ::fileList         := XbpListBox():new( self )
   ::fileList:tabStop := .T.
   ::extList          := XbpComboBox():new( self )
   ::extList:tabStop  := .T.
   ::extList:type     := XBPCOMBO_DROPDOWNLIST

RETURN self



/*
 * Systemresourcen anfordern
 */
METHOD FileSelector:create( oParent, oOwner, aPos, aSize, aPresParam, lVisible )
   ::xbpStatic:create( oParent, oOwner, aPos, aSize, aPresParam, lVisible )

   aSize := ::currentSize()
   ::fileList:create  (,, {4, 30}        , {aSize[1]-8, aSize[2]-30-4 } )
   ::fileList:itemMarked   := {|| ::fileMarked() }
   ::fileList:itemSelected := {|| ::fileSelected() }
   ::extList:create(,, {4, 30-4-24-96}, {aSize[1]-8, 24+96 } )

   ::aExtensions := { "*.*" }
   AEval( ::aExtensions, {|c| ::extList:xbpListBox:addItem( c ) } )

   ::extList:xbpListBox:setData( { 1 } )
   ::extList:xbpListBox:itemSelected := {|| ::fillFileList() }

RETURN self



/*
 * Verzeichnis und Dateierweiterungen fr die Dateiliste definieren
 */
METHOD FileSelector:setFilesTo( cDir, aExtensions )

   IF Valtype( aExtensions ) == "A"
      ::extList:xbpListBox:clear()
      AEval( aExtensions, {|c| ::extList:xbpListBox:addItem( c ) } )
      ::extList:xbpListBox:setData( { 1 } )
   ENDIF

   IF Valtype( cDir ) == "C"
      ::cDir := cDir
   ENDIF

   ::fillFileList()
RETURN self



/*
 * Listbox mit bereinstimmenden Dateien fllen
 */
METHOD FileSelector:fillFileList()
   LOCAL i, imax, j, jmax, aExtensions := {}
   LOCAL nOffset, cExtension


  /*
   * Liste der Erweiterungen aus der Combobox holen.
   * Als Trennzeichen dient das Leerzeichen
   */
   cExtension := AllTrim( ::extList:xbpSLE:getData() )

   DO WHILE ! Empty( cExtension )
      i := At( " ", cExtension )
      IF i > 0
         AAdd( aExtensions, AllTrim( SubStr( cExtension, 1, i-1 ) ) )
         cExtension := AllTrim( SubStr( cExtension, i+1 ) )
      ELSE
         AAdd( aExtensions, cExtension )
         cExtension := ""
      ENDIF
   ENDDO

   jmax := Len( aExtensions )

   ::fileList:clear()
   ::aFiles  := {}


  /*
   * Listbox mit Dateinamen fllen
   */
   FOR j:=1 TO jmax
      aDir    := Directory( ::cDir + "\" + aExtensions[j] )
      nOffset := Len( ::aFiles )
      imax    := Len( aDir )

      ASize( ::aFiles, nOffset + imax )

      FOR i:=1 TO imax
         ::aFiles[nOffset+i] := aDir[i,F_NAME]
         ::fileList:addItem( aDir[i,F_NAME] )
      NEXT
   NEXT

RETURN self



/*
 * Benutzerdefiniertes Ereignis "Datei ist markiert" plus Dateinamen senden
 */
METHOD FileSelector:fileMarked
   LOCAL aItems := ::fileList:getData()

   IF ! Empty( aItems ) .AND. ! Empty( ::aFiles )
      PostAppEvent( xbeFS_FileMarked, ::cDir + "\" + ::aFiles[ aItems[1] ] )
   ENDIF
RETURN self



/*
 * Benutzerdefiniertes Ereignis "Datei ist gew„hlt" plus Dateinamen senden
 */
METHOD FileSelector:fileSelected
   LOCAL aItems := ::fileList:getData()

   IF ! Empty( aItems ) .AND. ! Empty( ::aFiles )
      PostAppEvent( xbeFS_FileSelected, ::cDir + "\" + ::aFiles[ aItems[1] ] )
   ENDIF

RETURN self



/*
 * Die Funktion gibt ein Array mit den Buchstaben aller verfgbarer
 * Laufwerken auáer Diskettenlaufwerke zurck
 */
#define DRIVE_NOT_READY  21

FUNCTION AvailDrives()
   LOCAL cDrive := CurDrive()
   LOCAL aDrives:= { cDrive }
   LOCAL bError := ErrorBlock( {|oErr| DriveError( oErr, aDrives ) } )

   FOR i:=3 TO 26
      BEGIN SEQUENCE
        Curdrive( Chr(64+i) ) 
        CurDir()
        IF AScan( aDrives, CurDrive() ) == 0
           AAdd( aDrives, Curdrive() )
        ENDIF
      ENDSEQUENCE
   NEXT

   CurDrive( cDrive )

   ErrorBlock( bError )   
RETURN ASort( aDrives )



/*
 * Laufzeitfehler abfangen, wenn ein Laufwerk nicht bereit ist
 */
STATIC PROCEDURE DriveError( oError, aDrives )
   IF oError:osCode == DRIVE_NOT_READY
      AAdd( aDrives, oError:args[1] )
   ENDIF
   BREAK
RETURN

static procedure DokDruck( cFile )
LOCAL oPrinterPS, oBitmap, aRect, aSize
 
oPrinterPS := PrinterPS()
oBitmap    := XbpBitmap():new():create( oPrinterPS )
 
                                         // Papiergröße feststellen 
aSize      := oPrinterPS:device():paperSize()
aRect      := { 0, 0, aSize[1], aSize[2] }
 
oBitmap:loadFile( cFile )          // load Bitmap from file
 
oPrinterPS:device():startDoc()     // Spooler aktivieren

 
oBitmap:draw( oPrinterPS, aRect )  // Druckjob spoolen
 
oPrinterPS:device():endDoc()       // Spooler schließen
 
DestroyDevice( oPrinterPS )        // Resourcen freigeben
oBitmap:destroy()
 
return

/* 23.06.2008 18:50 geREMt, weil doppelt:
// Presentation-Space für einen Drucker erzeugen
FUNCTION PrinterPS()
 LOCAL oPS, oDC := XbpPrinter():new():create()
 
 oPS:=XbpPresSpace():new()
 oPS:create( oDC, oDC:paperSize(), GRA_PU_LOMETRIC )

RETURN oPS
 
// Drucker Device-Context freigeben
PROCEDURE DestroyDevice( oPS )
 LOCAL oDC := oPS:device()
 
 IF .NOT. oDC == NIL
    oPS:configure()          // Device-Context vom PS abhängen
    oDC:destroy()            // und freigeben
 ENDIF

RETURN

geREMt   23.06.2008 18:50  */

// Einfacher Texteditor - XbpMLE()

PROCEDURE showfunctionlist(cXFile, cTitle )
 LOCAL nEvent, mp1, mp2, oXbp
 LOCAL oMLE
 local lExit := FALSE
 local oDl1
 
 // Test-Datei in LOCAL Variable einlesen
 local cText := MemoRead( cXFile )
 if empty(cText)
    msgbox("Dateifehler")
    return
 endif
 
 oDl1 := XbpDialog():new(,,{50,50},{700,450})
 oDl1:title := cTitle
 oDl1:taskList := TRUE
 oDl1:create()

 oDl1:show()

   SetAppWindow(oDl1)
 // MLE erzeugen, Position bei :create() angeben

 // und Datencodeblock mit Zugriff auf LOCAL Variable erzeugen
 oMLE          := XbpMLE():new()
 oMLE:editable :=.T.
 oMLE:wordWrap :=.F.
 oMLE:dataLink := {|x| IIf( x==NIL, cText, cText := x ) }
 oMLE:create( , , {50,50}, {550,350} )
 
 // Text aus LOCAL Variable in Editierpuffer übertragen
 // Das erfolgt via :dataLink
 oMLE:setData()
 
  // Event loop = Programmsteuerung
  nEvent := 0
  DO WHILE nEvent <> xbeP_Close
    nEvent := AppEvent( @mp1, @mp2, @oXbp )
    oXbp:handleEvent( nEvent, mp1, mp2 )
  ENDDO
 
 // Text aus Editierpuffer holen und an LOCAL Variable zuweisen
 // Die Zuweisung erfolgt durch :dataLink
 oMLE:getData()
 
 // Resourcen freigeben
 oMLE:destroy()

 oDl1:destroy()

RETURN
 


