⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 print.c

📁 讲mfc的书
💻 C
📖 第 1 页 / 共 2 页
字号:
          * Check if device supports the BANDINFO escape.
          */

         nTemp = BANDINFO;
         bBandInfoDevice = Escape(hPrnDC, QUERYESCSUPPORT, sizeof(int), (LPSTR
                                  )&nTemp, NULL);

         /*
          * Do each band -- Call Escape() with NEXTBAND, then the
          * rect structure returned is the area where we are to
          * print in.  This loop exits when the rect area is empty.
          */
         while (Escape(hPrnDC, NEXTBAND, 0, NULL, (LPSTR)&rect) && !
                IsRectEmpty(&rect))
         {
            char szTmpBuf[100];

            /*
             * Do the BANDINFO, if needed.
             */

            if (bBandInfoDevice)
               Escape(hPrnDC, BANDINFO, sizeof(BANDINFOSTRUCT), (LPSTR)&
                      biBandInfo, (LPSTR)&biBandInfo);
            wsprintf(szTmpBuf, "Printing Band Number %d", ++nBandCount);
            SetDlgItemText(hDlgAbort, IDC_PERCENTAGE, (LPSTR)szTmpBuf);

            /*
             * Call PrintBand() to do actual output into band.
             *  Pass in our band-info flags to tell what sort
             *  of data to output into the band.  Note that on
             *  non-banding devices, we pass in the default bandinfo
             *  stuff set above (i.e. bText=TRUE, bGraphics=TRUE).
             */
            wErrorCode = PrintBand(hPrnDC, &rPrintRect, &rect,
                                   biBandInfo.bText, biBandInfo.bGraphics,
                                   lpDIBHdr, lpBits);
         }
      }
      else
      {

         /*
          * Print the whole page -- non-banding device.
          */
         rect = rPrintRect;
         SetDlgItemText(hDlgAbort, IDC_PERCENTAGE, (LPSTR)
                        "Sending bitmap to printer...");
         wErrorCode = PrintBand(hPrnDC, &rPrintRect, &rect, TRUE, TRUE,
                                lpDIBHdr, lpBits);

         /*
          * Non-banding devices need a NEWFRAME
          */
         if (Escape(hPrnDC, NEWFRAME, 0, NULL, NULL) < 0)
            return (ERR_NEWFRAME);
      }

      /*
       * End the print operation.  Only send the ENDDOC if
       *   we didn't abort or error.
       */
      if (!bAbort)
      {
         if (Escape(hPrnDC, ENDDOC, 0, NULL, NULL) < 0)
         {
            /*
             * We errored out on ENDDOC, but don't return here - we still
             * need to close the dialog box, free proc instances, etc.
             */
            wErrorCode = ERR_ENDDOC;
         }
         DestroyWindow(hDlgAbort);
      }


      /*
       * All done, clean up.
       */
      DeleteDC(hPrnDC);
   }
   else
      wErrorCode = ERR_GETDC;   // Couldn't get Printer DC!
   GlobalUnlock(hDib);
   return (wErrorCode);
}




// *******************************************************************
// Auxiliary Functions
//     -- Local to this module only
// *******************************************************************


/*********************************************************************
 *
 * CalculatePrintRect()
 *
 * Given fPrintOpt and a size of the DIB, return the area on the
 * printer where the image should go (in printer coordinates).  If
 * fPrintOpt is PW_SCALE, then lpPrintRect.left and .top should
 * contain WORDs which specify the scaling factor for the X and
 * Y directions, respecively.
 *
 * History:   
 * 
 *     Date      Author       Reason         
 *     9/15/91   Mark Bader   Created based on DIBVIEW
 *
 ********************************************************************/


void CalculatePrintRect(HDC hDC,             // HDC to printer DC
                        LPRECT lpPrintRect,  // Returned PrintRect
                        WORD fPrintOpt,      // Options
                        DWORD cxDIB,         // Size of DIB - x
                        DWORD cyDIB)         // Size of DIB - y
{
   int cxPage, cyPage, cxInch, cyInch;

   if (!hDC)
      return;

   /*
    * Get some info from printer driver
    */
   cxPage = GetDeviceCaps(hDC, HORZRES);     // Width of printr page - pixels
   cyPage = GetDeviceCaps(hDC, VERTRES);     // Height of printr page - pixels
   cxInch = GetDeviceCaps(hDC, LOGPIXELSX);  // Printer pixels per inch - X
   cyInch = GetDeviceCaps(hDC, LOGPIXELSY);  // Printer pixels per inch - Y
   switch (fPrintOpt)
      {

   /*
    * Best Fit case -- create a rectangle which preserves
    * the DIB's aspect ratio, and fills the page horizontally.
    *
    * The formula in the "->bottom" field below calculates the Y
    * position of the printed bitmap, based on the size of the
    * bitmap, the width of the page, and the relative size of
    * a printed pixel (cyInch / cxInch).
    */
   case PW_BESTFIT:
      lpPrintRect->top = 0;
      lpPrintRect->left = 0;
      lpPrintRect->bottom = (int)(((double)cyDIB * cxPage * cyInch) / ((double
                            )cxDIB * cxInch));
      lpPrintRect->right = cxPage;
      break;

   /*
    * Scaling option -- lpPrintRect's top/left contain
    * multipliers to multiply the DIB's height/width by.
    */

   case PW_SCALE:
   {
      int cxMult, cyMult;

      cxMult = lpPrintRect->left;
      cyMult = lpPrintRect->top;
      lpPrintRect->top = 0;
      lpPrintRect->left = 0;
      lpPrintRect->bottom = (int)(cyDIB * cyMult);
      lpPrintRect->right = (int)(cxDIB * cxMult);
   }
      break;

   /*
    * Stretch To Page case -- create a rectangle
    * which covers the entire printing page (note that this
    * is also the default).
    */
   case PW_STRETCHTOPAGE:
   default:
      lpPrintRect->top = 0;
      lpPrintRect->left = 0;
      lpPrintRect->bottom = cyPage;
      lpPrintRect->right = cxPage;
      break;
      }
}



/*********************************************************************
 *
 * PrintBand()
 *
 * This routine does ALL output to the printer.  It is called from
 * the PrintDIB() routine.  It is called for both banding and non-
 * banding printing devices.  lpRectClip contains the rectangular
 * area we should do our output into (i.e. we should clip our output
 * to this area).  The flags fDoText and fDoGraphics should be set
 * appropriately (if we want any text output to the rectangle, set
 * fDoText to true).  Normally these flags are returned on banding
 * devices which support the BANDINFO escape.
 *
 * History:   
 * 
 *     Date      Author       Reason         
 *     9/15/91   Mark Bader   Created based on DIBVIEW
 *
 ********************************************************************/


WORD PrintBand(HDC hDC,           // Handle to the Printer DC
               LPRECT lpRectOut,  // Rect where entire DIB is to go
               LPRECT lpRectClip, // Clippping rect where this portion goes
               BOOL fDoText,      // TRUE if this band is for text
               BOOL fDoGraphics,  // TRUE if this band is for graphics
               LPBITMAPINFOHEADER lpDIBHdr,   // Pointer to DIB header
               LPSTR lpDIBBits)   // Pointer to DIB bits
{
   RECT rect;                   // Temporary rectangle
   double dblXScaling,          // X and Y scaling factors
          dblYScaling;
   WORD wReturn = 0;            // Return code

   if (fDoGraphics)
   {
      dblXScaling = ((double)lpRectOut->right - lpRectOut->left) / (double)
                    lpDIBHdr->biWidth;
      dblYScaling = ((double)lpRectOut->bottom - lpRectOut->top) / (double)
                    lpDIBHdr->biHeight;
      /*
       * Now we set up a temporary rectangle -- this rectangle
       *  holds the coordinates on the paper where our bitmap
       *  WILL be output.  We can intersect this rectangle with
       *  the lpClipRect to see what we NEED to output to this
       *  band.  Then, we determine the coordinates in the DIB
       *  to which this rectangle corresponds (using dbl?Scaling).
       */
      IntersectRect(&rect, lpRectOut, lpRectClip);
      if (!IsRectEmpty(&rect))
      {
         RECT rectIn;

         rectIn.left = (int)((rect.left - lpRectOut->left) / dblXScaling + 0.5
                       );
         rectIn.top = (int)((rect.top - lpRectOut->top) / dblYScaling + 0.5);
         rectIn.right = (int)(rectIn.left + (rect.right - rect.left) /
                        dblXScaling + 0.5);
         rectIn.bottom = (int)(rectIn.top + (rect.bottom - rect.top) /
                         dblYScaling + 0.5);
         if (!StretchDIBits(hDC,                              // DestDC
                            rect.left,                        // DestX
                            rect.top,                         // DestY
                            rect.right - rect.left,           // DestWidth
                            rect.bottom - rect.top,           // DestHeight
                            rectIn.left,                      // SrcX
                            (int)(lpDIBHdr->biHeight) -       // SrcY
                            rectIn.top - (rectIn.bottom - rectIn.top),
                            rectIn.right - rectIn.left,       // SrcWidth
                            rectIn.bottom - rectIn.top,       // SrcHeight
                            lpDIBBits,                        // lpBits
                            (LPBITMAPINFO)lpDIBHdr,           // lpBitInfo
                            DIB_RGB_COLORS,                   // wUsage
                            SRCCOPY))                         // dwROP
            wReturn = ERR_STRETCHDIBITS; // StretchDIBits() failed!
      }
   }
   return wReturn;
}


/***********************************************************************
 *
 * GetPrinterDC()
 *
 * Return a DC to the currently selected printer.
 * Returns NULL on error.
 *
 * History:   
 * 
 *     Date      Author       Reason         
 *     9/15/91   Mark Bader   Created based on DIBVIEW
 *
 ***********************************************************************/


HDC GetPrinterDC(void)
{
   static char szPrinter[64];
   char *szDevice, *szDriver, *szOutput;

   GetProfileString("windows", "device", "", szPrinter, 64);
   if ((szDevice = strtok(szPrinter, ",")) && (szDriver = strtok(NULL, ", "))
       && (szOutput = strtok(NULL, ", ")))
   {
      lstrcpy((LPSTR)gszDevice, (LPSTR)szDevice);    // Copy to global variables
      lstrcpy((LPSTR)gszOutput, (LPSTR)szOutput);
      return CreateDC(szDriver, szDevice, szOutput, NULL);
   }
   return NULL;
}


/**********************************************************************
 * PrintAbortProc()
 *
 * Abort procedure - contains the message loop while printing is
 * in progress.  By using a PeekMessage() loop, multitasking
 * can occur during printing.
 *
 * History:   
 * 
 *     Date      Author       Reason         
 *     9/15/91   Mark Bader   Created         
 *
 **********************************************************************/


BOOL FAR PASCAL PrintAbortProc(HDC hDC, short code)
{
   MSG msg;

   while (!bAbort && PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
      if (!IsDialogMessage(hDlgAbort, &msg))
      {
         TranslateMessage(&msg);
         DispatchMessage(&msg);
      }
   return (!bAbort);
}

/***********************************************************************
 *
 * PrintAbortDlg()
 *
 *
 * This is the Dialog Procedure which will handle the "Now Printing"
 * dialog box.  When the user presses the "Cancel" button, the
 * global variable bAbort is set to TRUE, which causes the
 * PrintAbortProc to exit, which in turn causes the printing
 * operation to terminate.
 *
 * History:   
 * 
 *     Date      Author       Reason         
 *     9/15/91   Mark Bader   Created         
 *
 ***********************************************************************/


int FAR PASCAL PrintAbortDlg(HWND hWnd,   /* Handle to dialog box */ unsigned
                             msg, /* Message */ WORD wParam, LONG lParam)
{
   switch (msg)
      {
   case WM_INITDIALOG:
   {
      char szBuffer[100];

      /*
       * Fill in the text which specifies where this bitmap
       * is going ("on HP LaserJet on LPT1", for example)
       */

      wsprintf(szBuffer, "on %s on %s", (LPSTR)gszDevice, (LPSTR)gszOutput);
      SetDlgItemText(hWnd, IDC_PRINTTEXT2, (LPSTR)szBuffer);
      SetFocus(GetDlgItem(hWnd, IDCANCEL));
   }
      return TRUE;     // Return TRUE because we called SetFocus()

   case WM_COMMAND:
      bAbort = TRUE;
      DestroyWindow(hWnd);
      return TRUE;
      break;
      }
   return FALSE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -