Windows GDI打印机错误StartDocprinter

Windows GDI Printer error StartDocPrinter

本文关键字:StartDocprinter 错误 打印机 GDI Windows      更新时间:2023-10-16

实际上我正在使用QT打印,需要将RAW命令(ESCP命令)发送到打印机。进行了一些搜索之后,我发现我需要使用Windows API进行操作。

请参阅此线程:win32-c-print-rint-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()] = '';
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,这意味着失败。并使用getlastror(),函数返回1804。请参阅此错误,错误是error_invalid_datatype。我不确定是什么错误。我尝试将不同的docinfo.pdatatype用于"原始"," text"answers" xps_pass",结果是相同的。

我有什么可以解决的吗?

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()] = '';
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);
}

这对我来说是为将RAW命令发送到斑马打印机而没有所有复制缓冲器的方法:

void rawDataToPrinter(QString text, QString printerName)
{
    HANDLE hPrinter;
    if (OpenPrinter(const_cast<wchar_t*>(printerName.toStdWString().c_str()), &hPrinter, nullptr))
    {
        wchar_t docName[] = L"Print Job";
        wchar_t dataType[] = L"Raw";
        // Fill in the structure with info about this "document."
        DOC_INFO_1 docInfo;
        docInfo.pDocName = docName;
        docInfo.pOutputFile = nullptr;
        docInfo.pDatatype = dataType;
        // Inform the spooler the document is beginning.
        DWORD printJob = StartDocPrinter(hPrinter, 1, reinterpret_cast<LPBYTE>(&docInfo));
        if (printJob && StartPagePrinter(hPrinter))
        {
            DWORD dwBytesWritten;
            if(!WritePrinter(hPrinter, const_cast<char*>(qPrintable(text)), static_cast<DWORD>(text.length()), &dwBytesWritten))
            {
                qDebug() << "Print job failed..";
            }
            else
            {
                qDebug() << "Job send to printed";
            }
            EndPagePrinter(hPrinter);
            EndDocPrinter(hPrinter);
        }
        else
        {
            qDebug() << "Failed to open document or start page on printer " << printerName;
        }
        ClosePrinter(hPrinter);
    }
    else
    {
        qDebug() << "Failed to open printer " << printerName;
    }
}