home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic 4 Unleashed / Visual_Basic_4_Unleashed_SAMS_Publishing_1995.iso / repease / rep_file.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  28KB  |  734 lines

  1. /*==============================================================================
  2.    REP_FILE.C
  3.    Report Ease file i/o and report parameter functions.
  4.  
  5.    Report Ease
  6.    Sub Systems, Inc.
  7.    ReportEase, Copyright (c) 1992, Sub Systems, Inc. All Rights Reserved.
  8.    159 Main Street, #8C, Stoneham,  MA 02180 
  9.    (617) 438-8901.
  10.  
  11.    Software License Agreement  (1992)              
  12.    ----------------------------------
  13.    This license agreement allows the purchaser the right to modify the 
  14.    source code to incorporate in their application.
  15.    The target application must not be distributed as a standalone report writer
  16.    or a mail merge product.
  17.    Sub Systems, Inc. reserves the right to prosecute anybody found to be 
  18.    making illegal copies of the executable software or compiling the source
  19.    code for the purpose of selling there after.
  20. ===============================================================================*/
  21.  
  22. #include "windows.h"
  23.  
  24. #if defined (_WIN32)
  25.    #if !defined(WIN32)
  26.      #define WIN32
  27.    #endif
  28. #endif
  29. #if !defined(WIN32) 
  30.   #include "print.h"
  31. #endif
  32.  
  33. #include "stdio.h"
  34. #include "stdlib.h"
  35. #include "ctype.h"
  36. #include "fcntl.h"
  37. #include "io.h"
  38. #include "string.h"
  39. #include "sys\types.h"
  40. #include "sys\stat.h"
  41. #include "setjmp.h"
  42.  
  43. #include "commdlg.h"
  44.  
  45. #include "rep.h"
  46.  
  47. #define  PREFIX extern
  48. #include "rep1.h"
  49.  
  50. /*****************************************************************************
  51.     FrRead:
  52.     Read the input file or parse the input buffer to separate each text line.
  53.     The routine return a TRUE value when successful.
  54. ******************************************************************************/
  55. BOOL FrRead(LPSTR InputFile)  
  56. {
  57.     int  rwMode=6,i;
  58.     int  font,ItemSize;
  59.     HFILE iFile;
  60.     LPSTR pImage,pInfo;
  61.     BYTE  signature;
  62.     DWORD ImageSize,InfoSize;
  63.     char line[LINE_WIDTH+2],ProfString[3][NAME_WIDTH+2];
  64.  
  65.     strupr(InputFile);
  66.     rTrim(InputFile);          // trim any spaces on right
  67.     if (strlen(InputFile)==0) {
  68.         InitNewForm();        // initialize the new form 
  69.         return TRUE;
  70.     }
  71.     if (access(InputFile,rwMode)==-1) {
  72.         wsprintf(msg,"File: %s Does Not Exist, Create a New Form?",(LPSTR)InputFile);
  73.         if (IDNO==MessageBox(hFrWnd,msg,"New Form",MB_YESNO)) {
  74.             CloseFr();
  75.             return FALSE;
  76.         }
  77.         else {
  78.            InitNewForm();      // initialize the report 
  79.            return TRUE;        // the file will be created at update time 
  80.         }
  81.     }
  82.  
  83.     if ((iFile=_lopen(InputFile,OF_READ))==HFILE_ERROR) {
  84.         AbortFr("Could Not Open the Input File.",32);
  85.     }
  86.  
  87.     SetCursor(hWaitCursor);                    // show hour glass while reading 
  88.  
  89.     // INITIALIZE FONTS
  90.     for (i=1;i<MAX_FONTS;i++) {                // initialize the font table 
  91.        if (FrFont[i].InUse) DeleteFrObject(i); // delete old font/picture 
  92.     }
  93.  
  94.     // READ HEADER
  95.     if (_lread(iFile,&FormHdr,sizeof(struct StrFormHdr))!=sizeof(struct StrFormHdr)
  96.        || FormHdr.FormSign!=FORM_SIGN ) {
  97.         AbortFr("Not a valid form file",33);
  98.     }
  99.  
  100.     TotalItems=FormHdr.TotalItems;
  101.  
  102.     // READ TEXT LINES
  103.     FrHeight=0;                            // build the form height as well
  104.     if (FormHdr.FileFormatId<=2 && !Win32) ItemSize=OLD_ITEM_SIZE;
  105.     else                                   ItemSize=sizeof(struct StrItem);
  106.  
  107.     for(i=0;i<TotalItems;i++) {            // read each text line
  108.        if (ItemSize<sizeof(struct StrItem)) FarMemSet(&(item[i]),0,sizeof(struct StrItem));
  109.  
  110.        if (!FrFarRead(iFile,ItemSize,(char huge *)&(item[i]))) {
  111.           AbortFr("Error reading the item data",35);
  112.        }
  113.        if (item[i].type==LABEL || item[i].type==PICT || item[i].type==FIELD) {
  114.           font=item[i].font;
  115.           FrFont[font].InUse=TRUE;         // font in use
  116.        }
  117.        if (item[i].type==SECTION) {        // build the form height
  118.           FrHeight+=item[i].height;        // current height of the form 
  119.        }
  120.     }
  121.  
  122.     // READ FIELDS                         
  123.     if (FormHdr.FileFormatId==0) {         // old format: uses larger field records
  124.        for (i=0;i<FormHdr.FieldCount;i++) {// read one field at a time
  125.           // read one field
  126.           if (!FrFarRead(iFile,(long)sizeof(struct StrField),(char huge *)&(field[i])) ){
  127.               AbortFr("Error reading one field",36);
  128.           }
  129.           // read and discard extra 4 bytes that the old field format used
  130.           if (!FrFarRead(iFile,4,(char huge *)line) ){
  131.               AbortFr("Error reading field extra bytes",36);
  132.           }
  133.        }
  134.     }
  135.     else {                                 // new field records are 256 bytes  
  136.        if (!FrFarRead(iFile,(long)sizeof(struct StrField)*(long)FormHdr.FieldCount,(char huge *)field) ){
  137.            AbortFr("Error reading the fields",36);
  138.        }
  139.     }
  140.  
  141.     // READ BREAK FIELD
  142.     if (!FrFarRead(iFile,(long)sizeof(struct StrBreakField)*(long)FormHdr.BreakFieldCount,(char huge *)BreakField) ){
  143.         AbortFr("Error reading the break fields",36);
  144.     }
  145.  
  146.     // READ SECTIONS
  147.     if (FormHdr.FileFormatId<2) {          // old format: uses only one detail section
  148.        for (i=0;i<=SEC_DETAIL1;i++) {      // read upto the detail section
  149.           if (!FrFarRead(iFile,(long)sizeof(struct StrSection),(char huge *)&(section[i]))  ) {
  150.               AbortFr("Error reading one section",36);
  151.           }
  152.        }
  153.        for (i=SEC_FTR_LVL9;i<MAX_SECTIONS;i++) { // read the footer sections
  154.           if (!FrFarRead(iFile,(long)sizeof(struct StrSection),(char huge *)&(section[i]))  ) {
  155.               AbortFr("Error reading one section(B)",36);
  156.           }
  157.        }
  158.        // Fix indexes in the item array
  159.        for(i=0;i<TotalItems;i++) if (item[i].section>SEC_DETAIL1) item[i].section+=8;  // 8 new sections added
  160.        // Fix indexes in the field array
  161.        for (i=0;i<FormHdr.FieldCount;i++) if (field[i].section>SEC_DETAIL1) field[i].section+=8;  // 8 new sections added
  162.        // Fix indexes in the BreakField array
  163.        for (i=0;i<FormHdr.BreakFieldCount;i++) if (BreakField[i].section>SEC_DETAIL1) BreakField[i].section+=8;  // 8 new sections added
  164.     }
  165.     else {
  166.        if (!FrFarRead(iFile,(long)sizeof(struct StrSection)*(long)MAX_SECTIONS,(char huge *)section)  ) {
  167.            AbortFr("Error reading the sections",36);
  168.        }
  169.     }
  170.  
  171.     if (!FrFarRead(iFile,(long)sizeof(struct StrDlgField)*(long)MAX_DLGS,(char huge *)DlgField)) {
  172.         AbortFr("Dialog fields missing!",37);
  173.     }
  174.  
  175.  
  176.     // READ FONT TABLE
  177.  
  178.     if (!FrFarRead(iFile,1,&signature)) goto NO_FONT;
  179.  
  180.     if (signature!=FontSign) goto NO_FONT;
  181.  
  182.     TotalFonts=FormHdr.FontCount;
  183.     if (TotalFonts>MAX_FONTS) TotalFonts=MAX_FONTS;
  184.  
  185.     for (i=0;i<TotalFonts;i++) {     // read each font table element 
  186.        if (!FrFarRead(iFile,sizeof(int),(char huge *)&(FrFont[i].IsPict))) goto NO_FONT;
  187.  
  188.        if (FrFont[i].IsPict) {      // read in the picture bitmap 
  189.            //**** read the display dimensions of the picture ******
  190.            if (!FrFarRead(iFile,sizeof(UINT),(char huge *)&(FrFont[i].PictHeight))) goto NO_FONT;
  191.            if (!FrFarRead(iFile,sizeof(UINT),(char huge *)&(FrFont[i].PictWidth))) goto NO_FONT;
  192.           
  193.            //*** read the picture storage size in bytes ***
  194.            if (!FrFarRead(iFile,sizeof(DWORD),(char huge *)&ImageSize)) goto NO_FONT;
  195.            if (!FrFarRead(iFile,sizeof(DWORD),(char huge *)&InfoSize)) goto NO_FONT;
  196.            FrFont[i].ImageSize=ImageSize;
  197.            FrFont[i].InfoSize=InfoSize;
  198.  
  199.            if (InfoSize>0) {
  200.                //************ Allocate Space for image and info *********
  201.                if  (NULL==(FrFont[i].hImage=GlobalAlloc(GMEM_MOVEABLE,ImageSize))
  202.                  || NULL==(FrFont[i].hInfo=GlobalAlloc(GMEM_MOVEABLE,InfoSize))
  203.                  || NULL==(pImage=GlobalLock(FrFont[i].hImage)) 
  204.                  || NULL==(pInfo=GlobalLock(FrFont[i].hInfo)) ) {
  205.                      AbortFr("Ran Out of Memory for Picture Bitmap",ERR_NO_MEM);
  206.                }
  207.                //********** Read image and info data *******************
  208.                if (!FrFarRead(iFile,ImageSize,pImage)) goto NO_FONT;
  209.                if (!FrFarRead(iFile,InfoSize,pInfo)) goto NO_FONT;
  210.                
  211.                GlobalUnlock(FrFont[i].hImage);
  212.                GlobalUnlock(FrFont[i].hInfo);
  213.            }
  214.        }
  215.        else {                             // read the logical font structure
  216.            if (!FrFarRead(iFile,sizeof(LOGFONT),(char huge *)&(FrFont[i].lFont))) goto NO_FONT;
  217.        }
  218.     }
  219.  
  220.     goto END_FILE;
  221.  
  222.     NO_FONT:
  223.     MessageBox(hFrWnd,"Font Table Incomplete!",NULL,MB_OK);
  224.  
  225.  
  226.     END_FILE:
  227.     _lclose(iFile);
  228.  
  229.     TotalFields=FormHdr.FieldCount;
  230.     TotalBreakFields=FormHdr.BreakFieldCount;
  231.     TotalFonts=FormHdr.FontCount;
  232.     
  233.  
  234.     // FIND_PRINTER
  235.     if (strcmp(PrinterName,FormHdr.PrinterName)!=0 || strcmp(PrinterDriver,FormHdr.PrinterDriver)!=0) {
  236.         // form does not use the default printer 
  237.         if (ParseProfileString("devices",FormHdr.PrinterName,ProfString[0],ProfString[1],ProfString[2])) {
  238.             strcpy(PrinterPort,ProfString[1]);  // extract the device port 
  239.             strcpy(PrinterName,FormHdr.PrinterName);
  240.             strcpy(PrinterDriver,ProfString[0]);
  241.             InitPrinter();    // read the printer data 
  242.         }
  243.     }
  244.     
  245.     // apply the header data to the printer structure 
  246.     pDevMode->dmOrientation=FormHdr.Orientation;
  247.     pDevMode->dmPaperSize=FormHdr.PaperSize;
  248.     pDevMode->dmPaperLength=FormHdr.PaperLength;
  249.     pDevMode->dmPaperWidth=FormHdr.PaperWidth;
  250.     pDevMode->dmPrintQuality=FormHdr.PrintQuality;
  251.     CallPrinterDriver(DM_MODIFY|DM_UPDATE);
  252.  
  253.     if (!UseScreen) {          // create the printer device context 
  254.        strcpy(line,PrinterDriver);
  255.        line[strlen(line)-4]=0; // strip the .drv extension 
  256.        if (NULL==(hFrDC=CreateDC(line,PrinterName,PrinterPort,pDevMode))) {
  257.            AbortFr("Can not initialize printing",ERR_NO_DEVICE);
  258.        }
  259.        ResX=GetDeviceCaps(hFrDC,LOGPIXELSX);  // number of pixels per inch of X direction 
  260.        ResY=GetDeviceCaps(hFrDC,LOGPIXELSY);  // number of pixels per inch of Y direction 
  261.        SetLogicalUnit(hFrDC);                 // set the logical units
  262.  
  263.        if (!GetTextMetrics(hFrDC,&FrTextMet)) {       // get text metric for the newly created font 
  264.             AbortFr("Unable to get text metric for the font.",ERR_DISPLAY);
  265.        } 
  266.     }
  267.  
  268.     ProcessPrinterData();      // calculate operational variables from the header fields 
  269.  
  270.     // REALIZE_FONTS
  271.     FrFont[0].InUse=TRUE;                       // default font always used 
  272.     for (i=0;i<TotalFonts;i++) {
  273.        if (FrFont[i].InUse) {
  274.           if (FrFont[i].IsPict) {               // create device bitmap 
  275.              FrXlateDIB(hFrDC,i);
  276.           }
  277.           else {
  278.              if (!CreateOneFont(hFrDC,i)) {                 // create a new font 
  279.                 wsprintf(line,"Error Creating Font: %s",FrFont[i].lFont.lfFaceName);
  280.                 AbortFr(line,ERR_DISPLAY);
  281.              }
  282.           }
  283.        }
  284.        else InitFrObject(i);
  285.     }
  286.  
  287.     SetCursor(hArrowCursor);             // Show regular cursor
  288.     return TRUE;
  289. }
  290.  
  291. /*******************************************************************************
  292.     FrSaveAs:
  293.     Save the text to the output file. As for the file name.      
  294. *******************************************************************************/
  295. BOOL FrSaveAs(LPSTR OutFile)       
  296. {
  297.     BOOL result;
  298.  
  299.     strupr(OutFile);
  300.     if (strcmp(FormHdr.name,OutFile)==0) strcpy(FormHdr.name,""); // initialize form name 
  301.  
  302.     lstrcpy(msg,OutFile);
  303.     if (Win32) result=GetFileName(FALSE,msg,"ReportEase+ Files(*.FPC)|*.FPC|");
  304.     else       result=GetFileName(FALSE,msg,"ReportEase+ Files(*.FP)|*.FP|");
  305.     if (!result) return FALSE;
  306.     lstrcpy(OutFile,msg);
  307.     strcpy(FormArg.file,OutFile);
  308.     
  309.     return(FrSave(OutFile));
  310. }
  311.  
  312. /*******************************************************************************
  313.     FrSave:
  314.     Save the text to the output file or output buffer.       
  315. *******************************************************************************/
  316. BOOL FrSave(LPSTR OutFile)       
  317. {
  318.     int  ExistMode=0,len,i,j,result;
  319.     HFILE oFile;
  320.     char BuFile[129];
  321.     LPSTR pImage,pInfo;
  322.     OFSTRUCT ofs;
  323.  
  324.     if (strcmp(OutFile,"")==0) {         // get file name, if not available   
  325.        strcpy(msg,OutFile);              // pass the previous file name to the dialog box 
  326.        if (Win32) result=GetFileName(FALSE,msg,"ReportEase+ Files(*.FPC)|*.FPC|");
  327.        else       result=GetFileName(FALSE,msg,"ReportEase+ Files(*.FP)|*.FP|");
  328.        if (!result) return FALSE;
  329.        strcpy(OutFile,msg);              // retrieve the user provided file name 
  330.     }
  331.     
  332.     //********** check for a file extension, provide if not given **********
  333.     len=strlen(OutFile);
  334.     j=0;
  335.     for (i=len-1;i>=0;i--,j++) {
  336.        if (OutFile[i]=='.') break;            // extension already exists 
  337.        if (j==4 || i==0 || OutFile[i]=='\\') {// last 4 position don't have a period 
  338.           if (Win32) strcat(OutFile,".FPC");
  339.           else       strcat(OutFile,".FP");
  340.           break;
  341.        }
  342.     }
  343.     
  344.     if (access(OutFile,ExistMode)==0) {  // backup the previous file 
  345.        strcpy(BuFile,OutFile);          // build a backup file name with .TE extension 
  346.        i=strlen(BuFile)-1;
  347.        while(i>=0 && i>=(int)strlen(BuFile)-4 && BuFile[i]!='.' && BuFile[i]!='\\') i--; 
  348.        if (i>=0 && BuFile[i]=='.') BuFile[i]=0;
  349.        strcat(BuFile,".BP");
  350.        if (access(BuFile,ExistMode)==0) unlink(BuFile);
  351.        rename(OutFile,BuFile);
  352.     }
  353.  
  354.     strupr(OutFile);
  355.     if (HFILE_ERROR==(oFile=OpenFile(OutFile,&ofs,OF_CREATE|OF_WRITE))) {
  356.         MessageBox(hFrWnd,"Error Opening the Output File",NULL,MB_OK);
  357.         rename(BuFile,OutFile);
  358.         goto WRITE_ERROR;
  359.     }
  360.  
  361.     SetCursor(hWaitCursor);                    // show hour glass while waiting 
  362.     
  363.     StrTrim(FormHdr.name);
  364.  
  365.     if (strlen(FormHdr.name)==0) strcpy(FormHdr.name,OutFile);  // default report 
  366.  
  367.     FormHdr.FieldCount=TotalFields;
  368.     FormHdr.BreakFieldCount=TotalBreakFields;
  369.     FormHdr.FontCount=TotalFonts;
  370.     FormHdr.TotalItems=TotalItems;
  371.     FormHdr.FileFormatId=CUR_FILE_FORMAT;      // file format id
  372.  
  373.     // WRITE HEADER
  374.     if (_lwrite(oFile,(LPCSTR)&FormHdr,sizeof(struct StrFormHdr))!=sizeof(struct StrFormHdr)) {
  375.         MessageBox(hFrWnd,"Error writing to output file",NULL,MB_OK);
  376.         rename(BuFile,OutFile);
  377.         goto WRITE_ERROR;
  378.     }
  379.  
  380.     // WRITE TEXT LINES
  381.     for(i=0;i<TotalItems;i++) {         // read each text line 
  382.       if (!FrFarWrite(oFile,sizeof(struct StrItem),(char huge *)&(item[i]))) {
  383.         MessageBox(hFrWnd,"Error writing to output file!",NULL,MB_OK);
  384.         rename(BuFile,OutFile);
  385.         goto WRITE_ERROR;
  386.       }
  387.     }
  388.  
  389.     // WRITE FIELDS
  390.     if (!FrFarWrite(oFile,(long)sizeof(struct StrField)*(long)FormHdr.FieldCount,(char huge *)field)
  391.      || !FrFarWrite(oFile,(long)sizeof(struct StrBreakField)*(long)FormHdr.BreakFieldCount,(char huge *)BreakField)
  392.      || !FrFarWrite(oFile,(long)sizeof(struct StrSection)*(long)MAX_SECTIONS,(char huge *)section)
  393.      || !FrFarWrite(oFile,(long)sizeof(struct StrDlgField)*(long)MAX_DLGS,(char huge *)DlgField) ){
  394.         MessageBox(hFrWnd,"Error Writing the field information!",NULL,MB_OK);
  395.         rename(BuFile,OutFile);
  396.         goto WRITE_ERROR;
  397.     }
  398.  
  399.  
  400.     // WRITE FONT TABLE 
  401.     if (!FrFarWrite(oFile,1,&FontSign)) goto WRITE_ERROR;
  402.     
  403.     for (i=0;i<TotalFonts;i++) {             // write each font record 
  404.        if (!(FrFont[i].InUse)) InitFrObject(i);
  405.  
  406.        if (!FrFarWrite(oFile,sizeof(int),(char huge *)&(FrFont[i].IsPict))) goto WRITE_ERROR;
  407.        
  408.        if (FrFont[i].IsPict) {         // save pictures 
  409.           if (!FrFont[i].InUse) FrFont[i].ImageSize=FrFont[i].InfoSize=0;
  410.           
  411.           //**** write the display dimensions of the picture ******
  412.           if (!FrFarWrite(oFile,sizeof(UINT),(char huge *)&(FrFont[i].PictHeight))) goto WRITE_ERROR;
  413.           if (!FrFarWrite(oFile,sizeof(UINT),(char huge *)&(FrFont[i].PictWidth))) goto WRITE_ERROR;
  414.           
  415.           //**** write the storage requirement ********************
  416.           if (!FrFarWrite(oFile,sizeof(DWORD),(char huge *)&(FrFont[i].ImageSize))) goto WRITE_ERROR;
  417.           if (!FrFarWrite(oFile,sizeof(DWORD),(char huge *)&(FrFont[i].InfoSize))) goto WRITE_ERROR;
  418.           if (FrFont[i].InfoSize>0) {
  419.              //************ lock image and info *********
  420.              if ( NULL==(pImage=GlobalLock(FrFont[i].hImage)) 
  421.                || NULL==(pInfo=GlobalLock(FrFont[i].hInfo)) ) {
  422.                    MessageBox(hFrWnd,"Ran Out of Memory","File Save Incomplete!",MB_OK);
  423.                    goto WRITE_ERROR;
  424.              }
  425.              //********** Read image and info data *******************
  426.              if (!FrFarWrite(oFile,FrFont[i].ImageSize,pImage)) goto WRITE_ERROR;
  427.              if (!FrFarWrite(oFile,FrFont[i].InfoSize,pInfo)) goto WRITE_ERROR;
  428.              
  429.              GlobalUnlock(FrFont[i].hImage);
  430.              GlobalUnlock(FrFont[i].hInfo);
  431.           }
  432.        }
  433.        else {                              // write the font logical structure
  434.           if (!FrFarWrite(oFile,sizeof(LOGFONT),(char huge *)&(FrFont[i].lFont))) goto WRITE_ERROR;
  435.        }
  436.     }
  437.  
  438.     // END FILE
  439.     FrModified=FALSE;
  440.     SetWindowText(hFrWnd,OutFile);
  441.  
  442.     WRITE_ERROR:
  443.     if (oFile) _lclose(oFile);
  444.     SetCursor(hArrowCursor);
  445.     
  446.     return TRUE;
  447. }
  448.  
  449. /******************************************************************************
  450.     GetFileName:
  451.     This function gets the file name from the user.  The first argument is
  452.     TRUE for 'open' dialog box, and FALSE for the 'Save As' dialog box.
  453.     The second argument can be used to specify the initial file name and 
  454.     get the file selection from the user.  The third argument (filter) must 
  455.     be '|' for delimters for wild card pairs.
  456. ******************************************************************************/
  457. BOOL GetFileName(BOOL open,LPSTR file,LPSTR filter)
  458. {
  459.     int    i,len,result;
  460.     OPENFILENAME ofn;
  461.     MSG msg;
  462.  
  463.     // preprare to get the bitmap file name from the user
  464.     FarMemSet(&ofn,0,sizeof(OPENFILENAME));        // initialize
  465.     ofn.lStructSize=sizeof(OPENFILENAME);
  466.     ofn.hwndOwner=hFrWnd;
  467.     len=lstrlen(filter);
  468.     for (i=0;i<len;i++) if (filter[i]=='|') filter[i]=0;
  469.     ofn.lpstrFilter=filter;
  470.     if (len) ofn.nFilterIndex=1;
  471.     else     ofn.nFilterIndex=0;
  472.     ofn.lpstrFile=file;
  473.     ofn.nMaxFile=128;
  474.     ofn.Flags=OFN_SHOWHELP|OFN_HIDEREADONLY|OFN_NOCHANGEDIR;
  475.  
  476.     // get the file name from the user
  477.     if (open) result=GetOpenFileName(&ofn);
  478.     else      result=GetSaveFileName(&ofn);
  479.  
  480.     // discard any mouse messages left from the above call
  481.     while (PeekMessage(&msg,hFrWnd,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE|PM_NOYIELD));;
  482.  
  483.     return result;
  484. }
  485.  
  486. /******************************************************************************
  487.     FrFarRead:
  488.     This routine reads a specified number of bytes(long) from the input
  489.     file. A far pointer to the receiving buffer and the input stream
  490.     is given by the arguments.
  491.     
  492.     The routine returns a TRUE or FALSE result.
  493. *******************************************************************************/
  494. FrFarRead(HFILE iFile,long len,char huge *OutBuf)
  495. {
  496.     DWORD OutPos;
  497.     int   TempBufLen=LINE_WIDTH,ReadLen;
  498.     char  temp[LINE_WIDTH+2];
  499.  
  500.     OutPos=0;
  501.     
  502.     while (len>0) {
  503.        ReadLen=TempBufLen;
  504.        if ((long)ReadLen>len) ReadLen=(int)len;
  505.        len=len-ReadLen;
  506.        if (_lread(iFile,temp,ReadLen)!=(UINT)ReadLen) return FALSE;
  507.        HugeMove(temp,&OutBuf[OutPos],ReadLen);
  508.        OutPos=OutPos+ReadLen;
  509.     }
  510.     return TRUE;   
  511. }
  512.  
  513. /******************************************************************************
  514.     FrFarWrite:
  515.     This routine writes a specified number of bytes(long) to the output.
  516.     A far pointer to the input buffer and the output file stream is 
  517.     specified by the arguments.
  518.     
  519.     The routine returns a TRUE or FALSE result.
  520. *******************************************************************************/
  521. FrFarWrite(HFILE oFile,long len,char huge *InBuf)
  522. {
  523.     DWORD InPos;
  524.     int   TempBufLen=LINE_WIDTH,WriteLen;
  525.     char  temp[LINE_WIDTH+2];
  526.  
  527.     InPos=0;
  528.     
  529.     while (len>0) {
  530.        WriteLen=TempBufLen;
  531.        if ((long)WriteLen>len) WriteLen=(int)len;
  532.        len=len-WriteLen;
  533.        HugeMove(&InBuf[InPos],temp,WriteLen);
  534.        if (_lwrite(oFile,temp,WriteLen)!=(UINT)WriteLen) return FALSE;
  535.        InPos=InPos+WriteLen;
  536.     }
  537.     return TRUE;   
  538. }
  539.  
  540. /******************************************************************************
  541.     FrRepParameters:
  542.     This routine allows the user to specify the report parameters such
  543.     as page margins, date format, etc.
  544. ******************************************************************************/
  545. FrRepParameters()
  546. {
  547.     int i;
  548.  
  549.     if (CallDialogBox("RepParam",RepParam,0L)) {
  550.        // recalculate drawing sizes
  551.        ProcessPrinterData();                   // apply new margins 
  552.  
  553.        // recalculate the detail section width
  554.        for (i=0;i<TotalItems;i++) if (item[i].type==SECTION && item[i].section==SEC_DETAIL1) break;
  555.        if (i<TotalItems) item[i].width=(FrWidth-(int)(UNITS_PER_INCH*(FormHdr.LeftMargin+FormHdr.RightMargin)))/section[SEC_DETAIL1].columns;
  556.  
  557.        // recalculate window zone sizes
  558.        GetWinDimension();     // get window dimensions 
  559.  
  560.        PaintFlag=PAINT_WIN;   // paint the entire window
  561.        FrPaint();
  562.     }
  563.  
  564.     return TRUE;
  565. }
  566.  
  567. /******************************************************************************
  568.     FrPrintOptions:
  569.     This routine printer specific options.
  570. ******************************************************************************/
  571. FrPrintOptions()
  572. {
  573.     int i;
  574.  
  575.     // select a printer 
  576.     CallDialogBox("PrinterParam",PrinterParam,0);
  577.     
  578.     // recalculate drawing sizes
  579.     ProcessPrinterData();                   // apply new margins 
  580.     
  581.     // recalculate the detail section width
  582.     for (i=0;i<TotalItems;i++) if (item[i].type==SECTION && item[i].section==SEC_DETAIL1) break;
  583.     if (i<TotalItems) item[i].width=(FrWidth-(int)(UNITS_PER_INCH*(FormHdr.LeftMargin+FormHdr.RightMargin)))/section[SEC_DETAIL1].columns;
  584.  
  585.     FrModified=TRUE;
  586.     FrPaint();
  587.     
  588.     return TRUE;
  589. }
  590.  
  591. /******************************************************************************
  592.     FrRepFilter:
  593.     Accept the record selection criteria for the report.
  594. ******************************************************************************/
  595. FrRepFilter()
  596. {
  597.     int NewExp[NAME_WIDTH+2];
  598.     int i;
  599.  
  600.     if (ModifyExp(FormHdr.SelExp,NewExp,"Record Selection Criteria",EXP_PARM)!=-1) {
  601.        i=0;
  602.        while(NewExp[i]!=END_OF_EXP) {
  603.           FormHdr.SelExp[i]=NewExp[i];
  604.           i++;
  605.        }
  606.        FormHdr.SelExp[i]=NewExp[i];
  607.        FrModified=TRUE;
  608.     }
  609.     return TRUE;
  610. }
  611.  
  612. /******************************************************************************
  613.     CallPrinterDriver:
  614.     Call the vendor's printer driver for the current printer.
  615. *******************************************************************************/
  616. BOOL CallPrinterDriver(WORD mode)
  617. {
  618.     HANDLE hDriver;
  619.  
  620.     #if defined (WIN32)
  621.        if (OpenPrinter(PrinterName,&hDriver,NULL)) {
  622.           if (!DocumentProperties(hFrWnd,hDriver,PrinterName,pDevMode,pDevMode,mode)) {
  623.              MessageBox(hFrWnd,"Error Initializing the printer(CallPrinterDriver)",NULL,MB_OK);
  624.           }
  625.           ClosePrinter(hDriver);
  626.           return TRUE;
  627.        }
  628.     #endif
  629.  
  630.     if (NULL!=(hDriver=LoadLibrary(PrinterDriver))) {
  631.        int (WINAPI _export *fpDeviceMode)(HWND,HANDLE,DEVMODE FAR *,LPSTR,LPSTR,DEVMODE FAR *,LPSTR,WORD);
  632.        fpDeviceMode=(void far *)GetProcAddress(hDriver,"ExtDeviceMode");  // if available, get the address of ExtDeviceMode function in the library 
  633.  
  634.        if (fpDeviceMode!=NULL) {     // ExtDeviceMode function is supported by the driver 
  635.            if ((*fpDeviceMode)(hFrWnd,hDriver,pDevMode,(LPSTR)PrinterName,(LPSTR)PrinterPort,pDevMode,(LPSTR)NULL,mode)<0) {
  636.               MessageBox(hFrWnd,"Error Initializing the Printer Options","Printer Error",MB_OK);
  637.            }
  638.        }
  639.        
  640.        FreeLibrary(hDriver);         // unload the driver from the memory 
  641.     }
  642.  
  643.     return TRUE;
  644. }
  645.  
  646. /******************************************************************************
  647.     GetPrinterList:
  648.     This function returns a far pointer to the long string containing the 
  649.     printer names from the win.ini file.  The calling routine should
  650.     free the space for the printer list using the OurFree function.  The argument
  651.     returns the number of printers in the list.
  652. *******************************************************************************/
  653. LPSTR GetPrinterList(int far *count)
  654. {
  655.     int BufSize=1500,StringSize,CurSize,len;
  656.     LPSTR string;
  657.  
  658.  
  659.     if (NULL==(string=OurAlloc(BufSize))) return NULL;
  660.  
  661.     StringSize=GetProfileString("devices",NULL,"",string,BufSize);
  662.  
  663.     CurSize=0;
  664.     (*count)=0;
  665.  
  666.     while(CurSize<StringSize) {
  667.         (*count)++;
  668.         len=lstrlen(&string[CurSize]);
  669.         CurSize=CurSize+len+1;
  670.     }
  671.  
  672.     return string;
  673. }
  674.  
  675. /******************************************************************************
  676.     HugeMove:
  677.     Use this function to move data from one buffer to another when the
  678.     buffer may be larger than 64K.  This function handles overlapping
  679.     buffers.
  680.     Small/Medium Model Note:  This function will not work if compiled 
  681.     as an EXECUTABLE under small/medium model using the Borland compiler.
  682.     This is because Borland 'C' does not have a fmemmove library function.
  683.     
  684.     Note that this restriction is only for an executable and not for a DLL.
  685. *******************************************************************************/
  686. void HugeMove(void huge *src,void huge * dest, long count)
  687. {
  688.     #if defined(WIN32)
  689.        memmove(dest,src,count);
  690.     #else
  691.        long BuffSize=0x1000; // 4 K 
  692.        long BytesMoved=0;
  693.        long MoveSize;
  694.        void far *CurSrc,far *CurDest;
  695.        char huge *CharSrc;      // source cast as character pointer
  696.        char huge *CharDest;     // destination cast as character pointer
  697.  
  698.        if (count<=0 || src==dest) return;
  699.  
  700.        if (count<=0xFFFFL) {   // less than 64 K
  701.           FarMoveOl(src,dest,(WORD)count);
  702.           return;
  703.        }
  704.  
  705.        // move in 64K blocks now
  706.        CharSrc=(char huge *)src;
  707.        CharDest=(char huge *)dest;
  708.  
  709.        while (count>0) {
  710.           // calculate amount to move
  711.           if (count>=BuffSize) MoveSize=BuffSize;
  712.           else                 MoveSize=count;
  713.           
  714.           // calculate source and destination addresses
  715.           if (src>dest) {       // move from the top
  716.              CurSrc=(void far *)&CharSrc[BytesMoved];
  717.              CurDest=(void far *)&CharDest[BytesMoved];
  718.           }
  719.           else {               // move from the bottom to handle overlapping block
  720.              CurSrc=(void far *)&CharSrc[count-MoveSize];
  721.              CurDest=(void far *)&CharDest[count-MoveSize];
  722.           }
  723.  
  724.           // move this block
  725.           FarMoveOl(CurSrc,CurDest,(WORD)MoveSize);
  726.           count-=MoveSize;      // bytes left to move
  727.           BytesMoved+=MoveSize;
  728.        }
  729.     #endif
  730.     
  731.     return;
  732. }
  733.  
  734.