【问题标题】:Read Epson Printer Status using C++ and ESC/P使用 C++ 和 ESC/P 读取 Epson 打印机状态
【发布时间】:2011-10-25 18:19:00
【问题描述】:

我正在尝试使用 C++ 获取 PLQ-20 Espon 打印机的状态,但没有成功。

我尝试使用带有 PASSTHROUGH 参数的 GDI APIEscape 函数,但打印机永远无法理解该函数的转义码。

我尝试使用 WIN 32 API 并找到了示例代码 here。这适用于发送一些转义码,如 BEL(使蜂鸣器响起)或 FF(Form Feed,从打印机后部弹出纸张),但不适用于 ESC O(从打印机前端弹出纸张),ESC 0 / ESC 1(初始化打印机/重置错误)。

所以,我尝试通过 ESC j 转义码以这种方式获取打印机的状态,但没有成功(ReadPrinter 函数返回 0)。此外,打印缓冲区似乎不是空的,但我只发送转义命令。

我不知道我是否在发送转义码或尝试读取打印机状态时出错。

如果有人可以发布示例,那么每个人都可以,因为在网络上很难找到它们。

下面是我用来发送命令和读取结果的代码

#include <Windows.h>
#include <StdIO.h>


// **********************************************************************
// PrintError - uses printf() to display error code information
// 
// Params:
//   dwError       - the error code, usually from GetLastError()
//   lpString      - some caller-defined text to print with the error info
// 
// Returns: void
// 
void PrintError( DWORD dwError, LPCTSTR lpString )
{
#define MAX_MSG_BUF_SIZE 512
    TCHAR   *msgBuf;
    DWORD   cMsgLen;

    cMsgLen = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM |
                FORMAT_MESSAGE_ALLOCATE_BUFFER | 40, NULL, dwError,
                MAKELANGID(0, SUBLANG_ENGLISH_US), (LPTSTR) &msgBuf,
                MAX_MSG_BUF_SIZE, NULL );
    printf("%s Error [%d]:: %s\n", lpString, dwError, msgBuf );
    LocalFree( msgBuf );
#undef MAX_MSG_BUF_SIZE
}
// end PrintError
// **********************************************************************

// **********************************************************************
// ReadFileWithAlloc - allocates memory for and reads contents of a file
// 
// Params:
//   szFileName   - NULL terminated string specifying file name
//   pdwSize      - address of variable to receive file bytes size
//   ppBytes      - address of pointer which will be allocated and contain file bytes
// 
// Returns: TRUE for success, FALSE for failure.
//
// Notes: Caller is responsible for freeing the memory using GlobalFree()
// 
BOOL ReadFileWithAlloc( LPTSTR szFileName, LPDWORD pdwSize, LPBYTE *ppBytes )
{
    HANDLE      hFile;
    DWORD       dwBytes;
    BOOL        bSuccess = FALSE;

    // Validate pointer parameters
    if( ( pdwSize == NULL ) || ( ppBytes == NULL ) )
        return FALSE;
    // Open the file for reading
    hFile = CreateFile( szFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
    if( hFile == INVALID_HANDLE_VALUE )
    {
        PrintError( GetLastError(), TEXT("CreateFile()") );
        return FALSE;
    }
    // How big is the file?
    *pdwSize = GetFileSize( hFile, NULL );
    if( *pdwSize == (DWORD)-1 )
        PrintError( GetLastError(), TEXT("GetFileSize()") );
    else
    {
        // Allocate the memory
        *ppBytes = (LPBYTE)GlobalAlloc( GPTR, *pdwSize );
        if( *ppBytes == NULL )
            PrintError( GetLastError(), TEXT("Failed to allocate memory\n") );
        else
        {
            // Read the file into the newly allocated memory
            bSuccess = ReadFile( hFile, *ppBytes, *pdwSize, &dwBytes, NULL );
            if( ! bSuccess )
                PrintError( GetLastError(), TEXT("ReadFile()") );
        }
    }
    // Clean up
    CloseHandle( hFile );
    return bSuccess;
}
// End ReadFileWithAlloc
// **********************************************************************

// **********************************************************************
// RawDataToPrinter - sends binary data directly to a printer
// 
// Params:
//   szPrinterName - NULL terminated string specifying printer name
//   lpData        - Pointer to raw data bytes
//   dwCount       - Length of lpData in bytes
// 
// Returns: TRUE for success, FALSE for failure.
// 
BOOL RawDataToPrinter( LPTSTR szPrinterName, LPBYTE lpData, DWORD dwCount )
{
    HANDLE     hPrinter;
    DOC_INFO_1 DocInfo;
    DWORD      dwJob;
    DWORD      dwBytesWritten;

    // Need a handle to the printer.
    if( ! OpenPrinter( szPrinterName, &hPrinter, NULL ) )
    {
        PrintError( GetLastError(), TEXT("OpenPrinter") );
        return FALSE;
    }

    // Fill in the structure with info about this "document."
    DocInfo.pDocName = TEXT("My Document");
    DocInfo.pOutputFile = NULL;
    DocInfo.pDatatype = TEXT("RAW");
    // Inform the spooler the document is beginning.
    if( (dwJob = StartDocPrinter( hPrinter, 1, (LPBYTE)&DocInfo )) == 0 )
    {
        PrintError( GetLastError(), TEXT("StartDocPrinter") );
        ClosePrinter( hPrinter );
        return FALSE;
    }
    // Start a page.
    if( ! StartPagePrinter( hPrinter ) )
    {
        PrintError( GetLastError(), TEXT("StartPagePrinter") );
        EndDocPrinter( hPrinter );
        ClosePrinter( hPrinter );
        return FALSE;
    }
    // Send the data to the printer.
    if( ! WritePrinter( hPrinter, lpData, dwCount, &dwBytesWritten ) )
    {
        PrintError( GetLastError(), TEXT("WritePrinter") );
        EndPagePrinter( hPrinter );
        EndDocPrinter( hPrinter );
        ClosePrinter( hPrinter );
        return FALSE;
    }

    /*********************************/
    // CODE USED TO READ THE PRINTER
    LPBYTE retData = NULL;
    LPDWORD bbr = NULL;

    if(ReadPrinter(hPrinter, retData, 1, bbr))
    {
        printf("OUT : %i", retData);
    }
    else
    {
        printf("Failed to read printer");
    }
    /*********************************/

    // End the page.
    if( ! EndPagePrinter( hPrinter ) )
    {
        PrintError( GetLastError(), TEXT("EndPagePrinter") );
        EndDocPrinter( hPrinter );
        ClosePrinter( hPrinter );
        return FALSE;
    }
    // Inform the spooler that the document is ending.
    if( ! EndDocPrinter( hPrinter ) )
    {
        PrintError( GetLastError(), TEXT("EndDocPrinter") );
        ClosePrinter( hPrinter );
        return FALSE;
    }
    // Tidy up the printer handle.
    ClosePrinter( hPrinter );
    // Check to see if correct number of bytes were written.
    if( dwBytesWritten != dwCount )
    {
        //printf( TEXT("Wrote %d bytes instead of requested %d bytes.\n"), dwBytesWritten, dwCount );
        return FALSE;
    }
    return TRUE;
}
// End RawDataToPrinter
// **********************************************************************

int main( int argc, char* argv[] )
{
    LPBYTE  pBytes = NULL;

    int textSize = 2;

    DWORD   dwSize = textSize;

    pBytes = (LPBYTE) malloc (textSize*sizeof(BYTE));

    pBytes[0] = 0x1B;
    pBytes[1] = 0x6A;


    if( ! RawDataToPrinter(L"EPSON PLQ-20 ESC/P2", pBytes, dwSize) )
        printf("Failed to send data to printer.\n" );
    else
        printf("Data sent to printer.\n" );

    free(pBytes);
    return 0;
}
// end main
// **********************************************************************

谢谢!

【问题讨论】:

  • 几个问题: 1. 您想从打印机获取哪些信息? 2. 您是否将打印机设置为使用直接打印而不是后台打印? 3. 你知道这台打印机响应什么转义命令吗?每台打印机都不同。
  • 1.我必须管理不同的错误才能向用户显示消息。至少,我会知道打印机是否处于错误状态,以便能够显示消息并从计算机重置/重新初始化打印机。 2.不知道如何设置直接打印。 3. 本打印机响应 ESC/P 转义命令(这里有指南:support.epson.ru/products/manuals/000786/plq20pg_e.pdf

标签: c++ winapi printing epson dot-matrix


【解决方案1】:

Epson PLQ-20product brochure 表示打印机支持 Olivetti PR2E、Epson ESC/P2、Wincor 4915、IBM PPDS、IBM 4722 FP 仿真。

看起来您正在使用ESC/P2 命令,但是在快速搜索后我找不到任何命令来读取打印机的当前状态。

ESC/P2 参考文献

根据以上参考,控制出纸方式的命令是ESC EM

【讨论】:

  • 好的我没有注意到打印机可以理解不同的命令,我没有注意到代码不同。我尝试了 [this](support.epson.ru/products/manuals/000786/plq20pg_e.pdf) 编程指南中提到的代码,这些代码是 Olivetti PR2E 代码,但我不知道如何通知打印机哪组代码我正在使用,但我会这样搜索。
  • 我找到了如何设置必须将哪些代码发送到打印机(这是从打印机的控制面板设置的参数,而不是通过编程设置)。所以,这个解决方案不适合我。 @stukelly,你是对的,没有办法使用任何 ESC/P2 命令获取打印机状态。我将您的答案设置为已接受,因为它似乎没有任何解决方案。
  • 我认为我的回答可能是错误的,阅读您的链接后,当打印机处于 [PR2]、[PR54+] 或[PR40+] 模式。您是否尝试过使用其中一种模式?
  • 对不起,我还没有看到你的帖子。它可能会起作用,但操作员必须在每台打印机上手动更改此模式。有数百台这样的打印机,所以这不是一个好的解决方案。
猜你喜欢
  • 2020-09-22
  • 1970-01-01
  • 2017-07-16
  • 2018-03-18
  • 1970-01-01
  • 2016-12-01
  • 2014-09-12
  • 2010-10-05
  • 2011-11-11
相关资源
最近更新 更多