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;
}