如何使用 Flutter Dart 的 Win32 包读取 Boca 打印机状态

问题描述 投票:0回答:1

描述

这里我需要实现打印机和应用程序之间的双向通信。

  1. 阅读

到目前为止,我可以使用winspool API 的func writePrinter 在打印机中进行写入。我面临的问题是针对 readPrinter

打开打印机的代码

   final alloc = Arena();
   final pPrinterName = printerName.toNativeUtf16(allocator: alloc);
   final pWritePrinterHandle = alloc<HANDLE>();
   final pDefault = alloc<PRINTER_DEFAULTS>()
      ..ref.pDatatype = nullptr
      ..ref.pDevMode = nullptr
      ..ref.DesiredAccess = PRINTER_ALL_ACCESS;

   // Open Printer
   var fSuccess = OpenPrinter(pPrinterName, pWritePrinterHandle, pDefault);
   if (fSuccess == 0) {
      final error = GetLastError();
      throw Exception('OpenPrint error, status: $fSuccess, error: $error');
   }

向打印机发送命令的代码

   final pDocInfo = alloc<DOC_INFO_1>()
      ..ref.pDocName =
          'Boca Systems Communicator'.toNativeUtf16(allocator: alloc)
      ..ref.pDatatype =
          'RAW'.toNativeUtf16(allocator: alloc) // RAW, TEXT or XPS_PASS
      ..ref.pOutputFile = nullptr;

    //https://learn.microsoft.com/windows/win32/printdocs/startdocprinter
    var fStartDocJobId =
        StartDocPrinter(pWritePrinterHandle.value, 1, pDocInfo);
    if (fSuccess == 0) {
      final error = GetLastError();
      throw Exception(
          'StartDocPrinter error, status: $fSuccess, error: $error');
    }

    var fStartPrintSuccess = StartPagePrinter(pWritePrinterHandle.value);

    // Print Row Data
    String dataToPrint = '<S92>';
    final cWritten = alloc<DWORD>();
    final data = dataToPrint.toNativeUtf8(allocator: alloc);

    final writeSuccess = WritePrinter(
        pWritePrinterHandle.value, data, dataToPrint.length, cWritten);

    if (dataToPrint.length != cWritten.value) {
      final error = GetLastError();
      throw Exception(
          'WritePrinter error, status: $writeSuccess, error: $error');
    }

读取打印机的代码

  final printerJobName = '$printerName, Job $fStartDocJobId';
  final Completer<void> completer = Completer<void>();

  final pReadPrinterHandle = alloc<HANDLE>();
  final pReadDefault = alloc<PRINTER_DEFAULTS>()
    ..ref.pDatatype = nullptr
    ..ref.pDevMode = nullptr
    ..ref.DesiredAccess = PRINTER_USE_ACCESS;

  final openPrinterDetailName = printerJobName.toNativeUtf16(allocator: alloc);

  // Open Printer for Reading
  var fReadOpenSuccess =
      OpenPrinter(openPrinterDetailName, pReadPrinterHandle, pReadDefault);
  if (fReadOpenSuccess == 0) {
    final error = GetLastError();
    throw Exception(
        'Read OpenPrint error, status: $fReadOpenSuccess, error: $error, openPrinterDetailName $printerJobName');
  }

  final readBufferSize = 1024;
  final pReadData = alloc<Uint8>(readBufferSize);
  final bytesRead = alloc<Uint32>();

  final readSuccess = ReadPrinter(
      pReadPrinterHandle.value, pReadData, readBufferSize, bytesRead);

  if (readSuccess == 0) {
    final error = GetLastError();
    throw Exception('ReadPrinter error, status: $readSuccess, error: $error');
  }
  // Process the read data
  final readData = pReadData.cast<Utf8>().toDartString();

在上面的代码块中,ReadPrinter也没有被执行,也没有抛出错误。

Winspool Dart API 参考

flutter dart winapi thermal-printer
1个回答
0
投票
// Open the printer for reading using the port name (e.g., "USB001, Port"), it is required to add the ", Port" keyword as a postfix.
 
int openReadPrinter() {
    final Pointer<Utf16> pPortName = portName.toNativeUtf16();
    final success = OpenPrinter(pPortName, readPrinterHandle, nullptr);
    if (success == 0) {
        final error = GetLastError();
        throw Exception('OpenPrint Read error, status: $success, error: $error');
    }
    return success;
}

// Function to read from the printer
String readFromPrinter(Pointer readPrinterHandle) {
    const readBufferSize = 1024;
    final pReadData = alloc<Uint8>(readBufferSize);
    final bytesRead = alloc<Uint32>();
    final success =
        ReadPrinter(readPrinterHandle, pReadData, readBufferSize, bytesRead);
    
    if (success == 0) {
        final error = GetLastError();
        throw Exception("Read from printer failed. Error: $error");
    } else {
        return pReadData.cast<Utf8>().toDartString();
    }
}

在上面的代码中:

  • openReadPrinter
    功能打开打印机以使用指定的端口名称 (portName) 进行读取。如果成功,则返回一个非零值;否则,它会抛出带有错误详细信息的异常。
  • 包含针对
    ReadPrinter
    无法从打印机读取数据的情况的错误处理,提供有关遇到的错误的信息。

此代码演示了如何使用 winspool API 在 Dart 中实现应用程序和打印机之间的双向通信。

© www.soinside.com 2019 - 2024. All rights reserved.