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;
  • 相关阅读:
    ie下table无法设置宽度的坑,解决方案:在td里面添加div把td宽度撑开即可。
    js simple drag.
    javascript事件捕获机制,dom tree
    WPF,布局,Menu,MenuItem,DockPanel,Grid,DockPanel.Dock='',ToolBar,Content,Image,Uri
    .net IntPtr ==interoperable pointer
    Why do I keep getting mixed tabs and spaces in a Visual Studio C# code window?[vs power tools issue transfered]
    vs nuget package control.
    Introduction to the WinPcap Networking Libraries
    读懂这一篇,集群节点不下线
    函数组合的 N 种模式
  • 原文地址:https://www.cnblogs.com/lzl_17948876/p/3387442.html
Copyright © 2011-2022 走看看