2011-05-09 5 views
2

확인은, 여기에 내가 그것을 할 방법 :프린터로 직접 명령을 보내는 올바른 방법!

그러나
function PrintRawData(hPrn : THandle; 
         Buffer : pointer; 
         NumBytes : SpoolInt) : integer; 
{$IFDEF WIN32} 
var 
    BytesWritten : DWORD; 
{$ENDIF} 
begin 
    NumBytes := NumBytes * 2; //<-- I added this line 
    ... 

, 뭔가가 일부 명령 (이스케이프 시퀀스) 돈으로 잘못 :

또한
procedure TMainWindow.btnRawPrintClick(Sender: TObject); 
begin 
    BeginPrint; 
    SendStr(#27#69); 
    SendStr('MyData'); 
    SendStr(#10); 
    EndPrint; 
end; 

procedure TMainWindow.SendStr(Text: String); 
var 
    i: Integer; 
    data : Array of Char; 
begin 
    for i := 1 to Length(Text) do 
    begin 
    SetLength(data,i); 
    data[Pred(i)] := Text[i]; 
    end; 

    if (PrintRawData(printHandle, 
        data, 
        Length(data)) < 0) then begin 
    ShowMessage('PrintRawData Failed'); 
    EndRawPrintPage(printHandle); 
    EndRawPrintJob(printHandle); 
    exit; 
    end; 
end; 

procedure TMainWindow.BeginPrint; 
begin 
    printHandle := StartRawPrintJob('EPSON TM-T70 Receipt','ESDPRT001','Test Document'); 

    if printHandle < 0 then 
    begin 
    ShowMessage('StartRawPrintJob Failed!'); 
    exit; 
    end; 

    if (StartRawPrintPage(printHandle) < 0) then begin 
    ShowMessage('StartRawPrintPage Failed!'); 
    EndRawPrintJob(printHandle); 
    exit; 
    end; 
end; 

procedure TMainWindow.EndPrint; 
begin 
    if (EndRawPrintPage(printHandle) < 0) then begin 
    ShowMessage('EndRawPrintPage Failed'); 
    EndRawPrintJob(printHandle); 
    exit; 
    end; 

    if (EndRawPrintJob(printHandle) < 0) then begin 
    ShowMessage('EndRawPrintJob Failed'); 
    exit; 
    end; 
end; 

은 내가 here에서했다 약간의 코드를 변경 예상대로 작동하지 않습니다!

+1

어떻게 프린터에 코드를 얻고있다? 직접 LPT1 : 또는 다른 방법? 프린터 디버그 모드를 활성화하여 송신중인 헥스를 확인 했습니까? – mj2008

+0

'ESC'대신에 무엇을 보냅니 까? 대부분의 오래된 Epson 프린터의 경우 ASCII 문자 # 27입니다. –

+0

예, 저는 ESC 대신 # 27을 보냅니다. 명령을 보내기 위해 win API WritePrinter 함수를 사용합니다! – Peacelyk

답변

6

잘못된 기능을 사용하고 있습니다. Escape을 사용하고 두 번째 매개 변수로 PASSTHROUGH 플래그를 전달하십시오. 그러면 원시 처리되지 않은 이스케이프 코드가 프린터로 직접 전송됩니다.

Joe Hecht (이전의 Borland)는이 작업을 쉽게 수행 할 수 있도록 여러 번 게시했습니다. 여기서 unit PrtRaw을 찾았습니다.

+0

게시물을 제공해 주셔서 감사합니다. 내 게시물을 업데이트하고 코드를 추가했습니다. 그러나, 나는 두 번째 매개 변수로 통과 명령을 전달 이해하지 않습니다. 두 번째 매개 변수는 어떤 기능을합니까? 좀 더 설명해 주시겠습니까? – Peacelyk

+0

Ken, Peacelyk은 ['Escape'] (http : // msdn.microsoft.com/en-us/library/dd162701.aspx) Windows API 함수입니다. –

+0

@Peacelyk : 죄송합니다. 나는 원래의 대답으로 MSDN의 Escape 링크를 제공하는 것을 잊었다. 나는 그것을 지금 새롭게했다. –

3

Ansi 문자와 Unicode 문자 사이의 변경으로 인해 현재 코드가 잘못된 형식으로 프린터로 데이터를 보내고 있습니다. 사용중인 프린터는 분명히 일부 오류를 허용 할 수 있으므로 명령의 일부가 작동하는 이유가 있지만 한계가 있습니다. 델파이의 버전에

, Char 그래서 대신 AnsiChar를 사용하도록 Char 코드를 변경, 그래서 프린터가 예상대로, 1 바이트 문자를 보낼 수 WideChar에 해당합니다. 이전에 PrintRawData 함수를 사용해도 문제가 없었습니다. 당신의 변화가 잘못되었습니다. 프린터는 2 바이트 유니 코드 문자를 수신 할 것으로 기대하지는 않지만 사용자가 변경 한 양입니다.

원래 PrintRawData 코드를 복원 한 후,이에 SendStr 기능을 변경 :

procedure TMainWindow.SendStr(const Text: string); 
var 
    data: AnsiString; 
begin 
    data := Text; 

    if (PrintRawData(printHandle, 
        PAnsiChar(data), 
        Length(data)) < 0) then begin 
    ShowMessage('PrintRawData Failed'); 
    EndRawPrintPage(printHandle); 
    EndRawPrintJob(printHandle); 
    end; 
end; 

내가 코드를 다음과 같이 변경했다 :

  1. AnsiString으로 Char 배열을 교체합니다.
  2. 루프를 사용하여 한 번에 한 문자 씩 데이터 배열을 늘리는 대신 단일 할당 문을 사용하여 유니 코드 대 Ansi 변환을 수행하고 RTL에서 변환을 처리하도록합니다.
  3. PrintRawData으로 전달하기 위해 데이터 문자열을 PAnsiChar으로 유형 변환합니다.
  4. 내용을 수정해야하는 경우가 아니면 const로 문자열 매개 변수를 전달하십시오.
  5. 함수가 이미 완료된 경우 명시적인 exit 문을 사용할 필요가 없습니다.
+0

소설적인 포인트 : 라인 데이터에 주석을 달고 싶습니다 : = 잠재적으로 손실이있는 변환이기 때문에 "유니 코드에서 ansi 로의 변환"이라고하는 텍스트. –

0
Procedure StrLstYazdir(pYazilacakListe: TStringList; pYazici: String); 
var 
    hPrn: THandle; 
    yazilacakVeri: AnsiString; 
    intA: Integer; 
begin 
    hPrn := StartRawPrintJob(PChar(pYazici), '', 'Varakim'); 
    if (Integer(hPrn) < 0) then 
    Begin 
    ShowMessage('StartRawPrintJob Hatalı'); 
    Exit; 
    End; 

    if (StartRawPrintPage(hPrn) < 0) then 
    Begin 
    ShowMessage('StartRawPrintPage Hatalı'); 
    EndRawPrintJob(hPrn); 
    Exit; 
    end; 

    For intA := 0 to pYazilacakListe.Count - 1 do 
    Begin 
    yazilacakVeri := pYazilacakListe[intA] + #13 + #10; 

    if (PrintRawData(hPrn, PAnsiChar(yazilacakVeri), Length(yazilacakVeri)) < 0) 
    then 
    begin 
     ShowMessage('PrintRawData Hatalı'); 
     EndRawPrintPage(hPrn); 
     EndRawPrintJob(hPrn); 
     Exit; 
    End; 
    End; 
    if (EndRawPrintPage(hPrn) < 0) then 
    begin 
    ShowMessage('EndRawPrintPage Hatalı'); 
    EndRawPrintJob(hPrn); 
    Exit; 
    End; 

    if (EndRawPrintJob(hPrn) < 0) then 
    begin 
    ShowMessage('EndRawPrintJob Hatalı'); 
    Exit; 
    End; 
End; 

사용법 :

StrLstYazdir(Memo1.Lines ,'Lexmark Forms Printer 2491') 
+2

이 코드는 문제를 해결할 수 있지만 현재와 미래의 독자에게는 몇 가지 설명이 도움이 될 것입니다. – Thom

관련 문제