home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic 4 Unleashed / Visual_Basic_4_Unleashed_SAMS_Publishing_1995.iso / repease / rep_ini.c < prev    next >
C/C++ Source or Header  |  1995-07-18  |  37KB  |  864 lines

  1. /*==============================================================================
  2.    REP_INI.C
  3.    Report Ease initialization and exit functions.
  4.  
  5.    ReportEase Plus
  6.    Sub Systems, Inc.
  7.    ReportEase Plus, Copyright (c) 1993, Sub Systems, Inc. All Rights Reserved.
  8.    159 Main Street, #8C, Stoneham,  MA 02180 
  9.    (617) 438-8901.
  10.  
  11.    Software License Agreement  (1993)              
  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 "sys\types.h"
  39. #include "sys\stat.h"
  40. #include "string.h"
  41. #include "setjmp.h"
  42.  
  43. #include "rep.h"
  44.  
  45. #define  PREFIX extern
  46. #include "rep1.h"
  47.  
  48. BOOL ReportEaseActive=FALSE;    // TRUE when report ease has been called 
  49.  
  50. /*****************************************************************************
  51.    InitFr:
  52.      a. Construct a window class for FORM and create a window.
  53.      b. Initialize pointer and line length arrays.
  54.      c. Read the input file or parse the input buffer.
  55.      d. Initialize cursor, etc.
  56.  
  57.      This function return 0 on a successful execution, otherwise it 
  58.      returns an error code.
  59. *****************************************************************************/
  60. BOOL InitFr (DWORD WinStyle, int x,int y, int width, int height)
  61. {
  62.      // create a window class and the main ter edit window 
  63.  
  64.     WNDCLASS  wc;
  65.     char string[100],ClassName[20];
  66.  
  67.     if (ReportEaseActive) {
  68.        MessageBox(hFrParentWnd,"Report Ease Already Active!",NULL,MB_OK);
  69.        return ERR_DUPLICATE;
  70.     }
  71.     ReportEaseActive=TRUE;
  72.  
  73.     //********** initialization ********************
  74.     InitVariables();                       // initialize the global variables 
  75.  
  76.     AllocArrayMem();                       // allocate memory for line data arrays 
  77.  
  78.  
  79.     //***********************************************************************
  80.     if (CurrentPrinter(PrinterName,PrinterDriver,PrinterPort)) {
  81.         if (!InitPrinter()) return ERR_PRINTER;  // get current printer info 
  82.     }
  83.     else return ERR_PRINTER;
  84.  
  85.     //****************** set screen window or the printer characteristics ***
  86.     if (UseScreen) {                       // create the window 
  87.         if (SessionType=='F') strcpy(ClassName,"FrClass");
  88.         else                  strcpy(ClassName,"RepClass");
  89.  
  90.         //****** register class ******
  91.         wc.style = CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW|CS_BYTEALIGNCLIENT;    // allocate a DC for this class 
  92.         wc.cbClsExtra = 0;
  93.         wc.cbWndExtra = 0;
  94.         wc.hInstance = hFrInst;
  95.         wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  96.         if (SessionType=='F') wc.hCursor = NULL;                       // under form editor control
  97.         else                  wc.hCursor = LoadCursor(NULL,IDC_ARROW); // use default cursor
  98.         wc.hbrBackground = GetStockObject(WHITE_BRUSH); 
  99.         wc.lpszMenuName =  NULL;
  100.         if (SessionType=='F') wc.lpfnWndProc = (void far *)FrWndProc;
  101.         else                  wc.lpfnWndProc = (void far *)RepWndProc;
  102.         wc.lpszClassName = ClassName;
  103.         RegisterClass(&wc);                      // class registered 
  104.  
  105.         if (FrFileName[0]==0) strcpy(string,"(UNNAMED)");else strcpy(string,FrFileName);
  106.  
  107.         hFrMenu=0;
  108.         if (SessionType=='F') {
  109.            if (FormArg.ShowMenu) hFrMenu=LoadMenu(hFrInst,"FrMenu");
  110.         }
  111.         else                      hFrMenu=LoadMenu(hFrInst,"RepMenu");
  112.  
  113.         WindowBeingCreated=TRUE;               //to avoid certain functions during a window creation 
  114.  
  115.         hFrWnd = CreateWindow(ClassName,string,WinStyle,x,y,width,height,hFrParentWnd,hFrMenu,hFrInst,NULL);                        
  116.         
  117.         if (SessionType=='F') FormArg.hFrWnd=hFrWnd;
  118.         
  119.         ShowWindow(hFrWnd, SW_SHOW);
  120.         SetFocus(hFrWnd);
  121.         ValidateRect(hFrWnd,NULL);          // No need to paint right now 
  122.     }
  123.     else  hFrWnd=hFrParentWnd;              // set printer device context 
  124.     
  125.     InitDeviceProp();                       // initialize device properties 
  126.     WindowBeingCreated=FALSE;
  127.  
  128.     //***************** Allocate wrap buffer and read file ***************
  129.  
  130.     lstrcpy(string,FrFileName);             // temporarily convert far to near pointer 
  131.     if (!FrRead(string)) return ERR_IO;
  132.  
  133.     if (FrShowHorBar || FrShowVerBar) SetScrollBars();
  134.  
  135.     if (SessionType=='F') {
  136.        GetWinDimension();                      // recalculate the window dimensions
  137.        PaintFlag=PAINT_WIN;
  138.        FrPaint();
  139.     }
  140.  
  141.     FrModified=FALSE;
  142.  
  143.     return 0;                               // successful 
  144. }
  145.  
  146. /******************************************************************************
  147.     InitVariables:
  148.     Initialize the global variables.
  149. *******************************************************************************/
  150. void InitVariables() 
  151. {
  152.     int i;
  153.  
  154.     SelItem       =-1;    // selected screen item
  155.     TotalItems    =0;     // Total Screen items
  156.     CharHeight    =0;     // height of a character using the default font
  157.     CurCmd        =-1;    // Store the id of the current command
  158.     TotalTabRects =0;     // number of tab rectangle being displayed
  159.     hDescWnd      =NULL;  // field and label description window
  160.     hBM           =NULL;  // Compatible bitmap handle                                              
  161.     FrWidth       =0;     // Screen form width
  162.     FrHeight      =0;     // Screen for height
  163.     FrWinOrgX     =0;     // current horizontal window x co-ordinate in the logical space 
  164.     FrWinOrgY     =0;     // current vertical window x co-ordinate in the logical space 
  165.  
  166.     FocusRectDrawn=FALSE;        // Turn of the focus rectangle
  167.     IgnoreMouseMove=TRUE;        // ignore mouse move until a mouse button is depressed 
  168.  
  169.     hFrWnd        =NULL;         // window handle
  170.     hFrFont       =NULL;         // initialize the font variables 
  171.     FrFont        =NULL;
  172.     TotalFonts    =0;            // not fonts created yet 
  173.  
  174.     hMetaFile     =0;            // initialize the metafile handle
  175.     hMetaDC       =0;            // initialize the metafile device context
  176.  
  177.     ReportStatus  =REP_RESUMED;  // can have suspended,resumed,over and abort values 
  178.  
  179.     WindowBeingCreated=FALSE;    // TRUE when a window is being created 
  180.     
  181.     DrawColor     =0x00000000;   // Color to draw ruler, input area, and divider lines
  182.     BackColor     =0x00FFFFFF;   // background color
  183.     InputAreaColor=0x007F7F7F;   // input area color
  184.     SelectionColor=0x000000FF;   // Multiple selection rectangle
  185.     OptRectColor  =0x007F7F00;   // color of the option rectangles
  186.  
  187.     FrHelpWanted =FALSE;         // TRUE when help is requested 
  188.     FrModified   =FALSE;         // file modification flag 
  189.     strcpy(FrHelpFile,"REP.HLP");// FORM help file 
  190.  
  191.     FontSign=0xBE;               // indicates the beginning of the font table 
  192.  
  193.     hDevMode=0;
  194.     hFrDC=0;                     // window device context 
  195.     hPrtDC=0;                    // printer device context 
  196.     hFrAccTable=NULL;            // accelerator table handle 
  197.  
  198.     PaintEnabled=TRUE;           // painting enabled  
  199.  
  200.     TotalFields=0;               // total fields in the form 
  201.     TotalBreakFields=0;          // total Break Fields in the form 
  202.  
  203.     MsgCallback=NULL;            // message callback function
  204.  
  205.     printing=FALSE;              // TRUE when selectively printing from screen
  206.  
  207.     OurEditProc = (WNDPROC)MakeProcInstance((FARPROC)FrEditSubclass, hFrInst);
  208.     UndoItem=NULL;               // item undo data
  209.  
  210.     // define section names *****************************************
  211.     
  212.     strcpy(SectionName[SEC_HDR_REP]     ," Report Header ");
  213.     strcpy(SectionName[SEC_HDR_PAGE]    ,"  Page Header  ");
  214.     strcpy(SectionName[SEC_HDR_LVL1]    ," Sort 1 Header ");
  215.     strcpy(SectionName[SEC_HDR_LVL2]    ," Sort 2 Header ");
  216.     strcpy(SectionName[SEC_HDR_LVL3]    ," Sort 3 Header ");
  217.     strcpy(SectionName[SEC_HDR_LVL4]    ," Sort 4 Header ");
  218.     strcpy(SectionName[SEC_HDR_LVL5]    ," Sort 5 Header ");
  219.     strcpy(SectionName[SEC_HDR_LVL6]    ," Sort 6 Header ");
  220.     strcpy(SectionName[SEC_HDR_LVL7]    ," Sort 7 Header ");
  221.     strcpy(SectionName[SEC_HDR_LVL8]    ," Sort 8 Header ");
  222.     strcpy(SectionName[SEC_HDR_LVL9]    ," Sort 9 Header ");
  223.     strcpy(SectionName[SEC_DETAIL1]     ," Detail 1 Section ");
  224.     strcpy(SectionName[SEC_DETAIL2]     ," Detail 2 Section ");
  225.     strcpy(SectionName[SEC_DETAIL3]     ," Detail 3 Section ");
  226.     strcpy(SectionName[SEC_DETAIL4]     ," Detail 4 Section ");
  227.     strcpy(SectionName[SEC_DETAIL5]     ," Detail 5 Section ");
  228.     strcpy(SectionName[SEC_DETAIL6]     ," Detail 6 Section ");
  229.     strcpy(SectionName[SEC_DETAIL7]     ," Detail 7 Section ");
  230.     strcpy(SectionName[SEC_DETAIL8]     ," Detail 8 Section ");
  231.     strcpy(SectionName[SEC_DETAIL9]     ," Detail 9 Section ");
  232.     strcpy(SectionName[SEC_FTR_LVL9]    ," Sort 9 Footer ");
  233.     strcpy(SectionName[SEC_FTR_LVL8]    ," Sort 8 Footer ");
  234.     strcpy(SectionName[SEC_FTR_LVL7]    ," Sort 7 Footer ");
  235.     strcpy(SectionName[SEC_FTR_LVL6]    ," Sort 6 Footer ");
  236.     strcpy(SectionName[SEC_FTR_LVL5]    ," Sort 5 Footer ");
  237.     strcpy(SectionName[SEC_FTR_LVL4]    ," Sort 4 Footer ");
  238.     strcpy(SectionName[SEC_FTR_LVL3]    ," Sort 3 Footer ");
  239.     strcpy(SectionName[SEC_FTR_LVL2]    ," Sort 2 Footer ");
  240.     strcpy(SectionName[SEC_FTR_LVL1]    ," Sort 1 Footer ");
  241.     strcpy(SectionName[SEC_FTR_PAGE]    ,"  Page Footer  ");
  242.     strcpy(SectionName[SEC_FTR_REP]     ," Report Footer ");
  243.  
  244.     // Initialize the section array 
  245.     for (i=0;i<MAX_SECTIONS;i++) {
  246.         section[i].InUse=FALSE;
  247.         section[i].flags=0;              // see SFLAG_ flags 
  248.         section[i].FirstItem=0;
  249.         section[i].ItemCount=0;
  250.         section[i].columns=1;            // number of columns across 
  251.         section[i].SelExp[0]=END_OF_EXP; // section selection criteria 
  252.         section[i].selected=TRUE;        // answer of the selection expression 
  253.         memset(section[i].reserved,0,sizeof(section[i].reserved));
  254.     }
  255.     
  256.     // define system fields 
  257.     strcpy(SysField[SYS_PAGE].name,"PAGE");
  258.     SysField[SYS_PAGE].type=TYPE_NUM;
  259.     SysField[SYS_PAGE].width=4;
  260.  
  261.     strcpy(SysField[SYS_DATE].name,"DATE");
  262.     SysField[SYS_DATE].type=TYPE_DATE;
  263.     SysField[SYS_DATE].width=10;
  264.  
  265.     strcpy(SysField[SYS_TIME].name,"TIME");
  266.     SysField[SYS_TIME].type=TYPE_TEXT;
  267.     SysField[SYS_TIME].width=10;
  268.  
  269.     strcpy(SysField[SYS_REC_COUNT].name,"REC_COUNT");
  270.     SysField[SYS_REC_COUNT].type=TYPE_NUM;
  271.     SysField[SYS_REC_COUNT].width=6;
  272.  
  273.     strcpy(SysField[SYS_PARA_BREAK].name,"PARA_BREAK");
  274.     SysField[SYS_PARA_BREAK].type=TYPE_TEXT;
  275.     SysField[SYS_PARA_BREAK].width=2;
  276.  
  277.     //**** define the print value types 
  278.     strcpy(SumName[SUM_NONE]   ,"Value");
  279.     strcpy(SumName[SUM_TOTAL]  ,"Total");
  280.     strcpy(SumName[SUM_AVERAGE],"Average");
  281.     strcpy(SumName[SUM_COUNT]  ,"Count");
  282.     strcpy(SumName[SUM_MAX]    ,"Max");
  283.     strcpy(SumName[SUM_MIN]    ,"Min");
  284.  
  285.     //**** define the date formats 
  286.     strcpy(DateFormat[DT_MMDDYY]    ,"MMDDYY");
  287.     strcpy(DateFormat[DT_DDMMYY]    ,"DDMMYY");
  288.     strcpy(DateFormat[DT_MMDDYYYY]  ,"MMDDYYYY");
  289.     strcpy(DateFormat[DT_MMMDDYYYY] ,"MMMDDYYYY");
  290.  
  291.     //***** define the operator symbols ****
  292.  
  293.     InitOp(OP_COMMA,",",30,FALSE,FALSE,FALSE,"");
  294.  
  295.     InitOp(OP_ELSE,".ELSE.",40,FALSE,FALSE,FALSE,"");
  296.  
  297.     InitOp(OP_THEN,".THEN.",50,FALSE,FALSE,FALSE,"");
  298.  
  299.     InitOp(OP_IF,".IF.",60,TRUE,FALSE,FALSE,"");
  300.  
  301.     InitOp(OP_OR,".OR.",100,FALSE,FALSE,FALSE,"");
  302.  
  303.     InitOp(OP_AND,".AND.",200,FALSE,FALSE,FALSE,"");
  304.  
  305.     InitOp(OP_EQU,"=",300,FALSE,FALSE,FALSE,"");
  306.     InitOp(OP_NOT_EQU,"<>",300,FALSE,FALSE,FALSE,"");
  307.     InitOp(OP_NOT_EQU2,".",300,FALSE,FALSE,FALSE,"");
  308.  
  309.     InitOp(OP_GT,">",400,FALSE,FALSE,FALSE,"");
  310.     InitOp(OP_LT,"<",400,FALSE,FALSE,FALSE,"");
  311.     InitOp(OP_GTE,">=",400,FALSE,FALSE,FALSE,"");
  312.     InitOp(OP_LTE,"<=",400,FALSE,FALSE,FALSE,"");
  313.  
  314.     InitOp(OP_PART,"$",500,FALSE,FALSE,FALSE,"");
  315.  
  316.     InitOp(OP_PLUS,"+",600,FALSE,FALSE,FALSE,"");
  317.     InitOp(OP_MINUS,"-",600,FALSE,FALSE,FALSE,"");
  318.  
  319.     InitOp(OP_MULT,"*",700,FALSE,FALSE,FALSE,"");
  320.     InitOp(OP_DIV,"/",700,FALSE,FALSE,FALSE,"");
  321.  
  322.     InitOp(OP_NOT,".NOT.",800,TRUE,FALSE,FALSE,"");
  323.  
  324.     InitOp(OP_TOT_OF,".TOTAL-OF.",900,TRUE,TRUE,FALSE,"");
  325.     InitOp(OP_AVE_OF,".AVE-OF.",900,TRUE,TRUE,FALSE,"");
  326.     InitOp(OP_MAX_OF,".MAX-OF.",900,TRUE,TRUE,FALSE,"");
  327.     InitOp(OP_MIN_OF,".MIN-OF.",900,TRUE,TRUE,FALSE,"");
  328.     InitOp(OP_COUNT_OF,".COUNT-OF.",900,TRUE,TRUE,FALSE,"");
  329.  
  330.     InitOp(OP_LEN,"LEN",950,TRUE,FALSE,TRUE,     "LEN(string)\t-> Length of a String");          // functions 
  331.     InitOp(OP_UPPER,"UPPER",950,TRUE,FALSE,TRUE, "UPPER(string)\t-> Convert to UPPER CASE");
  332.     InitOp(OP_LOWER,"LOWER",950,TRUE,FALSE,TRUE, "LOWER(string)\t-> Convert to lower case");
  333.     InitOp(OP_TRIM,"TRIM",950,TRUE,FALSE,TRUE,   "TRIM(string)\t-> Trim Beginning and Ending Spaces ");
  334.     InitOp(OP_WORD,"WORD",950,FALSE,FALSE,TRUE,  "WORD(string,num)\t-> Extract a Word from the String");
  335.     InitOp(OP_CHAR,"CHAR",950,FALSE,FALSE,TRUE,  "CHAR(string,num)\t-> Extract a character from the String");
  336.  
  337.     InitOp(OP_MIN,"MIN",950,FALSE,FALSE,TRUE,    "MIN(num1,num2)\t-> Find Smaller of two Numbers");
  338.     InitOp(OP_MAX,"MAX",950,FALSE,FALSE,TRUE,    "MAX(num1,num2)\t-> Find Larger of two Numbers");
  339.     InitOp(OP_ROUND,"ROUND",950,FALSE,FALSE,TRUE,"ROUND(num1,num2)\t-> Round Num1 to Num2 Decimal Places");
  340.     InitOp(OP_INT,"INT",950,TRUE,FALSE,TRUE,     "INT(num/string/date)\t-> Convert to Integer Number");
  341.     InitOp(OP_ABS,"ABS",950,TRUE,FALSE,TRUE,     "ABS(num)\t-> Find Absolute Value");
  342.  
  343.     InitOp(OP_WEEKDAY,"WEEKDAY",950,TRUE,FALSE,TRUE,"WEEKDAY(date)\t-> Day of the week (string)");
  344.     InitOp(OP_DAY,"DAY",950,TRUE,FALSE,TRUE,        "DAY(date)\t-> Extract Day (nn) from a Date");
  345.     InitOp(OP_MONTH,"MONTH",950,TRUE,FALSE,TRUE,    "MONTH(date)\t-> Extract Month (nn) from a Date");
  346.     InitOp(OP_YEAR,"YEAR",950,TRUE,FALSE,TRUE,      "YEAR(date)\t-> Extract Year (nnnn) from a Date");
  347.  
  348.     InitOp(OP_FIRST_CHARS,"FIRST",950,FALSE,FALSE,TRUE,"FIRST(string,num)\t-> Extract First (num) Characters from the String");
  349.     InitOp(OP_LAST_CHARS,"LAST",950,FALSE,FALSE,TRUE,"LAST(string,num)\t-> Extract Last (num) Characters from the String");
  350.     InitOp(OP_TEXT,"TEXT",950,TRUE,FALSE,TRUE,       "TEXT(num/date)\t-> Convert to String Format");
  351.  
  352.     InitOp(OP_LPARAN,"(",1000,FALSE,FALSE,FALSE,"");
  353.     InitOp(OP_RPARAN,")",1000,FALSE,FALSE,FALSE,"");
  354.  
  355.  
  356.     //************* initialize the dialog fields ***************************
  357.     for (i=0;i<MAX_DLGS;i++) {
  358.         DlgField[i].InUse=FALSE;
  359.         memset(DlgField[i].reserved,0,sizeof(DlgField[i].reserved));
  360.     }
  361.  
  362.     //************* initialize the field string ***************************
  363.     for (i=0;i<NAME_WIDTH;i++) FieldString[i]=(char)(BYTE)FIELD_CHAR;
  364.     FieldString[i]=0;
  365.  
  366.     //************* initialize the option rectangle fields *****************
  367.     DrawOptRect=FALSE;
  368. }
  369.  
  370. /*****************************************************************************
  371.     InitOp:
  372.     Initialize operator symbol, precedence and unary/binary characteristics
  373. ******************************************************************************/
  374. InitOp(int OpId,LPSTR sym,int prec,BOOL unry,BOOL FooterOnly,BOOL fct,LPSTR help)
  375. {
  376.     int len;
  377.  
  378.     strcpy(OpSym[OpId-FIRST_OP],sym);       // operator symbol 
  379.     OpPrec[OpId-FIRST_OP]=prec;             // operator precedence level 
  380.     OpUnary[OpId-FIRST_OP]=unry;            // is it a unary operator 
  381.     OpFooter[OpId-FIRST_OP]=FooterOnly;     // valid only for footers 
  382.     OpFct[OpId-FIRST_OP]=fct;               // is it a function 
  383.     
  384.     len=strlen(help);
  385.     if (NULL==(OpHelp[OpId-FIRST_OP]=OurAlloc(len))) return FALSE;
  386.     if (len>0) lstrcpy(OpHelp[OpId-FIRST_OP],(LPSTR)help); // help message for the operator/function 
  387.  
  388.     return TRUE;
  389. }
  390.  
  391.  
  392. /*****************************************************************************
  393.     InitNewForm:
  394.     Initialize a new report.
  395. ******************************************************************************/
  396. InitNewForm()
  397. {
  398.     int CurItem;
  399.     
  400.     if (SessionType=='R') return TRUE;
  401.  
  402.     FormHdr.FormSign=FORM_SIGN;     // initialized the report hdr 
  403.     FormHdr.FileFormatId=CUR_FILE_FORMAT; // file format id
  404.     strcpy(FormHdr.name,FrFileName);// default report 
  405.     FormHdr.TotalItems=TotalItems;
  406.     FormHdr.FieldCount=TotalFields; // number of fields in the report 
  407.     FormHdr.BreakFieldCount=TotalBreakFields;
  408.     FormHdr.FontCount=TotalFonts;   // default font 
  409.     FormHdr.flags=0;
  410.     FormHdr.RulerType=RULER_INCH;   // select inch ruler
  411.     FormHdr.SecBannerHeight=CharHeight; // height of the section banner
  412.  
  413.     strcpy(FormHdr.DataSetName,FormArg.DataSetName);  // store the data set name (optional info) 
  414.  
  415.     // initialize the header fields 
  416.     FormHdr.LeftMargin=(float).25;  // margins in inches 
  417.     FormHdr.RightMargin=(float).25;
  418.     FormHdr.TopMargin=(float).5;
  419.     FormHdr.BottomMargin=(float).5;
  420.  
  421.     ProcessPrinterData();         // calculate operational variables from the header data 
  422.  
  423.     /*********************** Create Default Sections ********************/
  424.     CurItem=0;                                       // create header title section 
  425.     TotalItems=1;
  426.     InitItem(&item[CurItem]);                        // initialize the current item variables
  427.     item[CurItem].type=SECTION;
  428.     item[CurItem].x=(int)(FormHdr.LeftMargin*UNITS_PER_INCH);
  429.     item[CurItem].y=0;
  430.     item[CurItem].width=FrWidth-(int)(UNITS_PER_INCH*(FormHdr.LeftMargin+FormHdr.RightMargin));
  431.     item[CurItem].height=DEF_SEC_HEIGHT;
  432.     item[CurItem].section=SEC_HDR_PAGE;
  433.     section[SEC_HDR_PAGE].InUse=TRUE;                // define the page header
  434.     section[SEC_HDR_PAGE].ScrItem=CurItem;           // reference to the item
  435.  
  436.     FrHeight=item[CurItem].y+item[CurItem].height;   // current height of the form 
  437.  
  438.     CurItem++;                                       // create the group item 
  439.     TotalItems++;
  440.     InitItem(&item[CurItem]);                        // initialize the current item variables
  441.     item[CurItem].type=GROUP;
  442.     item[CurItem].width=2*DEF_RECT_WIDTH;
  443.     item[CurItem].height=2*DEF_RECT_HEIGHT;
  444.     item[CurItem].x=item[0].x+(item[0].width-item[CurItem].width)/2;
  445.     item[CurItem].y=item[0].y+CharHeight+(item[0].height-CharHeight-item[CurItem].height)/2;
  446.     item[CurItem].section=item[0].section;           // place it int the first section
  447.  
  448.  
  449.     CurItem++;                                       // create a detail section 
  450.     TotalItems++;
  451.     InitItem(&item[CurItem]);                        // initialize the current item variables
  452.     item[CurItem].type=SECTION;
  453.     item[CurItem].x=(int)(FormHdr.LeftMargin*UNITS_PER_INCH);
  454.     item[CurItem].y=FrHeight;
  455.     item[CurItem].width=FrWidth-(int)(UNITS_PER_INCH*(FormHdr.LeftMargin+FormHdr.RightMargin));
  456.     item[CurItem].height=DEF_SEC_HEIGHT;
  457.     item[CurItem].section=SEC_DETAIL1;
  458.     section[SEC_DETAIL1].InUse=TRUE;                 // define the page header 
  459.     section[SEC_DETAIL1].ScrItem=CurItem;            // reference to the item
  460.  
  461.     FrHeight=item[CurItem].y+item[CurItem].height;   // current height of the form 
  462.  
  463.     FormHdr.SelExp[0]=END_OF_EXP;                    // initialize record selection expression 
  464.  
  465.     // initialize the reserved space 
  466.     memset(FormHdr.reserved,0,sizeof(FormHdr.reserved));
  467.  
  468.     FrModified=FALSE;
  469.  
  470.     return TRUE;
  471. }
  472.  
  473. /*****************************************************************************
  474.     ProcessPrinterData:
  475.     Calculate operational variables from the header fields.
  476. *****************************************************************************/
  477. ProcessPrinterData()
  478. {
  479.     float length,width;
  480.     int  i,CurSec,columns;
  481.     char string[64];
  482.     HFONT hSysFont;
  483.  
  484.     // store printer and paper information 
  485.     strcpy(FormHdr.PrinterName,PrinterName);
  486.     strcpy(FormHdr.PrinterDriver,PrinterDriver);
  487.     FormHdr.Orientation=pDevMode->dmOrientation;
  488.     FormHdr.PaperSize=pDevMode->dmPaperSize;
  489.     FormHdr.PaperLength=pDevMode->dmPaperLength;
  490.     FormHdr.PaperWidth=pDevMode->dmPaperWidth;
  491.     FormHdr.PrintQuality=pDevMode->dmPrintQuality;
  492.     
  493.     strcpy(string,PrinterDriver);
  494.     string[strlen(string)-4]=0;       // strip the .drv extension 
  495.     if (hPrtDC) DeleteDC(hPrtDC);     // delete old device context
  496.     if ((hPrtDC=CreateDC(string,PrinterName,PrinterPort,pDevMode))!=NULL) {
  497.         POINT      pt;
  498.         int PrtResX=GetDeviceCaps(hPrtDC,LOGPIXELSX);    // number of pixels per inch of X direction 
  499.         int PrtResY=GetDeviceCaps(hPrtDC,LOGPIXELSY);    // number of pixels per inch of Y direction 
  500.  
  501.         Escape(hPrtDC,GETPHYSPAGESIZE,0,NULL,&pt);
  502.         width=(float)pt.x/PrtResX;                   // actual page size in inches
  503.         length=(float)pt.y/PrtResY;           
  504.         if (SessionType=='R' && UseScreen) {         // calculate the default printer font height 
  505.            CreateOneFont(hPrtDC,0);
  506.  
  507.            hSysFont=GetStockObject(SYSTEM_FONT);     // deselect our font 
  508.            SelectObject(hPrtDC,hSysFont);
  509.            DeleteObject(FrFont[0].hFont);            // delete the printer font 
  510.            FrFont[0].hFont=0;
  511.         }
  512.     }
  513.     else AbortFr("Printer Driver Error!",ERR_PRINTER);
  514.  
  515.     FrWidth=(int)(width*UNITS_PER_INCH);            // form width in logical units
  516.     
  517.     PrintWidthInches=width=width-FormHdr.LeftMargin-FormHdr.RightMargin;
  518.     PrintHeightInches=length-FormHdr.TopMargin-FormHdr.BottomMargin;
  519.  
  520.     ReportWidth=LineWidth=(int)(width*GetDeviceCaps(hFrDC,LOGPIXELSX)); 
  521.    
  522.     // Apply the margin to section items
  523.     for (i=0;i<TotalItems;i++) {
  524.        if (item[i].type!=SECTION) continue;
  525.        CurSec=item[i].section;
  526.        columns=section[CurSec].columns;
  527.        item[i].x=(int)(FormHdr.LeftMargin*UNITS_PER_INCH);
  528.        item[i].width=(FrWidth-(int)(UNITS_PER_INCH*(FormHdr.LeftMargin+FormHdr.RightMargin)))/columns;
  529.     }
  530.  
  531.     return TRUE;
  532. }
  533.  
  534.  
  535. /******************************************************************************
  536.     CloseFr:
  537.     Normal closing of FORM routine
  538. *******************************************************************************/
  539. BOOL CloseFr()
  540. {
  541.     int MessageResult,i;
  542.  
  543.     if (SessionType=='F' && FrModified) { // let user save the modifications 
  544.         if (IDYES==(MessageResult=MessageBox(hFrWnd,"Do You Wish to Save the Modifications?","File Modified",MB_YESNOCANCEL))) {
  545.            if (!FrSave(FrFileName)) return FALSE;
  546.         }
  547.         else if (MessageResult==IDCANCEL) return FALSE;
  548.     }
  549.     
  550.     WindowBeingCreated=TRUE;          // this disables message processing 
  551.  
  552.     if (hDevMode) {                    // release printer data memory 
  553.        GlobalUnlock(hDevMode);
  554.        GlobalFree(hDevMode);
  555.     }
  556.  
  557.  
  558.     // deselect objects from the main device context and release it
  559.     SelectObject(hFrDC,GetStockObject(NULL_BRUSH));
  560.     SelectObject(hFrDC,GetStockObject(NULL_PEN));
  561.     SelectObject(hFrDC,GetStockObject(SYSTEM_FONT));
  562.     if (UseScreen) ReleaseDC(hFrWnd,hFrDC);  // screen device context
  563.     else           DeleteDC(hFrDC);          // printer device context
  564.  
  565.     // delete special printer device context used for font selection
  566.     if (hPrtDC) {
  567.        SelectObject(hPrtDC,GetStockObject(SYSTEM_FONT));
  568.        DeleteDC(hPrtDC);     // delete the printer device context
  569.     }
  570.  
  571.     // delete other screen objects
  572.     if (UseScreen) {
  573.        // deselect objects from the memory and picture device contexts
  574.        // and delete the device contexts
  575.        SelectObject(hMemDC,hOldBM);
  576.        SelectObject(hMemDC,GetStockObject(SYSTEM_FONT));
  577.        SelectObject(hMemDC,GetStockObject(NULL_PEN));
  578.        SelectObject(hMemDC,GetStockObject(NULL_BRUSH));
  579.        DeleteDC(hMemDC);
  580.  
  581.        DeleteDC(hPictDC);
  582.  
  583.        // delete other objects
  584.        DeleteObject(hBM);                 // compatible bitmap
  585.  
  586.        DeleteObject(hBackBrush);          // background brush
  587.        DeleteObject(hDrawBrush);          // foreground drawing brush
  588.        DeleteObject(hInputAreaBrush);     // input area drawing brush
  589.  
  590.        DeleteObject(hFrPen);              // delete the regular pen 
  591.        DeleteObject(hFocusPen);           // delete the focus pen 
  592.        DeleteObject(hSelectionPen);       // delete the multiple selectio pen
  593.     }
  594.     
  595.     //************ delete fonts **********
  596.     for (i=0;i<TotalFonts;i++) {              // delete font objects 
  597.        if (FrFont[i].InUse) DeleteFrObject(i);// delete font/picture 
  598.     }
  599.     
  600.  
  601.     if (SessionType=='F') FormArg.open=FALSE;// mark the window as closed 
  602.  
  603.     if (UseScreen) DestroyWindow(hFrWnd);
  604.     
  605.     // Free metafile
  606.     if (hMetaFile) DeleteMetaFile(hMetaFile);
  607.  
  608.     // free process instance
  609.     FreeProcInstance((FARPROC)OurEditProc);
  610.  
  611.     // relase memory used by line arrays 
  612.     GlobalUnlock(hItem);
  613.     GlobalFree(hItem);
  614.  
  615.     GlobalUnlock(hFrFont);
  616.     GlobalFree(hFrFont);
  617.  
  618.     GlobalUnlock(hField);
  619.     GlobalFree(hField);
  620.  
  621.     GlobalUnlock(hTempField);
  622.     GlobalFree(hTempField);
  623.  
  624.  
  625.     //************ release memory used by operator help messages ******
  626.     for (i=0;i<MAX_OPS;i++) OurFree(OpHelp[i]);
  627.     
  628.     ReportEaseActive=FALSE;
  629.  
  630.     if (hFrParentWnd) {
  631.        if (MsgCallback!=NULL) MsgCallback(hFrWnd,REP_CLOSE);
  632.        else SendMessage(hFrParentWnd,REP_CLOSE,0,0L); // inform the parent window of closing 
  633.  
  634.        SetFocus(hFrParentWnd);
  635.     }
  636.     
  637.     return TRUE;
  638. }
  639.  
  640. /******************************************************************************
  641.    AbortFr:
  642.    Handles an abnormal termination of FORM routine.
  643. *******************************************************************************/
  644. void AbortFr(LPSTR desc,UINT code)
  645. {
  646.  
  647.    if (lstrlen(desc)>0) MessageBox(NULL,desc,"Fatal Error",MB_OK);
  648.    ReportEaseActive=FALSE;
  649.    
  650.    if (SessionType=='F') PostQuitMessage(code);
  651.    else                  ErrorCode=code;
  652.    // return an error code
  653.    #if defined (WIN32)
  654.       longjmp(FrAbort,-1);
  655.    #else
  656.       Throw((LPCATCHBUF) &FrAbort,-1);
  657.    #endif
  658. }
  659.                          
  660. /******************************************************************************
  661.    AllocArrayMem:
  662.    Allocate fixed global memory of the following types:
  663.       1.  Memory to store the handle to the line text data.
  664.       2.  Memory to store the handle to the line formatting data.
  665.       3.  Memory to store the fonts structure for the current window.
  666.       4.  Memory to store the line length of each line.
  667. *******************************************************************************/
  668. AllocArrayMem()
  669. {
  670.  
  671.     if ( (NULL==(hItem=GlobalAlloc(GMEM_MOVEABLE,(long)(MAX_ITEMS+1)*(long)sizeof(struct StrItem)))) 
  672.        || (NULL==(item=(struct StrItem huge *)GlobalLock(hItem))) 
  673.        || (NULL==(hFrFont=GlobalAlloc(GMEM_MOVEABLE,(long)(MAX_FONTS)*sizeof(struct StrFont)))) 
  674.        || (NULL==(FrFont=(struct StrFont far *)GlobalLock(hFrFont)))  
  675.        || (NULL==(hField=GlobalAlloc(GMEM_MOVEABLE,(long)(MAX_FIELDS+1)*sizeof(struct StrField)))) 
  676.        || (NULL==(field=(struct StrField huge *)GlobalLock(hField)))  
  677.        || (NULL==(hTempField=GlobalAlloc(GMEM_MOVEABLE,(long)(MAX_TEMP_FIELDS+1)*sizeof(struct StrField)))) 
  678.        || (NULL==(TempField=(struct StrField huge *)GlobalLock(hTempField)))  ) {
  679.        AbortFr("Ran Out of Memory (AllocArrayMem)",ERR_NO_MEM);
  680.     }
  681.     return TRUE;
  682. }
  683.  
  684. /******************************************************************************
  685.     InitDeviceProp:
  686.     Initialize Device properties such as display context, fonts etc.
  687. ******************************************************************************/
  688. void InitDeviceProp()
  689. {
  690.     int i,result;
  691.  
  692.     //********************* initialize the font table ******************
  693.     for (i=0;i<MAX_FONTS;i++) InitFrObject(i);  // initialize the font table 
  694.     TotalFonts=0;
  695.  
  696.     hWaitCursor=LoadCursor(NULL,IDC_WAIT);      // load hour glass cursor 
  697.     hArrowCursor=LoadCursor(NULL,IDC_ARROW);    // Regular Arrow cursor
  698.  
  699.     if (!UseScreen) return;
  700.     //************* properties specific to a screen window *************
  701.     
  702.     if (NULL==(hFrDC=GetDC(hFrWnd))) {          // allocate a class DC 
  703.          AbortFr("Unable to allocate a Display Context.",ERR_DISPLAY);
  704.     }
  705.     ResY=GetDeviceCaps(hFrDC,LOGPIXELSY);       // resolution (pixel/logical inch) of the current device 
  706.     ResX=GetDeviceCaps(hFrDC,LOGPIXELSX);
  707.     
  708.     SetLogicalUnit(hFrDC);                      // set the windows logical units to logical LOMETRIC 
  709.  
  710.     //************** establish the default font in the font table **********
  711.     TotalFonts=1;
  712.     FrFont[0].InUse=TRUE;                       // mark as in-use 
  713.     FrFont[0].IsPict=FALSE;                     // not a picture 
  714.     FrFont[0].hFont=NULL;
  715.     if (SessionType=='F') result=SelectBestFont(hFrDC,0,FormArg.FontTypeFace,11);
  716.     else                  result=SelectBestFont(hFrDC,0,"Courier New",11);
  717.     if (!result) {                               // font creation error
  718.        AbortFr("Error Creating Font(InitDeviceProp)",ERR_DISPLAY);
  719.     }
  720.  
  721.     hFrRegFont=hFrCurFont=FrFont[0].hFont;
  722.     CharHeight=FrFont[0].height;                // height of a character using the default font
  723.  
  724.     if (NULL==SelectObject(hFrDC,hFrRegFont)) { // select the newly created font 
  725.          AbortFr("Unable to select the font.",ERR_DISPLAY);
  726.     } 
  727.  
  728.     if (!GetTextMetrics(hFrDC,&FrTextMet)) {    // get text metric for the newly created font 
  729.          AbortFr("Unable to get text metric for the font.",ERR_DISPLAY);
  730.     } 
  731.     
  732.     if ( NULL==(hMemDC=CreateCompatibleDC(hFrDC))    // to buffer screen
  733.       || NULL==(hPictDC=CreateCompatibleDC(hFrDC)) ) {// to paint pictures 
  734.        AbortFr("Unable to create compatible DC",ERR_DISPLAY);
  735.     }
  736.     SetLogicalUnit(hMemDC);                       // set the windows logical units to logical LOMETRIC 
  737.     SetLogicalUnit(hPictDC);                      // set the windows logical units to logical LOMETRIC 
  738.  
  739.     GetWinDimension();                             // get window dimensions 
  740.  
  741.     SetBkMode(hFrDC,OPAQUE);                       // enable opaqe printing of text 
  742.  
  743.     hBackBrush=CreateSolidBrush(BackColor);        // solid brush to clear the background 
  744.     hDrawBrush=CreateSolidBrush(DrawColor);        // solid brush to reverse the background 
  745.     hInputAreaBrush=CreateSolidBrush(InputAreaColor);// solid brush to clear the input area background 
  746.     
  747.     if (NULL==(hFrPen=CreatePen(PS_SOLID,1,DrawColor))     // pen to draw ruler, input area, divider lines
  748.      || NULL==(hFocusPen=CreatePen(PS_DOT,1,DrawColor))    // pen to draw the focus rectangle
  749.      || NULL==(hSelectionPen=CreatePen(PS_SOLID,1,SelectionColor)) ){ // pen to draw the selection rectangle
  750.          AbortFr("Unable to create pens.",ERR_DISPLAY);
  751.     } 
  752.  
  753.     if (FrShowHorBar) {                            // display horizontal scroll bar 
  754.        ShowScrollBar(hFrWnd,SB_HORZ,TRUE);
  755.        SetScrollRange(hFrWnd,SB_HORZ,HOR_SCROLL_MIN,HOR_SCROLL_MAX,FALSE);
  756.        HorScrollPos=HOR_SCROLL_MIN;
  757.        SetScrollPos(hFrWnd,SB_HORZ,HorScrollPos,TRUE);
  758.        GetWinDimension();                          // get window dimensions 
  759.     }
  760.  
  761.     if (FrShowVerBar) {                            // prepare vertical scroll bar 
  762.        ShowScrollBar(hFrWnd,SB_VERT,TRUE);
  763.        SetScrollRange(hFrWnd,SB_VERT,VER_SCROLL_MIN,VER_SCROLL_MAX,FALSE);
  764.        GetWinDimension();                          // get window dimensions 
  765.     }
  766.     
  767.     if (NULL==(hFrAccTable=LoadAccelerators(hFrInst,"FrAccTable"))) {   // load the accelerator table 
  768.          AbortFr("Unable to load the accelerator table.",ERR_NO_DEVICE);
  769.     }
  770.  
  771.     if (SessionType=='F') {
  772.        //****** Define cursors *********
  773.        hCrossCursor=LoadCursor(NULL,IDC_CROSS);           // Cross cursor
  774.        hHorzCursor=LoadCursor(NULL,IDC_SIZEWE);           // Horizontal Cursor
  775.        hVertCursor=LoadCursor(NULL,IDC_SIZENS);           // Vertical Cursor
  776.        hDiagCursor=LoadCursor(NULL,IDC_SIZENESW);         // Forward diagonal curosr
  777.        hDiagBackCursor=LoadCursor(NULL,IDC_SIZENWSE);     // Backward diagonal cursor
  778.     }
  779.  
  780.     ValidateRect(hFrWnd,NULL);                      // No need to paint right now 
  781. }
  782.  
  783. /******************************************************************************
  784.     SetLogicalUnit:
  785.     Set the logical unit to 1/10 of logical millimeters.
  786. *******************************************************************************/
  787. SetLogicalUnit(HDC hDC)
  788. {
  789.     SetMapMode(hDC,MM_ANISOTROPIC);               // use customized units
  790.     
  791.     SetWindowExtEx(hDC,UNITS_PER_INCH,UNITS_PER_INCH,NULL);// logical dimension
  792.     SetViewportExtEx(hDC,ResX,ResY,NULL);                  // equivalent device dimension
  793.     return TRUE;
  794. }
  795.  
  796. /******************************************************************************
  797.     InitPrinter:
  798.     Read the characteristics for the current printer.
  799. *******************************************************************************/
  800. InitPrinter()
  801. {
  802.     int bytes,len;
  803.     HINSTANCE hDriver;
  804.     int (FAR PASCAL *fpDeviceMode)(HWND,HANDLE,DEVMODE FAR *,LPSTR,LPSTR,DEVMODE FAR *,LPSTR,WORD);
  805.  
  806.     if (hDevMode) {
  807.        GlobalUnlock(hDevMode);
  808.        GlobalFree(hDevMode);
  809.        hDevMode=0;                   
  810.        pDevMode=NULL;
  811.     }
  812.  
  813.     // add .drv extension to the driver name, if necessary 
  814.     len=lstrlen(PrinterDriver);
  815.     if (len<=4 || strcmpi(&(PrinterDriver[len-4]),".DRV")!=0) lstrcat(PrinterDriver,".DRV");
  816.  
  817.     #if defined (WIN32)
  818.        // load the printer driver
  819.        if (OpenPrinter(PrinterName,&hDriver,NULL)) {
  820.           if (0==(bytes=DocumentProperties(hFrParentWnd,hDriver,PrinterName,NULL,NULL,0))) {
  821.              AbortFr("Error Initializing the printer(InitPrinter)",ERR_PRINTER);
  822.           }
  823.           if ( (NULL==(hDevMode=GlobalAlloc(GMEM_MOVEABLE,bytes))) 
  824.              || (NULL==(pDevMode=(DEVMODE far *)GlobalLock(hDevMode)))  ) {
  825.              AbortFr("Ran Out of Memory (InitPrinter)",ERR_PRINTER);
  826.           }
  827.  
  828.           if (!DocumentProperties(hFrParentWnd,hDriver,PrinterName,pDevMode,NULL,DM_COPY)) {
  829.              AbortFr("Error Initializing the printer(InitPrinter a)",ERR_PRINTER);
  830.           }
  831.  
  832.           ClosePrinter(hDriver);
  833.           return TRUE;
  834.        }
  835.     #endif
  836.  
  837.     // load the printer driver
  838.     if (((WORD)(hDriver=LoadLibrary(PrinterDriver)))<32) {
  839.        AbortFr("Invalid Printer Driver",ERR_PRINTER);
  840.     }
  841.  
  842.     fpDeviceMode=(void far *)GetProcAddress(hDriver,"ExtDeviceMode");  // if available, get the address of ExtDeviceMode function in the library 
  843.  
  844.     if (fpDeviceMode!=NULL) {       // ExtDeviceMode function is supported by the driver 
  845.                                   // get the size of the printer information block 
  846.         if ((bytes=(*fpDeviceMode)(hFrParentWnd,hDriver,NULL,(LPSTR)PrinterName,(LPSTR)PrinterPort,NULL,(LPSTR)NULL,0))<=0) {
  847.            AbortFr("Error Initializing the printer(InitPrinter)",ERR_PRINTER);
  848.         }
  849.         
  850.         if ( (NULL==(hDevMode=GlobalAlloc(GMEM_MOVEABLE,bytes))) 
  851.            || (NULL==(pDevMode=(DEVMODE far *)GlobalLock(hDevMode)))  ) {
  852.            AbortFr("Ran Out of Memory (InitPrinter)",ERR_PRINTER);
  853.         }
  854.  
  855.         if ((*fpDeviceMode)(hFrParentWnd,hDriver,pDevMode,(LPSTR)PrinterName,(LPSTR)PrinterPort,NULL,(LPSTR)NULL,DM_COPY)<0) {
  856.            AbortFr("Error Initializing the printer(InitPrinter(w,2))",ERR_PRINTER);
  857.         }
  858.     }
  859.  
  860.     FreeLibrary(hDriver);                  // unload the driver from the memory 
  861.     
  862.     return TRUE;
  863. }
  864.