user3419168
user3419168

Reputation: 1135

Printing a specified BMP file to printer

I've ran into a problem that is a very foreign topic to me: printing to a printer.

Through scouring the internet I have found a way to print to my printer, but only simple text.

see here:

#include <stdio.h>
#include <windows.h>
#include <string.h>

int main () 
{
TCHAR   szDriver[16] = _T("WINSPOOL");
TCHAR   szPrinter[256];
DWORD   cchBuffer = 255;
HDC     hdcPrint = NULL;
HANDLE  hPrinter = NULL;
PRINTER_INFO_2  *pPrinterData;
BYTE    pdBuffer[16384];
BOOL    bReturn = FALSE;

DWORD   cbBuf = sizeof (pdBuffer);
DWORD   cbNeeded = 0;
pPrinterData = (PRINTER_INFO_2 *)&pdBuffer[0];

// get the default printer name
bReturn = GetDefaultPrinter(
    szPrinter,
    &cchBuffer);

if (bReturn) {
    // open the default printer
    bReturn = OpenPrinter(
        szPrinter,
        &hPrinter,
        NULL);
}

if (bReturn) {
    // get the printer port name
    bReturn =  GetPrinter(
        hPrinter,
        2,
        &pdBuffer[0],
        cbBuf,
        &cbNeeded);

       // this handle is no longer needed
    ClosePrinter(hPrinter);
}

if (bReturn) {
   // create the Print DC
   hdcPrint = CreateDC(szDriver, szPrinter, 
        pPrinterData->pPortName, NULL); 
}

if (hdcPrint) {
    // Print a test page that contains the string  
    // "PRINTER TEST" in the upper left corner.  

    Escape(hdcPrint, STARTDOC, 8, "Test-Doc", NULL); 
    TextOut(hdcPrint, 50, 50, _T("PRINTER TEST"), 12); 
    Escape(hdcPrint, NEWFRAME, 0, NULL, NULL); 
    Escape(hdcPrint, ENDDOC, 0, NULL, NULL); 

    // Delete the printer DC.  
    DeleteDC(hdcPrint); 
}

This successfully prints "PRINTER TEXT" to my printer. What I'm looking for is how to specify a path to a BMP file, and then print that BMP file. Though I've found some information using Google, all efforts have provided nothing. I appreciate any help.

Current update:

#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <string.h>

int main () 
{
TCHAR   szDriver[16] = _T("WINSPOOL");
TCHAR   szPrinter[256];
DWORD   cchBuffer = 255;
HDC     hdcPrint = NULL;
HDC     hdcPrintImg = NULL;
HANDLE  hPrinter = NULL;
PRINTER_INFO_2  *pPrinterData;
BYTE    pdBuffer[16384];
BOOL    bReturn = FALSE;

DWORD   cbBuf = sizeof (pdBuffer);
DWORD   cbNeeded = 0;
pPrinterData = (PRINTER_INFO_2 *)&pdBuffer[0];

// get the default printer name
bReturn = GetDefaultPrinter(
    szPrinter,
    &cchBuffer);

if (bReturn) {
    // open the default printer
    bReturn = OpenPrinter(
        szPrinter,
        &hPrinter,
        NULL);
}

if (bReturn) {
    // get the printer port name
    bReturn =  GetPrinter(
        hPrinter,
        2,
        &pdBuffer[0],
        cbBuf,
        &cbNeeded);

       // this handle is no longer needed
    ClosePrinter(hPrinter);
}

if (bReturn) {
    // create the Print DC
    HBITMAP bmp = (HBITMAP)LoadImage(0, L"print_file.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    HBITMAP CreatCompatibleBitmap(bmp);
    hdcPrintImg = bmp;
    hdcPrint = CreateDC(szDriver, szPrinter, 
        pPrinterData->pPortName, NULL); 
}

if (hdcPrint) {
    // Print a test page that contains the string  
    // "PRINTER TEST" in the upper left corner.  
    //Escape(hdcPrint, STARTDOC, 8, "Test-Doc", NULL); 
    //TextOut(hdcPrint, 50, 50, _T("PRINTER TEST"), 12); 
    BitBlt(hdcPrint, 0, 0, 3300, 2550, hdcPrintImg, 0, 0, SRCCOPY);
    //Escape(hdcPrint, NEWFRAME, 0, NULL, NULL); 
    //Escape(hdcPrint, ENDDOC, 0, NULL, NULL); 

    // Delete the printer DC.  
    DeleteDC(hdcPrint); 
}

}

Upvotes: 3

Views: 4400

Answers (1)

Jerry Coffin
Jerry Coffin

Reputation: 490178

Printing to a printer isn't much different from printing to the screen. You've already handled all the "stuff" that's different about a printer.

Your hdcPrint is basically just a normal handle to a normal DC. You can print a BMP to it just about the way you'd display a BMP on the screen:

  1. Load the BMP
  2. Create a DC compatible with your destination DC
  3. Select that BMP into a compatible DC
  4. Blit from the compatible DC to the DC for the printer.

The big difference is that a screen typically has around 100 DPI, where a printer typically has at least 300 DPI. As such, a picture that sized to look reasonable on-screen will generally look minuscule on a printer. Depending on its dimensions, you may well want to scale the picture up when printing to a printer.

As an aside: there are also a few printers that aren't compatible with Bit Blitting. You may want to use GetDeviceCaps(RC_BITBLT) or GetDeviceCaps(RC_STRETCHBLT) before writing your data. At one time, you ran into this pretty often, but I haven't seen it in quite a while.

Upvotes: 2

Related Questions