CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 2 of 2
  1. #1
    Join Date
    May 2002
    Location
    Germany
    Posts
    451

    Angry BIG BIG Printer Problem

    Hi,

    I cannot get it work right for a week and I am about to lost the hope that it can work somehow. Here, I try to put as much info as possible, so perhaps someone can help.
    The main problem is that printing works fine on one of the printers I am using but prints extremely large or small output on other units. The problem must be with calculation of the coordinates, I think. Here you are code snippets of what I do.

    Code:
    // Count vertical lines
    int PrintLineCounter = 0;
    
    // Create the print dialog
    CPrintDialog PrintDialog(FALSE, PD_ALLPAGES);
    if (PrintDialog.DoModal() != IDOK) {
    	return;
    }
    
    // Get Printer DC
    HDC hdcPrinter = PrintDialog.GetPrinterDC();
    if (hdcPrinter == NULL) {
    	return;
    }
    
    // Print on A4 only
    DEVMODE *pDevMode = PrintDialog.GetDevMode();
    if (((CString)A2CW("A4")).Compare(pDevMode->dmFormName) != 0) {
    	return;
    }
    
    // Attach to HDC
    CDC dcPrinter;
    dcPrinter.Attach(hdcPrinter);
    
    // Get printer size in pixels.
    // I saw references to that in posts here, took this routine from another website trusting that it works. Perhaps this fails? I include down there, together with CreateFontSize
    CRect PrintArea = UserPage(&dcPrinter, 0.5);
    
    // Font sizing is not my own, too
    FontSize4 = CreateFontSize(&dcPrinter, 4);
    FontSize8 = CreateFontSize(&dcPrinter, 6);
    
    // Create fonts using the calculated sizes
    FontCourier4Underline.CreateFont(FontSize4, 0, 0, 0, FW_NORMAL, 0, TRUE, 0, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_CHARACTER_PRECIS, PROOF_QUALITY, FIXED_PITCH, A2CW("Courier New"));
    FontCourier4.CreateFont(FontSize4, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_CHARACTER_PRECIS, PROOF_QUALITY, FIXED_PITCH, A2CW("Courier New"));
    FontCourier8Bold.CreateFont(FontSize8, 0, 0, 0, FW_BOLD, 0, 0, 0, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_CHARACTER_PRECIS, PROOF_QUALITY, FIXED_PITCH, A2CW("Courier New"));
    
    // call StartDoc() to begin printing
    DOCINFO docinfo;
    memset(&docinfo, 0, sizeof(docinfo));
    docinfo.cbSize = sizeof(docinfo);
    docinfo.lpszOutput = NULL;
    docinfo.lpszDocName = A2CW("Order");
    
    // If document start fails, no printing
    if (dcPrinter.StartDoc(&docinfo) < 0) {
    	dcPrinter.Detach();
    	return;
    }
    
    // First page start
    if (dcPrinter.StartPage() < 0) {
    	dcPrinter.AbortDoc();
    	return;
    }
    
    // Set coordinates to be right and down increasing, based on pixels
    SetMapMode(hdcPrinter, MM_TEXT);
    
    // Set printer font
    CFont *pOldFont = dcPrinter.SelectObject(&FontCourier4);
    
    // Draw a horizontal line
    dcPrinter.Rectangle(PrintArea.left, (PrintLineCounter * (FontSize4 + 1)) + (FontSize4 / 2), PrintArea.right, (PrintLineCounter++ * (FontSize4 + 1)) + (FontSize4 / 2) + 1);
    
    // Print some text
    dcPrinter.TextOut(PrintArea.left, PrintLineCounter++ * (FontSize4 + 1), "Gurus, where are you?");
    
    // Draw an additional horizontal line
    dcPrinter.Rectangle(PrintArea.left, (PrintLineCounter * (FontSize4 + 1)) + (FontSize4 / 2), PrintArea.right, (PrintLineCounter++ * (FontSize4 + 1)) + (FontSize4 / 2) + 1);
    
    // Print some more text
    dcPrinter.TextOut(PrintArea.left, PrintLineCounter++ * (FontSize4 + 1), "I hope close");
    
    // Print something to the middle of the page. Different font sizes lead to the conclusion to count vertical and horizontal points rather than rows and columns
    dcPrinter.SelectObject(&FontCourier8Bold);
    CSize Size = dcPrinter.GetTextExtent("CENTER");
    dcPrinter.TextOut(PrintArea.left + ((PrintArea.right - PrintArea.left) / 2) - (Size.cx / 2), PrintArea.top, "CENTER");
    
    
    // End of page
    dcPrinter.EndPage();
    
    // Send end document
    dcPrinter.EndDoc();
    
    // Restore font
    dcPrinter.SelectObject(pOldFont);
    
    // Cleanup
    dcPrinter.Detach();
    CDC::FromHandle(hdcPrinter)->DeleteDC();
    The question can come easily, how do I know the width and the height of a page. I took a dirty approach, set font printed a full page with given margin and counted. I was in the hope that if CreateFontSize work really appropriately then same number of characters fit on page at each density.

    But... something goes wrong. How can the size of a printing page and required font size calculated appropriately? I do not seek a miracle, just I would like to have the same printout from a CDialog based application on all printers... That should be some basic thing to do. Eh, eh, eh. I am very sad now. And did not even consider drawing boxes, putting pictures.



    Code:
    CRect COrderDialog::UserPage(CDC * pDC, float margin)
    {
        // This function returns the area in device units to be used to
        // prints a page with a true boarder of "margin".
        //
        // You could use individual margins for each edge
        // and apply below as needed.
        //
        // Set Map Mode - We do not want device units
        // due to lack of consistency.
        // If you do not use TWIPS you will have to change
        // the scaling factor below.
        int OriginalMapMode = pDC->SetMapMode(MM_TWIPS);
    
        // Variable needed to store printer info.
        CSize PrintOffset,Physical,Printable;
    
        // This gets the Physical size of the page in Device Units
        Physical.cx = pDC->GetDeviceCaps(PHYSICALWIDTH);
        Physical.cy = pDC->GetDeviceCaps(PHYSICALHEIGHT);
        // convert to logical
        pDC->DPtoLP(&Physical);
    
        // This gets the offset of the printable area from the
        // top corner of the page in Device Units
        PrintOffset.cx = pDC->GetDeviceCaps(PHYSICALOFFSETX);
        PrintOffset.cy = pDC->GetDeviceCaps(PHYSICALOFFSETY);
        // convert to logical
        pDC->DPtoLP(&PrintOffset);
    
        // Set Page scale to TWIPS, Which is 1440 per inch,
        // Zero/Zero is the upper left corner
        // Get Printable Page Size (This is in MM!) so convert to twips.
        Printable.cx =  (int)((float)pDC->GetDeviceCaps(HORZSIZE)*56.69);
        Printable.cy = (int)((float)pDC->GetDeviceCaps(VERTSIZE)*56.69);
    
        // Positive X -> RIGHT
        // Positive Y -> UP
        // Ref Zero is upper left corner
        int inch = 1440; // Scaling Factor Inches to TWIPS
        int Dx1, Dx2, Dy1, Dy2; // Distance printable area is from edge of paper
        Dx1 = PrintOffset.cx;
        Dy1 = PrintOffset.cy;
        // calculate remaining borders
        Dy2 = Physical.cy-Printable.cy-Dy1;
        Dx2 = Physical.cx-Printable.cx-Dx1;
        //
        // Define the User Area's location
        CRect PageArea;
        PageArea.left = (long)(margin*inch-Dx1);
        PageArea.right = (long)(Printable.cx-margin*inch+Dx2);
        PageArea.top = (int)-(margin*inch-Dy1); // My scale is inverted for y
        PageArea.bottom = (int)-(Printable.cy-margin*inch+Dy2);
        // now put back to device units to return to the program.
        pDC->LPtoDP(&PageArea);
        //
        // return
        return PageArea;
    }
    // Input: pointer to device context for printer
    // Input: desired point size of font (in points).
    // Output: integer height to send to CreateFont function.
    int COrderDialog::CreateFontSize(CDC *pdc, int points)
    {
        // This will calculate the font size for the printer that is specified
        // by a point size.
        //
        // if points is:
        //  (-) negative uses height as value for Net Font Height
        //                                         (ie. point size)
        //  (+) positive height is Total Height plus Leading Height!
        CSize size;
        int perinch = pdc->GetDeviceCaps(LOGPIXELSY);
        size.cx = size.cy = (perinch*points)/72;
        pdc->DPtoLP(&size);
        return size.cy;
    }

  2. #2
    Join Date
    Sep 1999
    Location
    Germany, Hessen
    Posts
    226
    Try to set the mapping mode BEFORE you call CreateFontSize(). perhaps that helps...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured