zoukankan      html  css  js  c++  java
  • 通过驱动向打印机发送一段(ESC)控制指令

    这个功能看起来挺奇葩的, 写这个是因为有客户在使用驱动连接票据打印机, 但是又要开钱箱, 驱动里只能每张单据都开钱箱, 而这个打印机又不是只打印结帐单

    所以就需要用软件控制打印机开钱箱

    票据打印机一般都支持ESC/POS指令, 所以就出现了如下代码, 通过这个函数可以吧ESC/POS指令里的开钱箱指令发送给打印机控制开钱箱

    同样, 也可以发送别的什么东西, 比如响响蜂鸣器之类的

    哦 补充下, 这个代码里使用的是默认打印机, 当然稍微改动下, 就可以先弹出个打印机列表, 然后选择打印机传进去, 这样就可以控制任意打印机了

    OpenPrinter(PChar(Printer.Printers[0]), nD, nPPD);
    uses
        WinSpool, Printers;
    
    
    function WritePrtDataForDriver(AData: string; var AErrCode: Byte): Boolean;
    var
      nD: Cardinal;
      nPPD: PPrinterDefaults;
      nDocInfo: DOC_INFO_1;
      nDataLength: DWORD;
      nSize: DWORD;
      nReturn: Boolean;
    begin
      Result := False;
    
      AErrCode := 1;
      nD := INVALID_HANDLE_VALUE;
      nPPD := New(PPrinterDefaults);
      try
        with nPPD^ do
        begin
          DesiredAccess := PRINTER_ACCESS_USE;
          pDatatype := nil;
          pDevMode := nil;
        end;
        OpenPrinter(PChar(Printer.Printers[0]), nD, nPPD);
      finally
        Dispose(nPPD);
      end;
      if nD = INVALID_HANDLE_VALUE  then
        Exit;
    
      with nDocInfo do
      begin
        pDocName := 'Print Document';
        pOutputFile := nil;
        pDatatype := 'RAW';
      end;
      AErrCode := 2;
      if StartDocPrinter(nD, 1, @nDocInfo) <= 0 then
        Exit;
      AErrCode := 3;
      if not StartPagePrinter(nD) then
        Exit;
      AErrCode := 4;
      nDataLength := Length(AData);
      nReturn := WritePrinter(nD, PChar(AData), nDataLength, nSize);
      if (not nReturn) or (nSize <> nDataLength) then
        Exit;
      AErrCode := 5;
      if not EndPagePrinter(nD) then
        Exit;
      AErrCode := 6;
      if not EndDocPrinter(nD) then
        Exit;
    
      AErrCode := 7;
      if not ClosePrinter(nD) then
        Exit;
    
      AErrCode := 0;
      Result := True;
    end;

    附: 获取驱动打印机状态:

    var
      i: Integer;
      nPRH: THandle;
      PrinterName:String;
      nBuff: array[0..8192] of Char;
      nSize: DWord;
      pInfo: PPrinterInfo2;
    begin
      Memo1.Lines.Clear;
      for i := 0 to Printer.Printers.Count - 1 do
      begin
        if OpenPrinter(PChar(Printer.Printers[i]), nPRH,nil) then
        begin
          if GetPrinter(nPRH, 2, @nBuff, SizeOf(nBuff), @nSize) then
          begin
            pInfo:=PPrinterInfo2(@nBuff);
            Memo1.Lines.Add('Device := ' + Printer.Printers[i]);
            Memo1.Lines.Add('Status := ' + inttostr(pInfo.Status));
            Memo1.Lines.Add('');
          end;
        end;
        ClosePrinter(nPRH);
      end;
    end;
  • 相关阅读:
    tmp
    【ask】ghost分区还原win7出现蓝屏,试图加载CLASSPNP驱动时出现
    手动编译svn
    【ask】Recursive process.nextTick detected. This will break in the next version of node. Please use setImmediate for recursive deferral.
    c++11小计
    入门系列-ABP CLI
    入门系列-参数验证集成
    入门系列-异常处理
    .NET Core 控制台启动失败“以一种访问权限不允许的方式做了一个访问套接字的尝试”
    入门系列-虚拟文件系统
  • 原文地址:https://www.cnblogs.com/lzl_17948876/p/3387442.html
Copyright © 2011-2022 走看看