daily pastebin goal
58%
SHARE
TWEET

Win32PrintTest.cpp with Qt

a guest Feb 6th, 2015 9 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Win32PrintTest.cpp
  2. // By Mike K.
  3. // Friday, February 6, 2015
  4. //
  5. // A function to print a test page using the same win32 functions that Qt uses but without
  6. // using the Qt print support.
  7. //
  8.  
  9.  
  10. #include "Win32PrintTest.h"
  11. #include <QDebug>
  12.  
  13.  
  14.  
  15.  
  16. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  17. void win32PrintTest()
  18. {
  19.     qDebug() << "Starting Win32 Print Test";
  20.  
  21.     // Get the name of the default printer
  22.     DWORD size = 0;
  23.     GetDefaultPrinter(NULL, &size);
  24.     TCHAR * printerName = new TCHAR[size];
  25.     BOOL ret = GetDefaultPrinter(printerName, &size);
  26.     if (!ret)
  27.     {
  28.         qDebug() << "Failed to get default printer name";
  29.         delete [] printerName;
  30.         return;
  31.     }
  32.     qDebug() << "Default printer name =" << QString::fromWCharArray(printerName);
  33.  
  34.  
  35.  
  36.     // Open the printer
  37.     HANDLE hPrinter;
  38.     ret = OpenPrinter(printerName, &hPrinter, NULL);
  39.     if (!ret)
  40.     {
  41.         qDebug() << "Failed to open printer";
  42.         delete [] printerName;
  43.         return;
  44.     }
  45.     qDebug() << "Successfully opened printer";
  46.  
  47.  
  48.  
  49.     // Get the printer
  50.     DWORD numBytes = 0;
  51.     GetPrinter(hPrinter, 2, 0, 0, &size);
  52.     BYTE * pBytes = new BYTE[size];
  53.     ret = GetPrinter(hPrinter, 2, pBytes, size, &numBytes);
  54.     if (!ret)
  55.     {
  56.         qDebug() << "Failed to get printer";
  57.         ClosePrinter(hPrinter);
  58.         delete [] pBytes;
  59.         delete [] printerName;
  60.         return;
  61.     }
  62.     qDebug() << "Successfully got printer";
  63.  
  64.  
  65.  
  66.     // Get the info
  67.     PRINTER_INFO_2 * pPrinterInfo = (PRINTER_INFO_2 *) pBytes;
  68.     qDebug() << "Server name =" << QString::fromWCharArray(pPrinterInfo->pServerName);
  69.     qDebug() << "Printer name =" << QString::fromWCharArray(pPrinterInfo->pPrinterName);
  70.     qDebug() << "Share name =" << QString::fromWCharArray(pPrinterInfo->pShareName);
  71.     qDebug() << "Port name =" << QString::fromWCharArray(pPrinterInfo->pPortName);
  72.     qDebug() << "Driver name =" << QString::fromWCharArray(pPrinterInfo->pDriverName);
  73.     qDebug() << "Comment =" << QString::fromWCharArray(pPrinterInfo->pComment);
  74.     qDebug() << "Location =" << QString::fromWCharArray(pPrinterInfo->pLocation);
  75.     qDebug() << "Print processor =" << QString::fromWCharArray(pPrinterInfo->pPrintProcessor);
  76.     qDebug() << "Data type =" << QString::fromWCharArray(pPrinterInfo->pDatatype);
  77.     qDebug() << "Status is " << pPrinterInfo->Status << win32PrinterStatusToString(pPrinterInfo->Status);
  78.     qDebug() << "Jobs in queue =" << pPrinterInfo->cJobs;
  79.  
  80.  
  81.  
  82.     DEVMODE * pDevMode = pPrinterInfo->pDevMode;
  83.     bool bOwnDevMode = false;
  84.  
  85.  
  86.  
  87.     if (pDevMode == NULL)
  88.     {
  89.         qDebug() << "DEVMODE is NULL.  Getting it a different way.";
  90.  
  91.         // Get the number of bytes required.
  92.         LONG lBytesNeeded = DocumentProperties(NULL, hPrinter, printerName, NULL, NULL, 0);
  93.         if (lBytesNeeded <= 0)
  94.         {
  95.             qDebug() << "DocumentProperties failed to return bytes needed (" << lBytesNeeded << ")";
  96.             qDebug() << "GetLastError =" << GetLastError();
  97.             ClosePrinter(hPrinter);
  98.             delete [] pBytes;
  99.             delete [] printerName;
  100.             return;
  101.         }
  102.  
  103.         // Allocate the buffer and get the DEVMODE
  104.         pDevMode = (DEVMODE *) new BYTE[lBytesNeeded];
  105.         bOwnDevMode = true;
  106.         LONG lRet = DocumentProperties(NULL, hPrinter, printerName, pDevMode, NULL, DM_OUT_BUFFER);
  107.         if ((lRet != IDOK) || (pDevMode == NULL))
  108.         {
  109.             qDebug() << "DocumentProperties failed to get DEVMODE";
  110.             qDebug() << "GetLastError =" << GetLastError();
  111.             ClosePrinter(hPrinter);
  112.             if (pDevMode) delete [] (BYTE *)(pDevMode);
  113.             delete [] pBytes;
  114.             delete [] printerName;
  115.             return;
  116.         }
  117.     }
  118.  
  119.  
  120.  
  121.     if (pDevMode)
  122.     {
  123.         qDebug() << "Device name" << QString::fromWCharArray(pDevMode->dmDeviceName);
  124.  
  125.         if (pDevMode->dmFields & DM_ORIENTATION)   qDebug() << "Paper orientation =" << win32OrientationToString(pDevMode->dmOrientation);
  126.         if (pDevMode->dmFields & DM_PAPERSIZE)     qDebug() << "Paper size =" << win32PaperSizeToString(pDevMode->dmPaperSize);
  127.         if (pDevMode->dmFields & DM_FORMNAME)      qDebug() << "Form name =" << QString::fromWCharArray(pDevMode->dmFormName);
  128.         if (pDevMode->dmFields & DM_PAPERWIDTH)    qDebug() << "Paper width =" << pDevMode->dmPaperWidth/10.0 << "mm";
  129.         if (pDevMode->dmFields & DM_PAPERLENGTH)   qDebug() << "Paper length =" << pDevMode->dmPaperLength/10.0 << "mm";
  130.         if (pDevMode->dmFields & DM_COPIES)        qDebug() << "Copies =" << pDevMode->dmCopies;
  131.         if (pDevMode->dmFields & DM_PRINTQUALITY)  qDebug() << "Print quality =" << win32PrintQualityToString(pDevMode->dmPrintQuality);
  132.         if (pDevMode->dmFields & DM_COLLATE)       qDebug() << "Collate =" << (pDevMode->dmCollate == DMCOLLATE_FALSE ? "No" : "Yes");
  133.         if (pDevMode->dmFields & DM_COLOR)         qDebug() << "Color =" << (pDevMode->dmColor == DMCOLOR_COLOR ? "Yes" : "No");
  134.         if (pDevMode->dmFields & DM_DUPLEX)        qDebug() << "Duplex =" << win32DuplexSettingToString(pDevMode->dmDuplex);
  135.         if (pDevMode->dmFields & DM_YRESOLUTION)   qDebug() << "Y-resolution =" << pDevMode->dmYResolution << "DPI";
  136.         if (pDevMode->dmFields & DM_DEFAULTSOURCE) qDebug() << "Default source =" << win32DefaultSourceToString(pDevMode->dmDefaultSource);
  137.     }
  138.  
  139.  
  140.  
  141.  
  142.     // Create a device context
  143.     HDC hDC = CreateDC(NULL, printerName, 0, pDevMode);
  144.     if (hDC == NULL)
  145.     {
  146.         qDebug() << "(!) Failed to create device context";
  147.         ClosePrinter(hPrinter);
  148.         if (bOwnDevMode) delete [] (BYTE *)(pDevMode);
  149.         delete [] pBytes;
  150.         delete [] printerName;
  151.         return;
  152.     }
  153.     qDebug() << "Successfully created device context";
  154.  
  155.  
  156.  
  157.     // Get info about printer and its settings
  158.     int xDPI = GetDeviceCaps(hDC, LOGPIXELSX);
  159.     int yDPI = GetDeviceCaps(hDC, LOGPIXELSY);
  160.     int widthPixels  = GetDeviceCaps(hDC, PHYSICALWIDTH);
  161.     int heightPixels = GetDeviceCaps(hDC, PHYSICALHEIGHT);
  162.     int xOffset = GetDeviceCaps(hDC, PHYSICALOFFSETX);
  163.     int yOffset = GetDeviceCaps(hDC, PHYSICALOFFSETY);
  164.  
  165.     qDebug() << "xDPI =" << xDPI;
  166.     qDebug() << "yDPI =" << yDPI;
  167.     qDebug() << "Size in device pixels =" << widthPixels << "x" << heightPixels;
  168.     qDebug() << "xOffset =" << xOffset;
  169.     qDebug() << "yOffset =" << yOffset;
  170.  
  171.     // Use 1/2 inch margin
  172.     // Point (0, 0) is the upper-left of the printable area of the page, which is xOffset from the left edge of the paper and yOffset from the top edge of the paper.
  173.     RECT rectPixels;
  174.     rectPixels.left   = xDPI/2 - xOffset;
  175.     rectPixels.right  = widthPixels - xDPI/2 - xOffset;
  176.     rectPixels.top    = yDPI/2 - yOffset;
  177.     rectPixels.bottom = heightPixels - yDPI/2 - yOffset;
  178.  
  179.  
  180.     // Draw something
  181.     DOCINFO di = {0};
  182.     di.cbSize = sizeof(DOCINFO);
  183.     di.lpszDocName = L"Win32 Print Test";
  184.     int sd = StartDoc(hDC, &di);
  185.     if (sd > 0)
  186.     {
  187.         qDebug() << "Started document";
  188.         int sp = StartPage(hDC);
  189.         if (sp > 0)
  190.         {
  191.             qDebug() << "Started page";
  192.             SelectObject(hDC, GetStockObject(NULL_BRUSH));
  193.             int xMid = (rectPixels.left + rectPixels.right)/2;
  194.             int yMid = (rectPixels.top + rectPixels.bottom)/2;
  195.             Rectangle(hDC, xMid-xDPI/2, yMid-yDPI/2+2*yDPI, xMid+xDPI/2, yMid+yDPI/2+2*yDPI);
  196.             Rectangle(hDC, xMid-xDPI/2, yMid-yDPI/2-2*yDPI, xMid+xDPI/2, yMid+yDPI/2-2*yDPI);
  197.             Rectangle(hDC, xMid-xDPI/2-2*xDPI, yMid-yDPI/2, xMid+xDPI/2-2*xDPI, yMid+yDPI/2);
  198.             Rectangle(hDC, xMid-xDPI/2+2*xDPI, yMid-yDPI/2, xMid+xDPI/2+2*xDPI, yMid+yDPI/2);
  199.             DrawText(hDC, L"Win32 Print Test", -1, &rectPixels, DT_SINGLELINE|DT_CENTER|DT_VCENTER);
  200.             int ep = EndPage(hDC);
  201.             if (ep) qDebug() << "Ended page"; else qDebug() << "Failed to end page";
  202.         }
  203.         else
  204.         {
  205.             // Failed to start page
  206.             qDebug() << "Failed to start page";
  207.         }
  208.  
  209.         int ed = EndDoc(hDC);
  210.         if (ed) qDebug() << "Ended document"; else qDebug() << "Failed to end document";
  211.     }
  212.     else
  213.     {
  214.         // Failed to start print job
  215.         qDebug() << "Failed to start document";
  216.     }
  217.  
  218.  
  219.  
  220.  
  221.     // Cleanup
  222.     DeleteDC(hDC);
  223.     ClosePrinter(hPrinter);
  224.     if (bOwnDevMode) delete [] (BYTE *)(pDevMode);
  225.     delete [] pBytes;
  226.     delete [] printerName;
  227. }
  228.  
  229.  
  230.  
  231.  
  232. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  233. // Converts a win32 printer status to a string (PRINTER_STATUS_*)
  234. QString win32PrinterStatusToString(DWORD status)
  235. {
  236.     QString str;
  237.     if (status & PRINTER_STATUS_BUSY) str += "Busy, ";
  238.     if (status & PRINTER_STATUS_DOOR_OPEN) str += "Door Open, ";
  239.     if (status & PRINTER_STATUS_ERROR) str += "Error, ";
  240.     if (status & PRINTER_STATUS_INITIALIZING) str += "Initializing, ";
  241.     if (status & PRINTER_STATUS_IO_ACTIVE) str += "IO Active, ";
  242.     if (status & PRINTER_STATUS_MANUAL_FEED) str += "Manual feed, ";
  243.     if (status & PRINTER_STATUS_NO_TONER) str += "No toner, ";
  244.     if (status & PRINTER_STATUS_NOT_AVAILABLE) str += "Not available, ";
  245.     if (status & PRINTER_STATUS_OFFLINE) str += "Offline, ";
  246.     if (status & PRINTER_STATUS_OUT_OF_MEMORY) str += "Out of memory, ";
  247.     if (status & PRINTER_STATUS_OUTPUT_BIN_FULL) str += "Output bin full, ";
  248.     if (status & PRINTER_STATUS_PAGE_PUNT) str += "Cannot print current page, ";
  249.     if (status & PRINTER_STATUS_PAPER_JAM) str += "Paper jam, ";
  250.     if (status & PRINTER_STATUS_PAPER_OUT) str += "Paper out, ";
  251.     if (status & PRINTER_STATUS_PAPER_PROBLEM) str += "Paper problem, ";
  252.     if (status & PRINTER_STATUS_PAUSED) str += "Paused, ";
  253.     if (status & PRINTER_STATUS_PENDING_DELETION) str += "Pending deletion, ";
  254.     if (status & PRINTER_STATUS_POWER_SAVE) str += "Power save, ";
  255.     if (status & PRINTER_STATUS_PRINTING) str += "Printing, ";
  256.     if (status & PRINTER_STATUS_PROCESSING) str += "Processing, ";
  257.     if (status & PRINTER_STATUS_SERVER_UNKNOWN) str += "Server unknown, ";
  258.     if (status & PRINTER_STATUS_TONER_LOW) str += "Toner low, ";
  259.     if (status & PRINTER_STATUS_USER_INTERVENTION) str += "User intervention, ";
  260.     if (status & PRINTER_STATUS_WAITING) str += "Waiting, ";
  261.     if (status & PRINTER_STATUS_WARMING_UP) str += "Warming up, ";
  262.  
  263.  
  264.     // Chop off the last ", "
  265.     if (str.endsWith(", ")) str = str.left(str.length() - 2);
  266.  
  267.  
  268.     // If no status
  269.     if (str.isEmpty()) str = "None";
  270.  
  271.     return "(" + str + ")";
  272. }
  273.  
  274.  
  275. QString win32OrientationToString(short orientation)
  276. {
  277.     if (orientation == DMORIENT_PORTRAIT)  return "Portrait";
  278.     if (orientation == DMORIENT_LANDSCAPE) return "Landscape";
  279.     return QString::number(orientation);
  280. }
  281.  
  282.  
  283. QString win32PaperSizeToString(short paperSize)
  284. {
  285.     if (paperSize == DMPAPER_LETTER) return "Letter";
  286.     if (paperSize == DMPAPER_LEGAL)  return "Legal";
  287.     if (paperSize == DMPAPER_A4)     return "A4";
  288.     if (paperSize == DMPAPER_USER)   return "Custom";
  289.     return QString::number(paperSize);
  290. }
  291.  
  292.  
  293. QString win32PrintQualityToString(short printQuality)
  294. {
  295.     if (printQuality == DMRES_HIGH)   return "High";
  296.     if (printQuality == DMRES_MEDIUM) return "Medium";
  297.     if (printQuality == DMRES_LOW)    return "Low";
  298.     if (printQuality == DMRES_DRAFT)  return "Draft";
  299.     if (printQuality > 0) return QString("%1 (xDPI)").arg(printQuality);      // If positive, specifies the DPI along the x-axis.
  300.     return QString::number(printQuality);
  301. }
  302.  
  303.  
  304. QString win32DuplexSettingToString(short duplex)
  305. {
  306.     if (duplex == DMDUP_SIMPLEX)    return "Simplex (nonduplex)";
  307.     if (duplex == DMDUP_HORIZONTAL) return "Duplex short-edge binding";
  308.     if (duplex == DMDUP_VERTICAL)   return "Duplex long-edge binding";
  309.     return QString::number(duplex);
  310. }
  311.  
  312.  
  313. QString win32DefaultSourceToString(short source)
  314. {
  315.     if (source == DMBIN_AUTO) return "Auto";
  316.     if (source == DMBIN_CASSETTE) return "Cassette";
  317.     if (source == DMBIN_ENVELOPE) return "Envelope";
  318.     if (source == DMBIN_ENVMANUAL) return "Envelope (manual)";
  319.     if (source == DMBIN_FIRST) return "First";
  320.     if (source == DMBIN_FORMSOURCE) return "Form source";
  321.     if (source == DMBIN_LARGECAPACITY) return "Large capacity";
  322.     if (source == DMBIN_LARGEFMT) return "Large format";
  323.     if (source == DMBIN_LAST) return "Last";
  324.     if (source == DMBIN_LOWER) return "Lower";
  325.     if (source == DMBIN_MANUAL) return "Manual";
  326.     if (source == DMBIN_MIDDLE) return "Middle";
  327.     if (source == DMBIN_ONLYONE) return "Only one";
  328.     if (source == DMBIN_TRACTOR) return "Tractor";
  329.     if (source == DMBIN_SMALLFMT) return "Small format";
  330.     if (source == DMBIN_UPPER) return "Upper";
  331.     if (source >= DMBIN_USER) return QString("Device-specific value (%1)").arg(source);
  332.     return QString::number(source);
  333. }
RAW Paste Data
Top