C++的连接打印机显示图片的问题

HDC hdcPrint; //打印机直流手柄

TCHAR szDevString [120]; //数组为WIN.INI数据

TCHAR * szPrinter,* szDriver; //打印机和驱动程序名称

TCHAR * szPort; //端口名称

TCHAR * nextChar;

//检索打印机,打印机驱动程序和  
//从WIN.INI输出端口名称。  

GetProfileString(_T(“windows”),_T(“device”),_T(“,,,”), 
    szDevString,120); 

//解析名字串,根据需要设置ptrs  
//如果字符串包含所需的名称,请使用它们  
//创建设备上下文。  

if((szPrinter = _tcstok_s(szDevString, 
           _T(“,”),&nextChar)) 
        &&(szDriver = _tcstok_s(NULL, 
           _T(“,”),&nextChar)) 
        &&(szPort = _tcstok_s(NULL, 
           _T(“,”),&nextChar)))
{
    hdcPrint = CreateDC(szDriver,szPrinter, 
        szPort,NULL); 
}

//打印包含该字符串的测试页  
//“打印机测试”在左上角。  

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

//删除打印机DC。  
DeleteDC(hdcPrint); 

    这是我查到的资料,已经测试完毕,但是现在的结果就是我只能打出一行文字,但是打印不出图像,希望有大神能来执教一下  我QQ568997743 如果解决定有重谢

你这个肯定打印不出图形,你用的是esc/pos指令集,这种底层的方式只能打印文本。
如果用这种方式要打印图像,需要自己计算像素点,转换为打印指令,再输出,不是一般的麻烦。

正确的做法是安装好打印机驱动,用windows的图形打印方式打印。

添加一个bitmap资源叫做IDB_BITMAP1,放一个图片

然后用下面的代码:

 // Q695292.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include "windows.h"
#include "resource.h"

int _tmain(int argc, _TCHAR* argv[])
{
    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) {

        Escape(hdcPrint, STARTDOC, 8, "Test-Doc", NULL); 

        HBITMAP hBitmap = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BITMAP1));

        HDC hMemDC = CreateCompatibleDC(hdcPrint);
        SelectObject(hMemDC, hBitmap);
        BitBlt(hdcPrint, 0, 0, 3650 * 15, 2710 * 15, hMemDC, 0, 0, SRCCOPY); //用bitblt画图
        DeleteDC(hMemDC);
        DeleteObject(hBitmap);

        Escape(hdcPrint, NEWFRAME, 0, NULL, NULL); 
        Escape(hdcPrint, ENDDOC, 0, NULL, NULL); 

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


图片说明
运行效果(我用的是pdf虚拟打印机,如果你默认打印机设置为你的物理打印机,就可以打印输出了)

 // Q695292.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include "windows.h"
#include "resource.h"

HBITMAP CaptureImage(HWND hwnd)
{
    HANDLE hDIB;
    DWORD dwBmpSize;
    HBITMAP hbmScreen = NULL;
    BITMAP bmpScreen;
    BITMAPINFOHEADER bi;
    CHAR *lpbitmap;
    INT width = GetSystemMetrics(SM_CXSCREEN);  // 屏幕宽
    INT height = GetSystemMetrics(SM_CYSCREEN);  // 屏幕高
    HDC hdcScreen = GetDC(NULL); // 全屏幕DC
    HDC hdcMemDC = CreateCompatibleDC(hdcScreen); // 创建兼容内存DC

    if (!hdcMemDC)
    {
        //echo(TEXT("CreateCompatibleDC has failed"));
        goto done;
    }

    // 通过窗口DC 创建一个兼容位图
    hbmScreen = CreateCompatibleBitmap(hdcScreen, width, height);

    if (!hbmScreen)
    {
        //echo(TEXT("CreateCompatibleBitmap Failed"));
        goto done;
    }

    // 将位图块传送到我们兼容的内存DC中
    SelectObject(hdcMemDC, hbmScreen);
    if (!BitBlt(
                hdcMemDC,    // 目的DC
                0, 0,        // 目的DC的 x,y 坐标
                width, height, // 目的 DC 的宽高
                hdcScreen,   // 来源DC
                0, 0,        // 来源DC的 x,y 坐标
                SRCCOPY))    // 粘贴方式
    {
        //echo(TEXT("BitBlt has failed"));
        goto done;
    }

    // 获取位图信息并存放在 bmpScreen 中
    GetObject(hbmScreen, sizeof(BITMAP), &bmpScreen);

    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = bmpScreen.bmWidth;
    bi.biHeight = bmpScreen.bmHeight;
    bi.biPlanes = 1;
    bi.biBitCount = 32;
    bi.biCompression = BI_RGB;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0;

    dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;

    // 在 32-bit Windows 系统上, GlobalAlloc 和 LocalAlloc 是由 HeapAlloc 封装来的
    // handle 指向进程默认的堆. 所以开销比 HeapAlloc 要大
    hDIB = GlobalAlloc(GHND, dwBmpSize);
    lpbitmap = (char *)GlobalLock(hDIB);

    // 获取兼容位图的位并且拷贝结果到一个 lpbitmap 中.
    GetDIBits(
        hdcScreen,  // 设备环境句柄
        hbmScreen,  // 位图句柄
        0,          // 指定检索的第一个扫描线
        (UINT)bmpScreen.bmHeight, // 指定检索的扫描线数
        lpbitmap,   // 指向用来检索位图数据的缓冲区的指针
        (BITMAPINFO *)&bi, // 该结构体保存位图的数据格式
        DIB_RGB_COLORS // 颜色表由红、绿、蓝(RGB)三个直接值构成
    );

    // 解锁堆内存并释放
    GlobalUnlock(hDIB);
    GlobalFree(hDIB);

    // 清理资源
done:
    //DeleteObject(hbmScreen);
    DeleteObject(hdcMemDC);
    ReleaseDC(NULL, hdcScreen);

    return hbmScreen;
}


int _tmain(int argc, _TCHAR* argv[])
{
    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) {

        Escape(hdcPrint, STARTDOC, 8, "Test-Doc", NULL); 

        HBITMAP hBitmap = CaptureImage(GetDesktopWindow()); //LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BITMAP1));

        HDC hMemDC = CreateCompatibleDC(hdcPrint);
        SelectObject(hMemDC, hBitmap);
        //BitBlt(hdcPrint, 0, 0, 3650 * 15, 2710 * 15, hMemDC, 0, 0, SRCCOPY);
        StretchBlt(hdcPrint, 300, 300, 1680 * 8 / 3, 1050 * 8 / 3, hMemDC, 0, 0, 1680, 1050, SRCCOPY);

        DeleteDC(hMemDC);
        DeleteObject(hBitmap);

        Escape(hdcPrint, NEWFRAME, 0, NULL, NULL); 
        Escape(hdcPrint, ENDDOC, 0, NULL, NULL); 

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


图片说明