c++ - Windows GDI 打印机错误 StartDocPrinter

标签 c++ qt winapi printing

实际上我正在使用 Qt 打印,需要将 RAW 命令(ESCP 命令)发送到打印机。在做了一些搜索之后,我发现我需要使用 Windows API 来完成它。

请参阅此线程:win32-c-print-string-to-printer

我创建了如下代码:

const QString pName = "EPSON LX-300+ /II";
LPBYTE lpData;
BOOL bStatus = FALSE;
HANDLE hPrinter = NULL;
DOC_INFO_1 DocInfo;
DWORD dwPrtJob = 0L;
DWORD dwBytesWritten = 0L;
LPTSTR printerName = new wchar_t[pName.length() + 1];
pName.toWCharArray(printerName);
printerName[pName.length()] = '\0';
QString so = "\x1b@Is it works?";
QByteArray ba = so.toUtf8();
lpData = (unsigned char*)(ba.data());
DWORD dwCount = ba.length();
qDebug() << so;

bStatus = OpenPrinter(printerName, &hPrinter, NULL);
if(bStatus) {
    DocInfo.pDocName = (LPTSTR)_T("My Document");
    DocInfo.pOutputFile = NULL;
    DocInfo.pDatatype = (LPTSTR)_T("RAW");
    dwPrtJob = StartDocPrinter (
                    hPrinter,
                    1,
                    (LPBYTE)&DocInfo);
    qDebug() << GetLastError();
    if (dwPrtJob > 0) {
            qDebug() << "COMMAND";
            // Send the data to the printer.
            bStatus = WritePrinter (
            hPrinter,
            lpData,
            dwCount,
            &dwBytesWritten);
    }
    qDebug() << dwCount;
    qDebug() << dwBytesWritten;

    EndDocPrinter (hPrinter);

    // Close the printer handle.
    bStatus = ClosePrinter(hPrinter);
    qDebug() << bStatus;
}

if (!bStatus || (dwCount != dwBytesWritten)) {
    bStatus = FALSE;
} else {
    bStatus = TRUE;
}

delete printerName;

代码在 StartDocPrinter 上失败,它返回 0,这意味着失败。并使用 GetLastError(),函数返回 1804。并引用 this ,错误是 ERROR_INVALID_DATATYPE。我不确定这是什么错误。我尝试对“RAW”、“TEXT”和“XPS_PASS”使用不同的 DocInfo.pDatatype,结果是一样的。

有什么办法可以解决吗?

最佳答案

DOC_INFO_1 DocInfo;
DocInfo.pDocName = (LPTSTR)_T("My Document");
DocInfo.pOutputFile = NULL;
DocInfo.pDatatype = (LPTSTR)_T("RAW");

这个转换归结为

DocInfo.pDocName = (wchar_t*)L"My Document";
...

pDocName 被声明为 wchar_t* 这是错误的,转换只是隐藏了错误和警告。尽量避免使用 Microsoft T 宏,这些宏已过时且无用。请改用 C++ charwchar_t*。要在 Windows 中声明 UTF16 宽字符字符串,请使用 L 前缀。正确的用法如下:

DOC_INFO_1 DocInfo;
wchar_t docName[100], dataType[100];
wcscpy_s(docName, 100, L"Print Job");
wcscpy_s(dataType, 100, L"RAW");
DocInfo.pDocName = docName;
DocInfo.pOutputFile = NULL;
DocInfo.pDatatype = dataType;

例子:

const QString pName = "EPSON LX-300+ /II";
wchar_t printerName[100];
pName.toWCharArray(printerName);
pName[pName.length()] = '\0';

HANDLE hprinter;
if (OpenPrinter(printerName, &hprinter, NULL))
{
    DOC_INFO_1 DocInfo;
    wchar_t docName[100], dataType[100];
    wcscpy_s(docName, 100, L"Print Job");
    wcscpy_s(dataType, 100, L"RAW");
    DocInfo.pDocName = docName;
    DocInfo.pOutputFile = NULL;
    DocInfo.pDatatype = dataType;

    DWORD printJob = StartDocPrinter(hprinter, 1, (LPBYTE)&DocInfo);
    if (printJob && StartPagePrinter(hprinter))
    {
        MessageBox(0, L"StartPagePrinter OKAY", 0, 0);
        DWORD written = 0;
        int buflen = 100;
        char *buf = new char[buflen];
        strcpy_s(buf, buflen, "123");
        if (WritePrinter(hprinter, buf, 3, &written))
            MessageBox(0, L"OKAY", 0, 0);
        delete[]buf;
        EndPagePrinter(hprinter);
        EndDocPrinter(hprinter);
    }
    ClosePrinter(hprinter);
}

关于c++ - Windows GDI 打印机错误 StartDocPrinter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38022965/

相关文章:

c++ - OOP 类定义问题

c++ - 写得很好的 C++ 例子

c++ - 如何获得忘记算术运算的警告?

c++ - 使用 Qt 连接到本地数据库

c++ - 在 winapi 中以尽可能低的权限运行进程

c++ - 为什么单例模板会使我的程序崩溃?

c++ - 为什么不显示 QGraphicsView

Qt Creator - 如何将工具提示的背景颜色设置为与小部件不同?

c++ - 如何在 Aero 玻璃窗上绘制不透明图像?

c++ - 使用 C++ 获取本地管理员用户名