// **********************************************************************
// Use VpeBase3
//
// Version: 1.0
//
// Create:
// Update: 25/09/1998 - Implemented changes in procedures OpenDoc and
//                      SetupPrinter. (Suggested by Peter Starkner, Nordteam)
//         16/09/1998 - Fixed text vertical alignment.
//         06/01/1999 - Changed vertical alignment.
//         12/05/2000 - Updated to use VPE 3.x and changed name to VpeBase3.
//                      Remove the AuxDoc in the process (uses rendering now).
//                      All 3.x changes by Jakob Kruse.
//         07/02/2002 - Compatibility with StarZen's VPE4VDF classes:
//                      Commented out Procedure Vpe_Print (Peter van Mil).
//         12/02/2002 - Uncommented Procedure Vpe_Print (Sture).
//         27/02/2004 - Renamed procedure Vpe_Print to Vpe_Print_Print
//         02/08/2004 - VpeWriteRTF error fixed
//         29/07/2006 - Paper bin functions interfaced by David Lack (taken from the newsgroups)
//                      Vpe_DevEnumPaperBins and Vpe_GetDevPaperBinName
//         03/02/2006 - Modificition suggested by
// ***********************************************************************

Use VPE3X.pkg
Use VPE3X.CFG
Use Files.utl    // Utilities for handling file related stuff
Use WinUser.nui  // User_Windows_User_Name function
Use FList.nui    // A lot of FLIST- procedures and functions
#IFDEF VPE_USE_EMBEDDED_PREVIEW
 Use Embedpre.vw
 Use ErrorHnd.nui // cErrorHandlerRedirector class and oErrorHandlerQuiet object (No User Interface)
#ENDIF
 #IFDEF glMainClientId#
#ELSE
 Use Macros.utl   // Various macros (FOR_EX...)
 desktop_section
   Integer glMainClientId#
   Move 0 to glMainClientId#
   Procedure Set iGlobal_MainClient_Id Integer obj#
     Move obj# to glMainClientId#
   End_Procedure
   Function iGlobal_MainClient_Id Returns Integer
     Integer self#
     ifnot glMainClientId# Begin
       Move Self to self#
       Move (client_id(self#)) to glMainClientId#
     End
     Function_Return glMainClientId#
   End_Function
 end_desktop_section
#ENDIF

Class cVPE is an Array
  Procedure construct_object
    Forward Send construct_object
    Set delegation_mode to delegate_to_parent
    Property DWord   phDoc            Public 0         // Document handle
    Property String  pTitle           Public "Preview"
    property string  pCurFont         public "Arial"
    Property Integer pCurFontSize     public 12
    Property Integer pCurTopMargin    public 200
    Property Integer pCurBottomMargin public 200
    Property Integer pCurLeftMargin   public 200
    Property Integer pCurRightMargin  public 200
    property string  pFont            public "Arial"
    Property Integer pFontSize        public 12
    Property Integer pLeftMargin      public 200
    Property Integer pRightMargin     public 200
    Property Integer pTopMargin       public 200
    Property Integer pBottomMargin    public 200
    property integer pPageWidth       public VPAPER_A4 // VPAPER_LETTER
    Property Integer pPageLength      public 0
    Property DWord   pOpenOptions     public 0
    property integer pBold            public 0
    Property Integer pUnderLine       public 0
    Property Integer pItalics         public 0
    property integer pLandscape       public 0
    // The property pNewPageOnNextLine is tested and set by the following
    // three procedure: NewPage, Write and WriteLn. It was introduced to
    // handle continuos Write/WriteLn across more pages.
    Property Integer pNewPageOnNextLine public 0
  End_Procedure
 // VpeSetAutoBreak - parameters :
  //  AUTO_BREAK_ON              // auto break
  //  AUTO_BREAK_OFF             // limited positioning, rendering
  //  AUTO_BREAK_NO_LIMITS       // none of above
  //  AUTO_BREAK_FULL
  Procedure Vpe_SetAutoBreak Integer liValue
    Integer liGrb
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeSetAutoBreak(lhDoc,liValue)) to liGrb
  End_Procedure
  function sDefaultSetupFileName returns string
    Integer lbCreateError liChannel
    String lsUserName lsFolder
    Get User_Windows_User_Name to lsUserName
    Get FLIST_CurrentFileListFolder to lsFolder
    Get Files_AppendPath lsFolder "VpeSetup" to lsFolder
    If (SEQ_FileExists(lsFolder)=SEQIT_NONE) Begin
      Get wvaWin32_CreateDirectory (ToAnsi(lsFolder)) to lbCreateError
      If lbCreateError Function_Return "c:\vpe3.set"
      Get SEQ_DirectOutput (Files_AppendPath(lsFolder,"readme.txt")) to liChannel
      If (liChannel>=0) Begin
        Writeln channel liChannel "This folder was created automatically to store setup files for the"
        Writeln "Virtual Print Engine (VPE)."
        Writeln ""
        Writeln "These files contain information about the currently selected printer."
        Send SEQ_CloseOutput liChannel
      End
    End
    Get Files_AppendPath lsFolder (lsUserName+".set") to lsUserName // overload
    Function_Return lsUserName
  End_Function
  function Vpe_GetDevice returns string
    DWord lhDoc
    Pointer lpDevice
    String lsDevice
    Integer liGrb
    Move (pad("",255)) to lsDevice
    GetAddress of lsDevice to lpDevice
     send OpenDoc
    Get phDoc to lhDoc
    Move (VpeGetDevice(lhDoc,lpDevice,255)) to liGrb
     send vpe_CloseDoc
    Function_Return (CString(lsDevice))
  End_Function
  Function IsLandscape returns dword
    Integer rval#
    Get Vpe_GetPageOrientation to rval#
    Function_Return (rval# = VORIENTATION_LANDSCAPE)
  End_Function
  Procedure vpe_SelectFont string Font# integer FontSize#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeSetFont(lhDoc,Font#,FontSize#)) to Vpe$ReturnGrb#
    Set pCurFont to Font#
    Set pCurFontSize to FontSize#
  End_Procedure
  Procedure ExportCurMargins
    Integer left# right# top# bottom# Width# Length#
    DWord lhDoc
    Get phDoc to lhDoc
    Get pPageWidth  to Width#
    Get pPageLength to Length#
     // If landscape: switch length and width:
    If (IsLandscape(Self)) Begin
      Move Width# to Left#  // Overload!
      Move Length# to Width#
      Move Left# to Length# // End overload!
    End
     get pCurLeftMargin   to Left#
    Get pCurRightMargin  to Right#
    Get pCurTopMargin    to Top#
    Get pCurBottomMargin to Bottom#
     Move (VpeSet(lhDoc,VLEFTMARGIN,  Left#))           to Vpe$ReturnGrb#
    Move (VpeSet(lhDoc,VRIGHTMARGIN, Width#-Right#))   to Vpe$ReturnGrb#
    Move (VpeSet(lhDoc,VTOPMARGIN,   Top#))            to Vpe$ReturnGrb#
    Move (VpeSet(lhDoc,VBOTTOMMARGIN,Length#-Bottom#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure SetMargins integer left# integer right# integer top# integer bottom#
    Set pCurLeftMargin   to Left#
    Set pCurRightMargin  to Right#
    Set pCurTopMargin    to Top#
    Set pCurBottomMargin to Bottom#
    Send ExportCurMargins
  End_Procedure
  Procedure vpe_Set Integer what# Integer val# // Same as SetCoord
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeSet(lhDoc,what#,val#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure SetCoord Integer what# Integer val#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeSet(lhDoc,what#,val#)) to Vpe$ReturnGrb#
  End_Procedure
  Function GetCoord Integer what# Returns integer
    DWord lhDoc
    Get phDoc to lhDoc
    Function_Return (VpeGet(lhDoc,what#))
  End_Function
  Function vpe_Get Integer what# Returns integer // Same as GetCoord
    DWord lhDoc
    Get phDoc to lhDoc
    Function_Return (VpeGet(lhDoc,what#))
  End_Function
  Procedure vpe_OpenDoc handle parent# string title# dword flags#
    DWord lhDoc
    Integer target# main_client#
    String bypass#
    Get VPE_OemToChar title# to title#

    #IFDEF VPE_USE_EMBEDDED_PREVIEW
     Get iGlobal_MainClient_Id to main_client#
     Move "" to bypass#
     Get_Profile_String "VEJMAN_SETUP" "OLD_PREVIEW" to bypass#
     If (bypass# = "") Begin
       Create_Object_Group OG_VpePreview PARENT main_client# (pTitle(Self))
       Send ErrorHnd_Quiet_Activate
       Send Popup to OG_Current_Object#
       Send ErrorHnd_Quiet_Deactivate
       Send Make_Invisible to OG_Current_Object#
       Get Target of OG_Current_Object# to target#
       Move (VpeOpenDoc(target#,title#,flags# ior VPE_EMBEDDED ior VPE_NO_USER_CLOSE)) to lhDoc
       Set phDoc of OG_Current_Object# to lhDoc
     End
     Else Move (VpeOpenDoc(parent#,title#,flags#)) to lhDoc
    #ELSE
     Move (VpeOpenDoc(parent#,title#,flags#)) to lhDoc
    #ENDIF
    Move (VpeLicense(lhDoc,VPE_SERIAL_CODE1,VPE_SERIAL_CODE2)) to Vpe$ReturnGrb#
    Set phDoc to lhDoc
    If (pLandscape(Self)) Begin
      Send Vpe_SetDevOrientation VORIENTATION_LANDSCAPE
      Send Vpe_SetPageOrientation VORIENTATION_LANDSCAPE
    End
  End_Procedure
  Procedure OpenDoc string tmpTitle# string tmpSetupFile#
    DWord lhDoc
    String title# SetupFile#
    Integer length# width#
    Integer target# main_client#
    String bypass#
    if num_arguments gt 0 move tmpTitle# to title#
    Else Get pTitle to title#
    If num_arguments gt 1 Move tmpSetupFile# to SetupFile#
    Else Get sDefaultSetupFileName to SetupFile# // "c:\vpe3.set"
    If (SetupFile# = "") Get sDefaultSetupFileName  to SetupFile# // "c:\vpe3.set"
     get VPE_OemToChar title# To title#
     get pPageWidth  to Width#
    Get pPageLength to Length#
    if (width# = VPAPER_A4) begin
      Move 2100 to Width#
      Move 2970 to Length#
    End
    If (width# = VPAPER_LETTER) Begin
      Move 2159 to Width#
      Move 2794 to Length#
    End
    Set pPageWidth  to Width#
    Set pPageLength to Length#
    // width and length are no longer passed as params to opendoc
    // we might have to set paper size diffently
    #IFDEF VPE_USE_EMBEDDED_PREVIEW
     Get iGlobal_MainClient_Id to main_client#
     Move "" to bypass#
     Get_Profile_String "VEJMAN_SETUP" "OLD_PREVIEW" to bypass#
     If (bypass# = "") Begin
       Create_Object_Group OG_VpePreview PARENT main_client# (pTitle(Self))
       Send ErrorHnd_Quiet_Activate
       Send Popup to OG_Current_Object#
       Send ErrorHnd_Quiet_Deactivate
       Send Make_Invisible to OG_Current_Object#
       Get Target of OG_Current_Object# to target#
       Move (VpeOpenDoc(target#,title#,pOpenOptions(Self) ior VPE_EMBEDDED ior VPE_NO_USER_CLOSE)) to lhDoc
       Set phDoc of OG_Current_Object# to lhDoc
     End
     Else Move (VpeOpenDoc(0,title#,pOpenOptions(Self))) to lhDoc
    #ELSE
     Move (VpeOpenDoc(0,title#,pOpenOptions(Self))) to lhDoc
    #ENDIF
    Move (VpeLicense(lhDoc,VPE_SERIAL_CODE1,VPE_SERIAL_CODE2)) to Vpe$ReturnGrb#
    Set phDoc to lhDoc
    If (pLandscape(Self)) Begin
      Send Vpe_SetDevOrientation VORIENTATION_LANDSCAPE
      Send Vpe_SetPageOrientation VORIENTATION_LANDSCAPE
    End
    move (VpeSetupPrinter(lhDoc,SetupFile#,PRINTDLG_ONFAIL)) to Vpe$ReturnGrb#
    If (Vpe$ReturnGrb# = 1) Begin // User pressed cancel
      Send vpe_CloseDoc
    End
    Else Begin
      Send SetMargins (pLeftMargin(Self)) (pRightMargin(Self)) (pTopMargin(Self)) (pBottomMargin(Self))
      Send vpe_SelectFont (pFont(Self)) (pFontSize(Self))
      Set pBold      to False
      Set pUnderLine to False
      Set pItalics   to False
      Set pNewPageOnNextLine to 0
    End
  End_Procedure
  Procedure vpe_CloseDoc
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeCloseDoc(lhDoc)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_PreviewDoc
    DWord lhDoc
    String bypass#
    Get phDoc to lhDoc
    Move (VpeSetPaperView(lhDoc,1)) to Vpe$ReturnGrb# // Display paper size
    Move (VpePreviewDoc(lhDoc, VPE_NULL, VPE_SHOW_MAXIMIZED)) to Vpe$ReturnGrb#
    #IFDEF VPE_USE_EMBEDDED_PREVIEW
     Move "" to bypass#
     Get_Profile_String "VEJMAN_SETUP" "OLD_PREVIEW" to bypass#
     If (bypass# = "") Send Make_Visible to OG_Current_Object#
    #ENDIF
  End_Procedure
  Procedure PreviewDoc
    DWord lhDoc
    Get phDoc to lhDoc
    //JK (2000.04.11): VpeGotoPage replaced with VpeGotoVisualPage
    //Move (VpeGotoPage(lhDoc,1)) to Vpe$ReturnGrb#
    Move (VpeGotoVisualPage(lhDoc,1)) to Vpe$ReturnGrb#
    Send vpe_PreviewDoc
  End_Procedure
   //JK (2000.04.11): Updates an open preview when the document has changed
  // Warning: if the user closes the preview, the document will also be closed,
  // and DispatchAllMessages will then return true.
  // At that point you immediately have to end all printing activites or
  // the program will crash!!!
  Function DispatchAllMessages Returns Integer
    DWord lhDoc
    Integer bClosed
    Get phDoc to lhDoc
    Move (VpeDispatchAllMessages(lhDoc)) to bClosed
    Function_Return bClosed
  End_Function
  Procedure vpe_PrintDoc
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpePrintDoc(lhDoc, VPE_FALSE)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure PrintDoc
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpePrintDoc(lhDoc, VPE_FALSE)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_SetupPrinter string file# integer mode#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeSetupPrinter(lhDoc,file#,mode#)) to Vpe$ReturnGrb#
  End_Procedure
   //JK: Writes current document to specified file
  Procedure vpe_WriteDoc String file#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeWriteDoc(lhDoc,file#)) to Vpe$ReturnGrb#
  End_Procedure
   //JK: Reads specified file into current document
  Procedure vpe_ReadDoc String file#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeReadDoc(lhDoc,file#)) to Vpe$ReturnGrb#
  End_Procedure
  Function iTextHeight.is integer width# string str# returns integer
    DWord lhDoc
    Integer rval#
    Get phDoc to lhDoc
    Get VPE_OemToChar str# to str#
    Move (VpeRenderWrite(lhDoc,100,100,(100+width#),VFREE,str#)) to Vpe$ReturnGrb#
    // Vpe$ReturnGrb# now contains info on whether autobreak occured
    Move (VpeGet(lhDoc,VRENDERHEIGHT)) to rval#
    Function_Return rval#
  End_Function
  Procedure Vpe_SetDevOrientation integer orient#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeSetDevOrientation(lhDoc,orient#)) to Vpe$ReturnGrb#
  End_Procedure
  Function Vpe_GetDevOrientation returns integer
    DWord lhDoc
    Get phDoc to lhDoc
    Function_Return (VpeGetDevOrientation(lhDoc))
  End_Function
  Procedure Vpe_SetPageOrientation integer orient#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeSetPageOrientation(lhDoc,orient#)) to Vpe$ReturnGrb#
  End_Procedure
  Function Vpe_GetPageOrientation returns integer
    DWord lhDoc
    Get phDoc to lhDoc
    Function_Return (VpeGetPageOrientation(lhDoc))
  End_Function
  Procedure SetupPrinter string tmpSetupFile#
    DWord lhDoc
    String SetupFile#
    If num_arguments gt 0 Move tmpSetupFile# to SetupFile#
    Else Get sDefaultSetupFileName to SetupFile#
    If SetupFile# eq "" Get sDefaultSetupFileName to SetupFile#
     send OpenDoc
    Get phDoc to lhDoc
    Move (VpeSetupPrinter(lhDoc,SetupFile#,PRINTDLG_ALWAYS)) to Vpe$ReturnGrb#
    Send vpe_CloseDoc
  End_Procedure
   // The procedures Write and WriteLn simulates the good old way of
  // outputting to the printer.
  Function AttributeString Returns String
    Function_Return ("["+If(pBold(Self),"B ","BO ")+If(pUnderLine(Self),"U ","UO ")+If(pItalics(Self),"I ","IO ")+"]")
  End_Function
  Function AttributeString.iii integer lbBold integer lbItalics integer lbUnderline returns string
    Function_Return ("["+If(lbBold,"B ","BO ")+If(lbUnderline,"U ","UO ")+If(lbItalics,"I","IO")+"]")
  End_Function

  // When something has been printed that is known to be one line, this
  // function will tell you how many more lines may printed on the current
  // page. In general the function will tell you how many more of the
  // previous objects may be printed on the current page.
  Function RemainingLines Returns integer
    Integer wy1 wy2 wy3
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeGet(lhDoc,VTOP))          to wy1
    Move (VpeGet(lhDoc,VBOTTOM))       to wy2
    Move (VpeGet(lhDoc,VBOTTOMMARGIN)) to wy3
    If (wy1=wy2) Function_Return 999 // No lines have been written yet
    Function_Return (wy3-wy2/Number(wy2-wy1))
  End_Function
  Function LinesPerPage Returns integer
    Integer wy1 wy2 wy3 wy4
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeGet(lhDoc,VTOP))          to wy1
    Move (VpeGet(lhDoc,VBOTTOM))       to wy2
    Move (VpeGet(lhDoc,VBOTTOMMARGIN)) to wy3
    Move (VpeGet(lhDoc,VTOPMARGIN))    to wy4
    If (wy1=wy2) Function_Return 999 // No lines have been written yet
    Function_Return (wy3-wy4/Number(wy2-wy1)-1)
  End_Function
  Function CheckPage Integer Lins# Returns Integer
    Function_Return (Lins#>RemainingLines(Self))
  End_Function
  Procedure vpe_PageBreak
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpePageBreak(lhDoc)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure NewPage
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpePageBreak(lhDoc)) to Vpe$ReturnGrb#
    Send ExportCurMargins
    Set pNewPageOnNextLine to 0
  End_Procedure
  Procedure Write string str#
    DWord lhDoc
    Get phDoc to lhDoc
    Get VPE_OemToChar str# to str#
    If (pNewPageOnNextLine(Self)=2) Send NewPage
    If (CheckPage(Self,1)) Set pNewPageOnNextLine to 1
    If (VpeGet(lhDoc,VBOTTOM)=VpeGet(lhDoc,VTOP)) ;
        Move (VpePrint(lhDoc,pCurLeftMargin(Self),pCurTopMargin(Self),AttributeString(Self)+str#)) to Vpe$ReturnGrb#
    //JK: hmm... shouldn't it be VpeGet(VRIGHT) and VpeGet(VTOP) ?!?
    Else Move (VpePrint(lhDoc,VRIGHT,VTOP,AttributeString(Self)+str#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure WriteLn string str#
    DWord lhDoc
    Integer VTOP# VBOTTOM#
    Get phDoc to lhDoc
    Send Write str#
    Move (VpeGet(lhDoc,VTOP)) to VTOP#
    Move (VpeGet(lhDoc,VBOTTOM)) to VBOTTOM#
    Move (VpeSet(lhDoc,VTOP,VTOP#+VBOTTOM#-VTOP#)) to Vpe$ReturnGrb#
    // These two lines are not equivalent ???
  //Move (VpeSet(lhDoc,VTOP,      VBOTTOM#      )) To Vpe$ReturnGrb#
    Move (VpeSet(lhDoc,VBOTTOM,VBOTTOM#+VBOTTOM#-VTOP#)) to Vpe$ReturnGrb#
    Move (VpeSet(lhDoc,VRIGHT,pCurLeftMargin(Self))) to Vpe$ReturnGrb#
    If (pNewPageOnNextLine(Self)=1) Set pNewPageOnNextLine to 2
  End_Procedure
  Procedure vpe_Write integer x1# integer y1# integer x2# integer y2# string str#
    Integer lhDoc
    Move str# to str#
    If (str#<>"") Begin
      //showln x1# ":" y1# ":" x2# ":" y2# ":" str#
      Get phDoc to lhDoc
      Get VPE_OemToChar str# to str#
      Move (VpeWrite(lhDoc,x1#,y1#,x2#,y2#,str#)) to Vpe$ReturnGrb#
    End
  End_Procedure
  Procedure vpe_WriteRTF integer x1# integer y1# integer x2# integer y2# string str#
    #IFSAME _VPEDLL_ VPEP32.DLL VPEE32.DLL VPEP3235.DLL VPEE3235.DLL
     DWord lhDoc
     Get phDoc to lhDoc
     //Get VPE_OemToChar str# To str#
     Move (VpeWriteRTF(lhDoc,x1#,y1#,x2#,y2#,str#)) to Vpe$ReturnGrb#
    #ELSE
     Showln "RTF functions can not be used with this version of VPE!"
    #ENDIF
  End_Procedure
  Procedure GenericWrite integer x1# integer y1# integer x2# integer y2# string str#
    Showln "GenericWrite should be vpe_Write"
  End_Procedure
  Procedure vpe_Line integer x1# integer y1# integer x2# integer y2#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeLine(lhDoc,x1#,y1#,x2#,y2#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_HorizontalLineKeepPos Integer tmpleft# Integer tmpright#
    Integer left# right#
    DWord lhDoc
    If num_arguments gt 0 Move tmpleft# to left#
    Else Move VLEFTMARGIN to left#
    If num_arguments gt 1 Move tmpright# to right#
    Else Move VRIGHTMARGIN to right#
    Get phDoc to lhDoc
    Move (VpeStorePos(lhDoc)) to Vpe$ReturnGrb#
    Send vpe_Line left# VBOTTOM right# VBOTTOM
    Move (VpeRestorePos(lhDoc)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure WriteLine integer tmpleft# integer tmpright#
    Integer left# right#
    DWord lhDoc
    If num_arguments gt 0 Move tmpleft# to left#
    Else Move VLEFTMARGIN to left#
    If num_arguments gt 1 Move tmpright# to right#
    Else Move VRIGHTMARGIN to right#
    Get phDoc to lhDoc
    Move (VpeStorePos(lhDoc)) to Vpe$ReturnGrb#
    Send vpe_Line left# VTOP right# VTOP
    Move (VpeRestorePos(lhDoc)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_Box integer x1# integer y1# integer x2# integer y2#
    DWord lhDoc
    If (x1# > x2#) Begin // Coordinates MUST be upper left, lower right.
      Move x1# to lhDoc // Otherwise errors in pre-viewer.
      Move x2# to x1#
      Move lhDoc to x2#
    End
    If (y1# > y2#) Begin
      Move y1# to lhDoc
      Move y2# to y1#
      Move lhDoc to y2#
    End
    Get phDoc to lhDoc
    Move (VpeBox(lhDoc,x1#,y1#,x2#,y2#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_Ellipse Integer x1# Integer y1# Integer x2# Integer y2#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeEllipse(lhDoc,x1#,y1#,x2#,y2#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_SetTransparentMode Integer onoff#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeSetTransparentMode(lhDoc,onoff#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_SetBkgColor Integer color#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeSetBkgColor(lhDoc,color#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_SetHatchStyle Integer hatch#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeSetHatchStyle(lhDoc,hatch#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_SetHatchColor Integer color#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeSetHatchColor(lhDoc,color#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_Print_Print integer x1# integer y1# string str#
    DWord lhDoc
    Get phDoc to lhDoc
    Get VPE_OemToChar str# to str#
    Move (VpePrint(lhDoc,x1#,y1#,str#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_PrintBox integer x1# integer y1# string str#
    DWord lhDoc
    Get phDoc to lhDoc
    Get VPE_OemToChar str# to str#
    Move (VpePrintBox(lhDoc,x1#,y1#,str#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_WriteBox Integer x1# Integer y1# Integer x2# Integer y2# String str#
    DWord lhDoc
    Get phDoc to lhDoc
    Get VPE_OemToChar str# to str#
    Move (VpeWriteBox(lhDoc,x1#,y1#,x2#,y2#,str#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure Vpe_Polygon integer arrayhandle# integer length#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpePolygon(lhDoc,arrayhandle#,length#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure Vpe_Polyline Integer arrayhandle# Integer length#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpePolyline(lhDoc,arrayhandle#,length#)) to Vpe$ReturnGrb#
  End_Procedure
 //External_Function32 VpePolyLine "VpePolyLine" Dword lhDoc Dword array# integer size# returns dword#
//// long EXPO VpePolygon(long hDoc, POINT *pt, unsigned int size);
//External_Function32 VpePolyLine "VpePolyLine" Dword lhDoc Dword array# integer size# returns dword#
  Procedure vpe_SetAlign integer attr#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeSetAlign(lhDoc,attr#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_SetPen Integer size# Integer style# Integer color#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeSetPen(lhDoc,size#,style#,color#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_Picture Integer x1# Integer y1# Integer x2# Integer y2# String bmpstr# Integer flags#
    DWord lhDoc
    String path#
    Get phDoc to lhDoc
     //JK - 2000.06.26:
    // Check if bitmap really exists
    // If it doesn't, don't try top print it.
    // If it does, convert to full path/filename.
    If (pos(sysconf(SYSCONF_DIR_SEPARATOR),bmpstr#) > 0) Begin
      // File has path already
      If (not(SEQ_FileExists(bmpstr#))) Procedure_Return
    End
    Else Begin
      // File has no path, so we search along dfpath
      Move (SEQ_FindFileAlongDFPath(bmpstr#)) to path#
      If (path# = "") Procedure_Return
      Move (path# + sysconf(SYSCONF_DIR_SEPARATOR) + bmpstr#) to bmpstr#
    End
     //JK - 2000.06.08:
    // Dirty hack to always save bitmaps in the generated document
    Move (flags# ior PIC_IN_FILE) to flags#
    Move (VpePicture(lhDoc,x1#,y1#,x2#,y2#,bmpstr#,flags#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_PictureKeepPos Integer x1# Integer y1# Integer x2# Integer y2# String bmpstr# Integer flags#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeStorePos(lhDoc)) to Vpe$ReturnGrb#
    Send vpe_Picture x1# y1# x2# y2# bmpstr# flags#
    Move (VpeRestorePos(lhDoc)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_StorePos
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeStorePos(lhDoc)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_RestorePos
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeRestorePos(lhDoc)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_DefineHeader Integer x1# Integer y1# Integer x2# Integer y2# String text#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeDefineHeader(lhDoc,x1#,y1#,x2#,y2#,text#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_DefineFooter Integer x1# Integer y1# Integer x2# Integer y2# String text#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeDefineFooter(lhDoc,x1#,y1#,x2#,y2#,text#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_SetTextColor DWord color#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeSetTextColor(lhDoc,color#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_SetDefOutRectSP Integer left# Integer top# Integer right# Integer bottom#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeSetDefOutRectSP(lhDoc,left#,top#,right#,bottom#)) to Vpe$ReturnGrb#
  End_Procedure
  Function vpe_GetCurrentPage Returns Integer
    DWord lhDoc
    Get phDoc to lhDoc
    Function_Return (VpeGetCurrentPage(lhDoc))
  End_Function
  Function vpe_GetPageCount returns integer
    DWord lhDoc
    Get phDoc to lhDoc
    Function_Return (VpeGetPageCount(lhDoc))
  End_Function
  Procedure vpe_GotoPage integer page#
    DWord lhDoc
    Get phDoc to lhDoc
    Move (VpeGotoPage(lhDoc,page#)) to Vpe$ReturnGrb#
  End_Procedure
  Procedure vpe_Addbookmark Integer parent# String title#
    DWord lhDoc
    Get phDoc to lhDoc
//     Move (VpeAddBookmark(lhDoc,parent#,title#)) to Vpe$ReturnGrb#
  End_Procedure
  Function Vpe_DevEnumPaperBins Returns Integer
    DWord hDoc#
    Integer iVal
    Get phDoc to hDoc#
    Move (vpeDevEnumPaperBins(hDoc#)) to iVal
    Function_Return iVal
  End_Function
  Function Vpe_GetDevPaperBinName Integer iIndex Returns String
    DWord hDoc#
    Integer iVal p2BinName
    String sBinName
    ZeroString 65 to sBinName
    GetAddress of sBinName to p2BinName
    Get phDoc to hDoc#
    Move (vpeGetDevPaperBinName(hDoc#,iIndex,p2BinName,64)) to iVal
    Function_Return sBinName
  End_Function

End_Class // cVPE

Integer oVPE#

Object oVPE is a cVPE
  Procedure display_previous_object
    Showln ("Left/Right/Top/Bottom:"+String(GetCoord(oVPE#,VLeft))*String(GetCoord(oVPE#,VRight))*String(GetCoord(oVPE#,VTop))*String(GetCoord(oVPE#,VBottom)))
  End_Procedure
  Procedure display_stuff
    Showln "****vpe_get*******************************************"
    Showln ("Text: Left/Right/Top/Bottom:"+String(GetCoord(oVPE#,VLeft))*String(GetCoord(oVPE#,VRight))*String(GetCoord(oVPE#,VTop))*String(GetCoord(oVPE#,VBottom)))
    Showln ("Marg: Left/Right/Top/Bottom:"+String(GetCoord(oVPE#,VLeftMargin))*String(GetCoord(oVPE#,VRightMargin))*String(GetCoord(oVPE#,VTopMargin))*String(GetCoord(oVPE#,VBottomMargin)))
  End_Procedure
  Move Self to oVPE#
End_Object