home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic 4 Unleashed / Visual_Basic_4_Unleashed_SAMS_Publishing_1995.iso / repease / rep_rep1.c < prev    next >
C/C++ Source or Header  |  1995-02-23  |  35KB  |  948 lines

  1. /*==============================================================================
  2.    REP_REP1.C
  3.    Report Ease: Report Executer report painting and printing routines.
  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 "dos.h"
  42. #include "setjmp.h"
  43.  
  44. #include "rep.h"
  45.  
  46. #define  PREFIX extern
  47. #include "rep1.h"
  48.  
  49. #include "rep_dlg.h"
  50.  
  51. /****************************************************************************
  52.     RepWndProc:
  53.     This routine process the messages coming to the report output
  54.     window.
  55. ****************************************************************************/
  56.  
  57. long CALLBACK _export RepWndProc(HWND hWnd,unsigned message,WPARAM wParam,LPARAM lParam)
  58. {
  59.     int LastCompletePage,NewPage;
  60.     long CurPos,LastPos;
  61.     int  ScrollPos;
  62.  
  63.     //*********** translate accelerator ***********
  64.     if (FrTranslateAccelerator(hWnd,message,wParam,lParam)) return TRUE; // accelerator translated 
  65.     
  66.     if (ReportStage==IN_EXIT) LastCompletePage=PageCount;
  67.     else                      LastCompletePage=PageCount-1;
  68.  
  69.     switch (message) {
  70.         case WM_VSCROLL:                      // vertical scroll bar commands 
  71.             switch (SCROLL_MSG(wParam,lParam)) {
  72.                 case SB_LINEDOWN:             // scroll window one line down 
  73.                    RepDown(FrWinHeight/20);break;
  74.                 case SB_LINEUP:               // scroll window one line up 
  75.                    RepUp(FrWinHeight/20);break;
  76.                 case SB_PAGEDOWN:             // next page 
  77.                    RepDown(FrWinHeight);break;
  78.                 case SB_PAGEUP:               // previous page 
  79.                    RepUp(FrWinHeight);break;
  80.                 case SB_THUMBTRACK:           // absolute line position as the thump moves
  81.                    NewPage=(int)(((long)LastCompletePage*THUMB_POS(wParam,lParam))/(VER_SCROLL_MAX-VER_SCROLL_MIN));
  82.                    if (NewPage>=LastCompletePage) NewPage=LastCompletePage-1;
  83.                    if (NewPage!=ScrPage) {
  84.                       ScrPage=NewPage;
  85.                       hMetaFile=ReadMetaFilePage(ScrPage,ScrMetaFile,hMetaFile); // read next print page
  86.                       FrWinOrgY=0;                  // show the top of the page
  87.                       PaintRepScr();                // paint the new screen page
  88.                    }
  89.                    break;
  90.                 default:
  91.                    break;
  92.             }
  93.             break;
  94.         case WM_HSCROLL:                      // horizontal scroll bar commands 
  95.             switch (SCROLL_MSG(wParam,lParam)) {
  96.                 case SB_LINEDOWN:             // scroll window one column toward right 
  97.                    RepRight(FrWinWidth/10);break;
  98.                 case SB_LINEUP:               // scroll window one column toward left 
  99.                    RepLeft(FrWinWidth/10);break;
  100.                 case SB_PAGEDOWN:             // next horizontal page 
  101.                    RepRight(FrWinWidth);break;
  102.                 case SB_PAGEUP:               // previous horizontal page 
  103.                    RepLeft(FrWinWidth);break;
  104.                 case SB_THUMBTRACK:           // absolute line position as the thump moves
  105.                    FrWinOrgX=(int)(((long)PrintWidth*THUMB_POS(wParam,lParam))/(VER_SCROLL_MAX-VER_SCROLL_MIN));
  106.                    PaintRepScr();                // paint the new screen page
  107.                    break;
  108.  
  109.                 default:
  110.                    break;
  111.             }
  112.             break;
  113.         case WM_COMMAND:
  114.             switch (COMMAND_ID(wParam,lParam)) {
  115.                 case ID_JUMP:            // jump to a specify page
  116.                     PageJump();
  117.                     break;
  118.  
  119.                 case ID_PRINT:           // print range of processed pages
  120.                     SelectivePrint();    // print selected pages
  121.                     break;
  122.  
  123.                 case ID_EXIT:
  124.                     if (ReportStage==IN_EXIT) return RepCleanup();
  125.                     ReportStatus=REP_ABORT;
  126.                     break;
  127.  
  128.                 //*********************************************************
  129.                 // Navigation commands                                     
  130.                 //*********************************************************
  131.                 case ID_PGUP:                 // process page-up key 
  132.                     RepUp(FrWinHeight);break;
  133.                 case ID_PGDN:                 // process page-down key 
  134.                     RepDown(FrWinHeight);break;
  135.                 case ID_UP:                   // process the up arrow key 
  136.                     RepUp(FrWinHeight/20);break;
  137.                 case ID_DOWN:                 // process the down arrow key 
  138.                     RepDown(FrWinHeight/20);break;
  139.                 case ID_LEFT:                 // process the left arrow 
  140.                     RepLeft(FrWinWidth/10);break;
  141.                 case ID_RIGHT:                // process the right arrow 
  142.                     RepRight(FrWinWidth/10);break;     
  143.  
  144.                 default:
  145.                     return (DefWindowProc(hWnd, message, wParam, lParam));
  146.  
  147.             }
  148.             break;
  149.  
  150.         case WM_CLOSE:
  151.             if      (ReportStage==IN_EXIT) return RepCleanup();
  152.             else if (ReportStage!=IN_TOTALS) ReportStatus=REP_ABORT;
  153.             break;
  154.  
  155.         case WM_PAINT:
  156.             RepaintRepScr();
  157.             break;
  158.  
  159.         default:
  160.             return (DefWindowProc(hWnd, message, wParam, lParam));
  161.     }
  162.     
  163.     RepInitMenu(hFrMenu);                    // update the menu display 
  164.  
  165.     //******************* set vertical and horizontal scroll bars************
  166.     if (LastCompletePage>0) {
  167.        
  168.        //******************* set vertical scroll bar ***********************
  169.        CurPos=(long)ScrPage*(long)PageHeight+FrWinOrgY;
  170.        LastPos=(long)LastCompletePage*(long)PageHeight;
  171.        ScrollPos=VER_SCROLL_MIN+(int)(CurPos*(VER_SCROLL_MAX-VER_SCROLL_MIN)/LastPos);
  172.        if (ScrollPos!=VerScrollPos) {        /* redraw */
  173.           VerScrollPos=ScrollPos;
  174.           SetScrollPos(hFrWnd,SB_VERT,VerScrollPos,TRUE);
  175.        }
  176.     
  177.        //******************* set horizontal scroll bar ***********************
  178.        if (PrintWidth>FrWinWidth) {
  179.           ScrollPos=HOR_SCROLL_MIN+(int)((long)FrWinOrgX*(HOR_SCROLL_MAX-HOR_SCROLL_MIN)/PrintWidth);
  180.           if (ScrollPos>HOR_SCROLL_MAX) ScrollPos=HOR_SCROLL_MAX;
  181.           if (ScrollPos!=HorScrollPos) { /* redraw */
  182.              HorScrollPos=ScrollPos;
  183.              SetScrollPos(hFrWnd,SB_HORZ,HorScrollPos,TRUE);
  184.           }
  185.        }
  186.     }
  187.  
  188.     return (LRESULT)(NULL);
  189. }
  190.  
  191. /******************************************************************************
  192.     RepInitMenu:
  193.     Initialzes and redraws the report menu bar
  194. ******************************************************************************/
  195. RepInitMenu(HMENU hMenu)
  196. {
  197.     int LastCompletePage;
  198.  
  199.     if (ReportStage==IN_EXIT) LastCompletePage=PageCount;
  200.     else                      LastCompletePage=PageCount-1;
  201.  
  202.     EnableMenuItem(hMenu,ID_JUMP   ,LastCompletePage>1 ? MF_ENABLED : MF_GRAYED);
  203.     EnableMenuItem(hMenu,ID_PRINT  ,LastCompletePage>0 && !printing ? MF_ENABLED : MF_GRAYED);
  204.     
  205.     DrawMenuBar(hFrWnd);                  // redraw the menu bar 
  206.  
  207.     return TRUE;
  208. }
  209.  
  210. /******************************************************************************
  211.     RepaintRepScr:
  212.     This routine is called when a paint message is received by the RepWndProc
  213.     function.
  214.     This routine repaint the entire client area.
  215. *******************************************************************************/
  216. RepaintRepScr()
  217. {
  218.     PAINTSTRUCT PaintData;
  219.  
  220.     BeginPaint(hFrWnd,&PaintData); 
  221.     EndPaint(hFrWnd,&PaintData); 
  222.  
  223.     if (WindowBeingCreated) return TRUE;
  224.  
  225.     GetWinDimension();      // get window dimensions 
  226.  
  227.     PaintRepScr();
  228.     
  229.     return TRUE;
  230. }
  231.  
  232. /****************************************************************************
  233.     PaintRepScr:
  234.     Paint the report screen window.
  235. ****************************************************************************/
  236. PaintRepScr()
  237. {
  238.     RECT rect;
  239.     HRGN rgn;
  240.  
  241.     if (!PaintEnabled) return TRUE;    // painting disabled 
  242.     
  243.     FrSetViewWindow();                 // set the window origin
  244.     
  245.     ShowScrRepStatus();                // print screen reporting status
  246.  
  247.     // Clear the remaining area
  248.     rect.left=FrWinOrgX;               // build the drawing area rectangle
  249.     rect.right=rect.left+FrWinWidth;
  250.     rect.top=FrWinOrgY;
  251.     rect.bottom=FrWinOrgY+FrWinHeight;
  252.     FillRect(hMemDC,&rect,hBackBrush);
  253.  
  254.     // select clipping region to include only the drawing area
  255.     rgn=CreateRectRgn(FrRect.left,FrRect.top,FrRect.right,FrRect.bottom);
  256.     SelectClipRgn(hMemDC,rgn);
  257.     DeleteObject(rgn);                   // delete the temporary region
  258.  
  259.     // Play the current metafile
  260.     if (hMetaFile) PlayMetaFile(hMemDC,hMetaFile);
  261.  
  262.     // print the page break line
  263.     if (ReportStage==IN_EXIT && ScrPage==PageCount-1) 
  264.          SelectObject(hMemDC,hSelectionPen);          // mark end of report
  265.     else SelectObject(hMemDC,hFocusPen);              // mark end of page
  266.     MoveToEx(hMemDC,0,PageHeight,NULL);
  267.     LineTo(hMemDC,PrintWidth,PageHeight);
  268.  
  269.     // Copy the memory bitmap to the device
  270.     BitBlt(hFrDC,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,hMemDC,rect.left,rect.top,SRCCOPY);
  271.     
  272.     ValidateRect(hFrWnd,NULL);           // remove any pending paint messages
  273.     SelectClipRgn(hMemDC,NULL);
  274.     
  275.     return TRUE;
  276. }
  277.  
  278. /******************************************************************************
  279.     ShowScrRepStatus:
  280.     Display the progress of the screen reporting
  281. ******************************************************************************/
  282. ShowScrRepStatus()
  283. {
  284.     RECT rect;
  285.     char string[100];
  286.     int  LabelLen;
  287.  
  288.     // clear the status area
  289.     rect.left=FrWinOrgX;              // build the status area rectangle
  290.     rect.right=rect.left+FrWinWidth;
  291.     rect.top=FrWinOrgY-FrWinRect.top;
  292.     rect.bottom=rect.top+(InputRect.bottom-InputRect.top);
  293.     FillRect(hMemDC,&rect,hInputAreaBrush);
  294.  
  295.     // display status info
  296.     SetFont(hMemDC,DEFAULT_CFMT);
  297.     SetTextColor(hMemDC,DrawColor);
  298.     SetBkMode(hMemDC,TRANSPARENT);
  299.  
  300.     if (ReportStage==IN_EXIT) {       // report completely processed
  301.        // print page count
  302.        wsprintf(string,"   Last Page: %d",PageCount);
  303.        ExtTextOut(hMemDC,rect.left,rect.top,ETO_CLIPPED,&rect,string,lstrlen(string),NULL);
  304.        // print record count
  305.        wsprintf(string,"   Record Count: %d",RecCount);
  306.        ExtTextOut(hMemDC,rect.left,rect.top+CharHeight,ETO_CLIPPED,&rect,string,lstrlen(string),NULL);
  307.     }
  308.     else {                            // records being processed
  309.        // print page count
  310.        wsprintf(string,"   Processing Page# %d",PageCount);
  311.        ExtTextOut(hMemDC,rect.left,rect.top,ETO_CLIPPED,&rect,string,lstrlen(string),NULL);
  312.        // print record count
  313.        wsprintf(string,"   Processing Record#: %d",RecCount);
  314.        ExtTextOut(hMemDC,rect.left,rect.top+CharHeight,ETO_CLIPPED,&rect,string,lstrlen(string),NULL);
  315.     }
  316.  
  317.     // print current screen page number
  318.     if (ReportStage==IN_EXIT || PageCount>1) {
  319.        wsprintf(string,"Current Page: %d   ",ScrPage+1);
  320.        LabelLen=GetLabelLen(string,DEFAULT_CFMT);
  321.        ExtTextOut(hMemDC,rect.right-LabelLen,rect.top+CharHeight,ETO_CLIPPED,&rect,string,lstrlen(string),NULL);
  322.     }
  323.  
  324.     // Copy the memory bitmap to the device
  325.     BitBlt(hFrDC,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,hMemDC,rect.left,rect.top,SRCCOPY);
  326.  
  327.     return TRUE;
  328. }
  329.  
  330. /******************************************************************************
  331.     RepUp:
  332.     Move the window upward.
  333. ******************************************************************************/
  334. RepUp(int height)
  335. {
  336.     int LastCompletePage;
  337.  
  338.     if (ReportStage==IN_EXIT) LastCompletePage=PageCount;
  339.     else                      LastCompletePage=PageCount-1;
  340.     if (LastCompletePage==0) return TRUE;
  341.  
  342.     if (FrWinOrgY>0) {
  343.        FrWinOrgY-=height;
  344.        if (FrWinOrgY<0) FrWinOrgY=0;
  345.        PaintRepScr();                // paint new screen page
  346.     }
  347.     else if (ScrPage>0) {
  348.        ScrPage--;
  349.        hMetaFile=ReadMetaFilePage(ScrPage,ScrMetaFile,hMetaFile); // read next print page
  350.        FrWinOrgY=PageHeight-(height-CharHeight); // show the bottom of the page
  351.        PaintRepScr();                // paint the new screen page
  352.     }
  353.  
  354.     return TRUE;
  355. }
  356.  
  357. /******************************************************************************
  358.     RepDown:
  359.     Move the window downward
  360. ******************************************************************************/
  361. RepDown(int height)
  362. {
  363.     int LastCompletePage;
  364.  
  365.     if (ReportStage==IN_EXIT) LastCompletePage=PageCount;
  366.     else                      LastCompletePage=PageCount-1;
  367.     if (LastCompletePage==0) return TRUE;
  368.  
  369.     if (FrWinOrgY+height<PageHeight) {
  370.        FrWinOrgY+=height;
  371.        PaintRepScr();                // paint new screen page
  372.     }
  373.     else if ((ScrPage+1)<LastCompletePage) {
  374.        ScrPage++;
  375.        hMetaFile=ReadMetaFilePage(ScrPage,ScrMetaFile,hMetaFile); // read next print page
  376.        FrWinOrgY=0;                  // show the top of the page
  377.        PaintRepScr();                // paint the new screen page
  378.     }
  379.  
  380.     return TRUE;
  381. }
  382.  
  383. /******************************************************************************
  384.     RepLeft:
  385.     Move the window leftward.
  386. ******************************************************************************/
  387. RepLeft(int width)
  388. {
  389.     int LastCompletePage;
  390.  
  391.     if (ReportStage==IN_EXIT) LastCompletePage=PageCount;
  392.     else                      LastCompletePage=PageCount-1;
  393.     if (LastCompletePage==0) return TRUE;
  394.  
  395.     if (FrWinOrgX>0) {
  396.        FrWinOrgX-=width;
  397.        if (FrWinOrgX<0) FrWinOrgX=0;
  398.        PaintRepScr();                // paint new screen page
  399.     }
  400.  
  401.     return TRUE;
  402. }
  403.  
  404. /******************************************************************************
  405.     RepRight:
  406.     Move the window rightward.
  407. ******************************************************************************/
  408. RepRight(int width)
  409. {
  410.     int LastCompletePage;
  411.  
  412.     if (ReportStage==IN_EXIT) LastCompletePage=PageCount;
  413.     else                      LastCompletePage=PageCount-1;
  414.     if (LastCompletePage==0) return TRUE;
  415.     
  416.     if (FrWinOrgX<PrintWidth) {
  417.        FrWinOrgX+=width;
  418.        PaintRepScr();                // paint new screen page
  419.     }
  420.     
  421.     return TRUE;
  422. }
  423.  
  424. /******************************************************************************
  425.     ProcessUserCommands:
  426.     This routine is called from the RepRec function after processing a record.
  427.     This routine retrieve the user commands to scroll
  428.     the output window or carryout menu functions.  This function returns
  429.     when all messages are processed.
  430. *******************************************************************************/
  431. ProcessUserCommands()
  432. {
  433.     MSG msg;
  434.  
  435.     //*** process messages but do not yield ***
  436.     while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
  437.         if (!TranslateAccelerator(msg.hwnd,hFrAccTable,&msg)) {
  438.             TranslateMessage(&msg);
  439.             DispatchMessage(&msg);
  440.         }
  441.         if (ReportStatus==REP_ABORT) break;
  442.     }
  443.     
  444.     // check if user wishes to abort the processing
  445.     if (ReportStatus==REP_ABORT && ReportStage==IN_RECORDS) {
  446.        ErrorCode=ERR_SUSPEND;
  447.        // return the error code
  448.        #if defined (WIN32)
  449.           longjmp(FrAbort,-1);
  450.        #else
  451.           Throw((LPCATCHBUF) &FrAbort,-1);
  452.        #endif
  453.     }
  454.  
  455.     return TRUE;
  456. }
  457.  
  458. /******************************************************************************
  459.     PageJump:
  460.     Position at the requested screen page.
  461. *******************************************************************************/     
  462. PageJump()
  463. {
  464.     int page;
  465.     
  466.     page=CallDialogBox("JumpParam",JumpParam,0);
  467.     
  468.     if (page==0) return TRUE;        // cancelled by the user
  469.  
  470.     if (page-1!=ScrPage) {           // jump 
  471.        ScrPage=page-1;               // screen page number to jump to
  472.        hMetaFile=ReadMetaFilePage(ScrPage,ScrMetaFile,hMetaFile);  // read next print page
  473.        FrWinOrgY=0;                  // show the top of the page
  474.        PaintRepScr();                // paint the new screen page
  475.     }
  476.     return TRUE;
  477. }
  478.  
  479. /******************************************************************************
  480.     SelectivePrint:
  481.     Print selected pages from the screen
  482. *******************************************************************************/     
  483. SelectivePrint()
  484. {
  485.     HDC hPrtDC;
  486.     char line[LINE_WIDTH+1];
  487.     FARPROC lpProc;
  488.     int i,SaveReportStatus,SavePageCount,SaveResX,SaveResY;
  489.     HMETAFILE hMetaFile=NULL;
  490.  
  491.     if (!CallDialogBox("PrintParam",PrintParam,0)) return TRUE;
  492.     
  493.     FirstPrintPage--;   // convert to 0 base
  494.     LastPrintPage--;
  495.  
  496.     // open the printer
  497.     strcpy(line,PrinterDriver);
  498.     line[strlen(line)-4]=0; // strip the .drv extension 
  499.     if (NULL==(hPrtDC=CreateDC(line,PrinterName,PrinterPort,pDevMode))) {
  500.         MessageBox(hFrWnd,"Can not initialize printing",NULL,MB_OK);
  501.         return FALSE;
  502.     }
  503.  
  504.     // preprare for printing
  505.     lpProc = MakeProcInstance((FARPROC)ScrPrintProc, hFrInst);
  506.     lpAbortDlg = MakeProcInstance((FARPROC)ScrPrintAbortParam, hFrInst);
  507.     Escape(hPrtDC,SETABORTPROC,0,(LPSTR)(long)lpProc,NULL);  // activate the abort routine 
  508.  
  509.     if (Escape(hPrtDC,STARTDOC,strlen(FormHdr.name),FormHdr.name,NULL)<0) {
  510.         MessageBox(hFrWnd,"Unable to Start the Print Job",NULL,MB_OK);
  511.         return FALSE;
  512.     }
  513.     
  514.     hAbortWnd=CreateDialog(hFrInst,"ScrPrintAbortParam",hFrWnd,(DLGPROC)lpAbortDlg);
  515.     ShowWindow(hAbortWnd,SW_NORMAL);
  516.     
  517.     UpdateWindow(hAbortWnd);
  518.     if (hFrWnd) EnableWindow(hFrWnd,FALSE); // disable the main window 
  519.  
  520.     // set the printer status
  521.     SaveReportStatus=ReportStatus;          // save the current report status
  522.     SavePageCount=PageCount;                // save the current page count
  523.  
  524.     SaveResX=ResX;                          // save the screen resolution
  525.     SaveResY=ResY;                          
  526.     ResX=GetDeviceCaps(hPrtDC,LOGPIXELSX);  // number of pixels per inch of X direction 
  527.     ResY=GetDeviceCaps(hPrtDC,LOGPIXELSY);  // number of pixels per inch of Y direction 
  528.  
  529.     PageCount=1;
  530.  
  531.     // print each page
  532.     for (i=FirstPrintPage;i<=LastPrintPage;i++) {
  533.         SetLogicalUnit(hPrtDC);                              // set the logical units
  534.         
  535.         hMetaFile=ReadMetaFilePage(i,PrtMetaFile,hMetaFile); // read next print page
  536.         if (hMetaFile) PlayMetaFile(hPrtDC,hMetaFile);       // play the metafile page
  537.         Escape(hPrtDC,NEWFRAME,0,0L,0L);                     // advance to the next page 
  538.         if (ReportStatus==REP_ABORT) break;
  539.         PageCount++;
  540.     }
  541.  
  542.     //reset the print status
  543.     ResX=SaveResX;                          // restore the screen resolution
  544.     ResY=SaveResY;                          
  545.  
  546.     ReportStatus=SaveReportStatus;           // restore the current report status
  547.     PageCount=SavePageCount;                 // restore the current page count
  548.  
  549.     // end the printing
  550.     Escape(hPrtDC,ENDDOC,0,0L,0L);           // end of print job 
  551.     if (hFrWnd) EnableWindow(hFrWnd,TRUE);  // activate the parent window 
  552.     if (hMetaFile) DeleteMetaFile(hMetaFile);
  553.     DestroyWindow(hAbortWnd);               // destroy the abort window 
  554.     FreeProcInstance(lpProc);               // free the process instances 
  555.     FreeProcInstance(lpAbortDlg);
  556.  
  557.     DeleteDC(hPrtDC);
  558.     hPrtDC=NULL;
  559.  
  560.     return TRUE;
  561. }
  562.  
  563. /******************************************************************************
  564.     AdvancePage:
  565.     Advance to the next page.
  566. *******************************************************************************/     
  567. AdvancePage(int CurSec)
  568. {
  569.  
  570.     int  i,sec;
  571.     int fld;
  572.     BOOL calculated=FALSE;
  573.     
  574.     if (ReportStatus==REP_ABORT) return TRUE;
  575.  
  576.     if (PageAdvanced || AdvancingPage) return FALSE;  // page already advanced 
  577.  
  578.     AdvancingPage=TRUE;                               // advancing to next page 
  579.  
  580.     CurHeight=PrintHeight;
  581.  
  582.     PrintSection(SEC_FTR_PAGE);                       // print page footer 
  583.  
  584.     if (UseScreen) {
  585.        TransferMetaFile();                            // transfer the current page to the meta file
  586.     }
  587.     else {
  588.        Escape(hFrDC,NEWFRAME,0,0L,0L);                // advance to the next page 
  589.        PrintProc(hFrDC,0);                            // show the last status
  590.  
  591.        if (ReportStatus==REP_ABORT) {
  592.           if (ReportStage==IN_EXIT) return FALSE;
  593.           else {
  594.              ErrorCode=ERR_SUSPEND;
  595.              // return error code
  596.              #if defined (WIN32)
  597.                 longjmp(FrAbort,-1);
  598.              #else
  599.                 Throw((LPCATCHBUF) &FrAbort,-1);
  600.              #endif
  601.           }
  602.        }
  603.        StartPage(hFrDC);
  604.        SetLogicalUnit(hFrDC);                         // set the logical units
  605.     }
  606.  
  607.     PageCount++;
  608.     CurHeight=TopMargin;
  609.  
  610.     //******************** zero the page totals **************
  611.     for(fld=0;fld<TotalFields;fld++) {
  612.        if (field[fld].InUse && field[fld].section==SEC_FTR_PAGE) {
  613.            if (!(FLAG_RETAIN&field[fld].flags)) {
  614.               field[fld].HoldNum=0;
  615.               field[fld].HoldDbl=0;
  616.               field[fld].count=0;
  617.               if (field[fld].SumType==SUM_MAX || field[fld].SumType==SUM_MIN) {
  618.                  field[fld].HoldNum=UserField[fld].NumData;
  619.                  field[fld].HoldDbl=UserField[fld].DblData;
  620.               }
  621.            }
  622.        }
  623.        //** update the system page count fields **
  624.        if (field[fld].source==SRC_SYS && field[fld].SysIdx==SYS_PAGE) field[fld].NumData=PageCount;
  625.     } 
  626.  
  627.     //*************** Initialize the next page ***************
  628.     if (!TrialMode) {
  629.        PrintSection(SEC_HDR_PAGE);                       // print page headers 
  630.  
  631.        if (CurSec>=SEC_DETAIL1 && CurSec<=SEC_DETAIL9) {
  632.           for (i=0;i<TotalBreakFields;i++) {                // print group headers if needed 
  633.              sec=BreakField[i].section;
  634.              if (SFLAG_REPRINT&(section[sec].flags)) {
  635.                 if (!calculated) {
  636.                     CalculateFields(0,SEC_HDR_LVL9);        // calculate all fields for all section 
  637.                     calculated=TRUE;
  638.                 }
  639.                 PrintSection(sec);
  640.              }
  641.           }
  642.        }
  643.     }
  644.  
  645.     AdvancingPage=FALSE;                 // page advance complete 
  646.     PageAdvanced=TRUE;
  647.  
  648.     // show screen pages and update menu
  649.     if (UseScreen) {
  650.       if (PageCount==2) {
  651.          RepInitMenu(hFrMenu);             // enable screen printing
  652.          PaintRepScr();                    // show the first screen
  653.       }
  654.       else if (PageCount==3) RepInitMenu(hFrMenu); // enable page jump
  655.     }
  656.  
  657.  
  658.     return TRUE;
  659. }
  660.  
  661. /*****************************************************************************
  662.     CreateNewMetaFiles:
  663.     Create permanent and temporary meta files.
  664. *****************************************************************************/
  665. CreateNewMetaFiles()
  666. {
  667.     char   prefix[13];
  668.  
  669.     // build directory path
  670.     if (lstrlen(RepArg.SwapDir)==0)  RepGetCurDir(RepArg.SwapDir);
  671.     
  672.     if (lstrlen(RepArg.SwapDir)!=0) {
  673.        if (RepArg.SwapDir[lstrlen(RepArg.SwapDir)-1]!='\\') lstrcat(RepArg.SwapDir,"\\");
  674.     }
  675.  
  676.     // build file prefix - make unique by using the current system time
  677.     lstrcpy(prefix,SystemTime);
  678.     prefix[2]=prefix[5]='R';   // replace ':' in time by a letter
  679.  
  680.     // create permanent metafile
  681.     lstrcpy(MetaFile,RepArg.SwapDir);
  682.     lstrcat(MetaFile,prefix);
  683.     lstrcat(MetaFile,".MF");
  684.  
  685.     // create temporary metafile name
  686.     lstrcpy(TempMetaFile,RepArg.SwapDir);
  687.     lstrcat(TempMetaFile,prefix);
  688.     lstrcat(TempMetaFile,".MFT");
  689.  
  690.     // create screen metafile name
  691.     lstrcpy(ScrMetaFile,RepArg.SwapDir);
  692.     lstrcat(ScrMetaFile,prefix);
  693.     lstrcat(ScrMetaFile,".MFS");
  694.  
  695.     // create selective print metafile name
  696.     lstrcpy(PrtMetaFile,RepArg.SwapDir);
  697.     lstrcat(PrtMetaFile,prefix);
  698.     lstrcat(PrtMetaFile,".MFP");
  699.  
  700.     return TRUE;
  701. }
  702.  
  703. /*****************************************************************************
  704.     TransferMetaFile:
  705.     Transfer the current page meta file to the permanent file.
  706. *****************************************************************************/
  707. TransferMetaFile()
  708. {
  709.     HMETAFILE hMeta1,hMeta2;
  710.     long FileSize;
  711.  
  712.     if (PageCount==1) {
  713.         CreateNewMetaFiles();  // Create permanent and temporary metafiles
  714.         PageLoc[0]=0;
  715.     }
  716.  
  717.     if (NULL==(hMeta1=CloseMetaFile(hMetaDC))) AbortFr("Error Creating Meta File(TransferMetaFile)",ERR_NO_FILE);
  718.     
  719.     unlink(TempMetaFile);                    // delete any old temporary disk meta file
  720.     if (NULL==(hMeta2=CopyMetaFile(hMeta1,TempMetaFile))) AbortFr("Error Copying Meta File(TransferMetaFile)",ERR_NO_FILE);
  721.     DeleteMetaFile(hMeta2);                  // delete temporary memory meta files
  722.  
  723.     // transfer temporary disk meta file to the permanent disk meta file
  724.     FileSize=GetFileLength(TempMetaFile);
  725.     CopyFileData(TempMetaFile,0,MetaFile,PageLoc[PageCount-1],FileSize);
  726.     
  727.     // record the page location data
  728.     PageLoc[PageCount]=PageLoc[PageCount-1]+FileSize;
  729.  
  730.     // create new memory meta file device context
  731.     if (NULL==(hMetaDC=CreateMetaFile(NULL))) AbortFr("Error creating metafile(TransferMetaFile)",ERR_NO_FILE);
  732.  
  733.     // assign the first screen meta file
  734.     if (PageCount==1 && !hMetaFile) hMetaFile=hMeta1;
  735.     else                            DeleteMetaFile(hMeta1);
  736.  
  737.     return TRUE;
  738. }
  739.  
  740. /*****************************************************************************
  741.     ReadMetaFilePage:
  742.     Read one page from the permanent disk file to the new meta file and
  743.     returns a meta file handle.
  744. *****************************************************************************/
  745. HMETAFILE ReadMetaFilePage(int page,LPSTR NewMetaFile,HMETAFILE hMetaFile)
  746. {
  747.     HMETAFILE hNewMeta;
  748.  
  749.     // delete old memory meta file
  750.     if (hMetaFile) {
  751.        DeleteMetaFile(hMetaFile);
  752.        hMetaFile=0;
  753.     }
  754.  
  755.     unlink(NewMetaFile);                    // delete any existing temp file
  756.     CopyFileData(MetaFile,PageLoc[page],NewMetaFile,0,PageLoc[page+1]-PageLoc[page]);
  757.  
  758.     // get a meta file from the temporary disk file
  759.     if (NULL==(hMetaFile=GetMetaFile(NewMetaFile))) AbortFr("Error getting the disk meta file(ReadMetaFilePage)",ERR_NO_FILE);
  760.  
  761.     // create the memory metafile
  762.     if (NULL==(hNewMeta=CopyMetaFile(hMetaFile,NULL))) return hMetaFile; // forced to used slow disk meta file
  763.     else {                                     // use fast memory meta file
  764.        DeleteMetaFile(hMetaFile);              // delete the disk meta file
  765.        return hNewMeta;
  766.     }
  767. }
  768.  
  769. /*****************************************************************************
  770.     PrintTrial:
  771.     This routine prints the trial records.  Trials records can be used
  772.     to adjust the form before printing the data records.
  773. *****************************************************************************/
  774. PrintTrial()
  775. {
  776.     int i,j;
  777.  
  778.     if (IDNO==MessageBox(hFrWnd,"Print a Trial Record Now?","Trial Print",MB_YESNO)) return TRUE;
  779.     
  780.     PRINT_ONE_RECORD:
  781.     TrialMode=TRUE;
  782.  
  783.     for (i=0;i<MAX_SECTIONS;i++) {
  784.         if (i==SEC_DETAIL1 && section[i].columns>1) {
  785.             for (j=0;j<section[i].columns;j++) PrintSection(i);
  786.         }
  787.         else PrintSection(i);
  788.     }
  789.     
  790.     //***** Advance page if other than detail section used *****************
  791.     for (i=0;i<MAX_SECTIONS;i++) {
  792.        if ((i<SEC_DETAIL1 || i>SEC_DETAIL9) && section[i].InUse) {
  793.           AdvancePage(i);
  794.           PageCount=1;
  795.           break;
  796.        }
  797.     }
  798.  
  799.     TrialMode=FALSE;
  800.  
  801.     if (IDYES==MessageBox(hFrWnd,"Print another Trial Record?","Trial Record",MB_YESNO)) goto PRINT_ONE_RECORD;
  802.  
  803.     return TRUE;
  804. }
  805.  
  806. /******************************************************************************
  807.     PrintProc:
  808.     Dispatches the messages to the PrintAbort routine, and checks
  809.     if the user cancelled the printing
  810. ******************************************************************************/
  811. int CALLBACK _export PrintProc(HDC hPr, int code)
  812. {
  813.     MSG msg;
  814.     char string[20];
  815.     int count;
  816.  
  817.     //**************** show the page and record counters ******
  818.     count=GetDlgItemInt(hAbortDlg,IDC_CUR_REC,NULL,FALSE);
  819.     if (count!=RecCount) {
  820.        itoa(PageCount,string,10);
  821.        SetDlgItemText(hAbortDlg,IDC_CUR_PAGE,string);
  822.  
  823.        ltoa(RecCount,string,10);
  824.        SetDlgItemText(hAbortDlg,IDC_CUR_REC,string);
  825.     }
  826.  
  827.  
  828.     //**************** yield to other processes *****************
  829.     while (ReportStatus!=REP_ABORT && hPr==hFrDC && PeekMessage(&msg,NULL,0,0,TRUE)) {  // process message until abort 
  830.        if (!IsDialogMessage(hAbortWnd,&msg)) {  // dispatch modeless dialog messages 
  831.            TranslateMessage(&msg);              // translate/dispatch other window messages 
  832.            DispatchMessage(&msg);
  833.        }
  834.        if (code) ReportStatus=REP_ABORT;
  835.     }
  836.     
  837.  
  838.     return TRUE;
  839. }
  840.  
  841. /******************************************************************************
  842.     ScrPrintProc:
  843.     Dispatches the messages to the ScrPrintAbort routine, and checks
  844.     if the user cancelled the printing
  845. ******************************************************************************/
  846. int CALLBACK _export ScrPrintProc(HDC hPr, int code)
  847. {
  848.     MSG msg;
  849.     char string[20];
  850.     int count;
  851.  
  852.     //**************** show the page counter ******
  853.     count=GetDlgItemInt(hAbortDlg,IDC_CUR_PAGE,NULL,FALSE);
  854.     if (count!=PageCount) {
  855.        itoa(PageCount,string,10);
  856.        SetDlgItemText(hAbortDlg,IDC_CUR_PAGE,string);
  857.     }
  858.  
  859.     //**************** yield to other processes *****************
  860.     while (ReportStatus!=REP_ABORT && PeekMessage(&msg,0,0,0,TRUE)) {  // process message until abort 
  861.        if (!IsDialogMessage(hAbortWnd,&msg)) {  // dispatch modeless dialog messages 
  862.            TranslateMessage(&msg);              // translate/dispatch other window messages 
  863.            DispatchMessage(&msg);
  864.        }
  865.        if (code) ReportStatus=REP_ABORT;
  866.     }
  867.     
  868.  
  869.     return TRUE;
  870. }
  871.  
  872. /******************************************************************************
  873.    RepGetCurDir:
  874.    get full path name of the current working directory 
  875. *******************************************************************************/
  876. LPSTR RepGetCurDir(LPSTR CurDir)
  877. {
  878.     #if defined (WIN32) 
  879.        GetCurrentDirectory(LINE_WIDTH/2,CurDir);
  880.     #else
  881.        char CurDrv[4],TempDir[64];
  882.        union REGS reg;
  883.        struct SREGS sreg;
  884.  
  885.        /*********** get default drive ***********/
  886.        segread(&sreg);
  887.        reg.h.ah=0x19;
  888.        int86x(0x21,®,®,&sreg);
  889.        CurDrv[0]=reg.h.al+'A';
  890.        CurDrv[1]=0;
  891.        lstrcat(CurDrv,":\\");
  892.  
  893.        /* get current sub directory ******/
  894.        reg.h.ah=0x47;
  895.        reg.h.dl=0;
  896.        sreg.ds=(WORD)(((unsigned long)(LPSTR)TempDir)>>16);
  897.        sreg.es=sreg.ds;                   /* must provide a valid selector in ES */
  898.        reg.x.si=(WORD)((((unsigned long)(LPSTR)TempDir)<<16)>>16);
  899.        
  900.        int86x(0x21,®,®,&sreg);
  901.        
  902.        lstrcpy(CurDir,CurDrv);
  903.        lstrcat(CurDir,TempDir);
  904.     #endif
  905.  
  906.     return CurDir;
  907. }
  908.  
  909. /******************************************************************************
  910.    CopyFileData:
  911.    Copy specified number if bytes from the source file to the destination file.
  912. *******************************************************************************/
  913. int CopyFileData(LPSTR SrcFile, long SrcPos, LPSTR DstFile, long DstPos, long count)
  914. {
  915.     HFILE iFile,oFile;
  916.     OFSTRUCT OpenBuf;
  917.     int bytes;
  918.  
  919.     // open the source file
  920.     if ((iFile=OpenFile(SrcFile,&OpenBuf,OF_READ))==HFILE_ERROR) AbortFr("Error opening the input file(CopyFileData)",ERR_NO_FILE);
  921.     if (_llseek(iFile,SrcPos,0)==HFILE_ERROR) AbortFr("Error seeking the input file(CopyFileData)",ERR_NO_FILE);
  922.  
  923.     // open the destination file
  924.     if (OpenFile(DstFile,&OpenBuf,OF_EXIST)!=HFILE_ERROR) {
  925.          if ((oFile=OpenFile(DstFile,&OpenBuf,OF_READWRITE))==HFILE_ERROR) AbortFr("Error opening the output file(CopyFileData)",ERR_NO_FILE);
  926.          if (_llseek(oFile,DstPos,0)==HFILE_ERROR) AbortFr("Error seeking the output file(CopyFileData)",ERR_NO_FILE);
  927.     }
  928.     else if ((oFile=OpenFile(DstFile,&OpenBuf,OF_WRITE|OF_CREATE))==HFILE_ERROR) AbortFr("Error opening the output file(CopyFileData A)",ERR_NO_FILE);
  929.  
  930.     // copy the file data
  931.     while(count>0) {
  932.       bytes=BUF_SIZE;                         //transfer size
  933.       if ((long)bytes>count) bytes=(int)count;
  934.  
  935.       if (_lread(iFile,FileBuf,bytes)==(UINT)HFILE_ERROR) AbortFr("Error reading the input file(CopyFileData)",ERR_NO_FILE);    // read
  936.       if (_lwrite(oFile,FileBuf,bytes)==(UINT)HFILE_ERROR) AbortFr("Error writing the output file(CopyFileData)",ERR_NO_FILE); // write
  937.     
  938.       count-=bytes;
  939.     }
  940.  
  941.  
  942.     // close the files
  943.     _lclose(iFile);
  944.     _lclose(oFile);
  945.  
  946.     return TRUE;
  947. }
  948.