2014-11-08 66 views
0

编辑这个问题已经收到了一些downvotes。我没有给过)。德尔福打印到通用文本驱动程序(Intermec PM4i)?

我有Intermec PM4i标签打印机和通用文本打印驱动程序。我能够从记事本或Delphi打印文本文件脚本调用ShellExecute('printto',..)shellapi函数。

我发现几个原始打印的例子,但没有工作。 Delphi应用程序如何在没有shellapi函数的情况下打印到Generic_text_driver?这不是GDI printer.canvas功能的驱动程序。

我已经尝试过“所有”甚至是传统的PASSTHROUGH打印示例。只有工作方法是Notepad.exe或shellexecute('printto','tempfile.txt',...),我猜是内部使用记事本。我可以看到记事本打印对话框在屏幕上闪烁。我想直接从Delphi应用程序中进行控制。

此printFileToGeneric不起作用。

// https://groups.google.com/forum/#!topic/borland.public.delphi.winapi/viHjsTf5EqA 
Procedure PrintFileToGeneric(Const sFileName, printerName, docName: string; ejectPage: boolean); 
Const 
    BufSize = 16384; 
Var 
    Count : Integer; 
    BytesWritten: DWORD; 
    hPrinter: THandle; 
    DocInfo: TDocInfo1; 
    f: file; 
    Buffer: Pointer; 
    ch: Char; 
Begin 
    If not WinSpool.OpenPrinter(PChar(printerName), hPrinter, nil) Then 
    raise Exception.Create('Printer not found'); 

    Try 
    DocInfo.pDocName := PChar(docName); 
    DocInfo.pOutputFile := nil; 
    DocInfo.pDatatype := 'RAW'; 
    If StartDocPrinter(hPrinter, 1, @DocInfo) = 0 Then 
     Raise Exception.Create('StartDocPrinter failed'); 

    Try 
     If not StartPagePrinter(hPrinter) Then 
     Raise Exception.Create('StartPagePrinter failed'); 

     System.Assign(f, sFileName); 
     Try 
     Reset(f, 1); 
     GetMem(Buffer, BufSize); 
     Try 
      While not eof(f) Do Begin 
      Blockread(f, Buffer^, BufSize, Count); 
      If Count > 0 Then Begin 
       If not WritePrinter(hPrinter, Buffer, Count, BytesWritten) Then 
       Raise Exception.Create('WritePrinter failed'); 
      End; 
      End; 
     Finally 
      If ejectPage Then Begin 
      ch:= #12; 
      WritePrinter(hPrinter, @ch, 1, BytesWritten); 
      End; 
      FreeMem(Buffer, BufSize); 
     End; 
     Finally 
     EndPagePrinter(hPrinter); 
     System.Closefile(f); 
     End; 
    Finally 
     EndDocPrinter(hPrinter); 
    End; 
    Finally 
    WinSpool.ClosePrinter(hPrinter); 
    End; 
End; 

以下prtRaw helper util示例不起作用。

prtRaw.StartRawPrintJob/StartRawPrintPage/PrintRawData/EndRawPrintPage/EndRawPrintJob 
http://www.swissdelphicenter.ch/torry/showcode.php?id=940 

以下AssignPrn方法不起作用。

function testPrintText(params: TStrings): Integer; 
var 
    stemp:String; 
    idx: Integer; 
    pOutput: TextFile; 
begin 
    Result:=0;  
    idx := getPrinterIndexByName(params.Values['printer']); 
    if (idx<0) then Raise Exception.Create('Printer not found'); 
    WriteLn('Use printer(text) ' + IntToStr(idx) + ' ' + Printer.Printers[idx]); 

    Printer.PrinterIndex := idx; 
    stemp := params.Values['jobname']; 
    if (stemp='') then stemp:='rawtextprint'; 
    Printer.Title:=stemp; 

    AssignPrn(pOutput); 
    ReWrite(pOutput); 

    stemp := 'INPUT ON'+#10; 
    stemp := stemp + 'NASC 1252'+#10; 
    stemp := stemp + 'BF OFF'+#10; 
    stemp := stemp + 'PP 30,480:FT "Swiss 721 BT",8,0,100'+#10; 
    stemp := stemp + 'PT "Test text 30,480 position ABC'+#10; 
    Write(pOutput, stemp); 
    //Write(pOutput, 'INPUT ON:'); 
    //Write(pOutput, 'NASC 1252:'); 
    //Write(pOutput, 'BF OFF:'); 
    //Write(pOutput, 'PP 30,480:FT "Swiss 721 BT",8,0,100:'); 
    //Write(pOutput, 'PT "Test text 30,480 position ABC":'); 
    //Write(pOutput, 'Text line 3 goes here#13#10'); 
    //Write(pOutput, 'Text line 4 goes here#13#10');  

    CloseFile(pOutput); 
end; 

这Printer.Canvas没有打印任何东西,因为记事本内部使用GDI打印输出它应该有打印的东西。这里缺少一些东西。

function testPrintGDI(params: TStrings): Integer; 
var 
    filename, docName:String; 
    idx: Integer; 
    lines: TStrings; 
begin 
    Result:=0; 
    idx := getPrinterIndexByName(params.Values['printer']); 
    if (idx<0) then Raise Exception.Create('Printer not found'); 
    WriteLn('Use printer(gdi) ' + IntToStr(idx) + ' ' + Printer.Printers[idx]); 
    docName := params.Values['jobname']; 
    if (docName='') then docName:='rawtextprint'; 

    filename := params.values['input']; 
    If Not FileExists(filename) then Raise Exception.Create('input file not found'); 

    Printer.PrinterIndex := idx; 
    Printer.Title := docName; 
    Printer.BeginDoc; 
    lines := readTextLines(filename); 
    try 
    for idx := 0 to lines.Count-1 do begin 
     Printer.Canvas.TextOut(10, 10*idx, lines[idx]); 
    end; 
    finally 
    FreeAndNil(lines); 
    Printer.EndDoc; 
    end; 
end; 

工作只有三个方法都是从Notepad.exe的,德尔福的ShellExecute调用打印或打开一个原始TCP套接字将IP:端口地址和写文本行到套接字的OutputStream。

function testPrintPrintTo(params: TStrings): Integer; 
var 
    filename, printerName:String; 
    idx: Integer; 
    exInfo: TShellExecuteInfo; 
    device,driver,port: array[0..255] of Char; 
    hDeviceMode: THandle; 
    timeout:Integer; 
    //iRet: Cardinal; 
begin 
    Result:=0; 

    idx := getPrinterIndexByName(params.Values['printer']); 
    if (idx<0) then Raise Exception.Create('Printer not found'); 
    WriteLn('Use printer(printto) ' + IntToStr(idx) + ' ' + Printer.Printers[idx]); 

    filename := params.values['input']; 
    If Not FileExists(filename) then Raise Exception.Create('input file not found'); 
    filename := uCommon.absoluteFilePath(filename); 

    Printer.PrinterIndex := idx; 
    Printer.GetPrinter(device, driver, port, hDeviceMode); 
    printerName := Format('"%s" "%s" "%s"', [device, driver, port]); 

    FillChar(exInfo, SizeOf(exInfo), 0); 
    with exInfo do begin 
    cbSize := SizeOf(exInfo); 
    fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_DDEWAIT; 
    Wnd := 0; 
    exInfo.lpVerb := 'printto'; 
    exInfo.lpParameters := PChar(printerName); 
    lpFile := PChar(filename); 
    lpDirectory := nil; 
    nShow := SW_HIDE; 
    end; 
    WriteLn('printto ' + printerName); 

    if Not ShellExecuteEx(@exInfo) then begin 
    Raise Exception.Create('ShellExecuteEx failed'); 
    exit; 
    end; 

    try 
    timeout := 30000; 
    while WaitForSingleObject(exInfo.hProcess, 50) <> WAIT_OBJECT_0 do begin 
     Writeln('wait timeout ' + IntToStr(timeout)); 
     dec(timeout, 50); 
     if (timeout<1) then break; 
    end; 
    finally 
    CloseHandle(exInfo.hProcess); 
    end; 

    {iRet:=ShellExecute(0, 'printto', 
     PChar(filename), 
     PChar(printerName), //Printer.Printers[idx]), 
     nil, //PChar(filepath), 
     SW_HIDE // SW_SHOWNORMAL 
); 
    Writeln('printto return code ' + IntToStr(iRet)); // >32 OK } 

end; 
+0

记事本打印到GDI打印机 – 2014-11-08 07:35:54

+0

所以我可以使用Printer.Canvas.TextOut( '...')德尔福功能generictext驱动程序(易腾迈PM4i标签打印机)可能。不调用任何图形绘制函数可能会尽可能简化。一旦回到办公室就会试试这个。 – Whome 2014-11-08 07:58:17

回答

0

您可以从记事本打印到此打印机。记事本使用标准的GDI机制打印。如果记事本可以做到这一点,那么你也可以。使用Printer.BeginDoc,Printer.Canvas等打印到此打印机。

+0

我使用打印机组件Printer.BeginDoc/Printer.Canvas.TextOut('test print')/ Printer.EndDoc从Delphi测试了这个。没有打印。记事本使用generictext打印驱动程序做一些额外的技巧。我放弃并实现了一个原始的tcp套接字到printerIP:9100,并手动发送专有的FingerPrint + DirectProtocol命令。 – Whome 2014-11-10 08:16:36

+0

记事本没有做任何额外的技巧。这只是一台GDI打印机。我真的无法想象你还在寻找什么。这听起来好像你不需要建议,并希望按照你的方式去做。在这种情况下,为什么要问? – 2014-11-10 23:37:22

+0

Whoohaa,为什么这种敌意?正如你可以看到我已经广泛尝试并提供了所有示例代码。你们中有些人可能会觉得它很有价值它就是这样,(Delphi)Printer.canvas没有通过generictext驱动程序工作。记事本确实通过相同的驱动程序工作。我通过一个原始套接字11.22.33.44:9100提交相同的文本文件,它的工作原理。当然,我错过了delphi代码中的一部分,但无法弄清楚。你已经试过这种标签打印机? – Whome 2014-11-11 08:25:35

0

您可以使用此过程: 其中LabelFile是,我们正在使用此代码标签文件的完整路径,并使用通用文本打印机驱动程序的工作原理和打印机设置为默认打印机。 它适用于斑马打印机和Windows XP操作系统。

我希望这会帮助你。

function PrintLabel(LabelName: String): Boolean; 
var 
    EfsLabel,dummy: TextFile; 
    ch : Char; 
begin 
try 
try 
    Result:= False; 
    AssignFile(EfsLabel,LabelName); 
    Reset(EfsLabel); 
    Assignprn(dummy); 
    ReWrite(Dummy); 

    While not Eof(EfsLabel) do 
    begin 
    Read(EfsLabel, Ch); 
    Write(dummy, Ch); 
    end; 

    Result:= True; 

except 
    Result:=False; 
    LogMessage('Error Printing Label',[],LOG_ERROR); 
end; 

finally 
CloseFile(EfsLabel); 
CloseFile(dummy); 
end; 

end; 
+0

如果这应该有帮助,请重新格式化您的代码(缩进!)或很难查看。 – Markus 2014-12-25 12:14:24

+0

我希望现在可以读取代码! – 2014-12-25 13:31:08