segunda-feira, 10 de janeiro de 2011

Enviando caracteres diretamente ao buffer da impressora

Ao trabalharmos com impressão, em certos casos desejamos alterar o comportamento da impressora.

Algumas opções, principalmente em impressoras matriciais, são obtidas através do envio dos chamados "códigos de escape" para a impressora (por exemplo, alterar espaçamento entre as linhas (#45), tipo de fonte (#18, #23), etc). Em versões 16-bit do Windows, isso não era complicado, mas agora, nas versões 32-bit, o acesso direto ao hardware não é mais possível.

Portanto, para enviarmos caracteres diretamente a impressora, devemos utilizar o "escape" chamado "PASSTHROUGH" do Windows e enviarmos a informação desejada diretamente.

Na documentação do Win32 SDK este escape é dado como obsoleto, mas enquanto utilizarmos impressoras matriciais que necessitem de "códigos escape" para certas funcionalidades, ele será necessário.

Ao utilizar impressoras Postscript tenha cuidado, pois nem sempre esta técnica irá funcionar. Em impressoras matriciais, você pode enviar qualquer tipo de caracteres que achar necessário.

Abaixo segue um código exemplificando o envio de uma string qualquer diretamente ao buffer da impressora:

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

uses Printers;

type
{ Tipo requerido pelo PASSTHROUGH }
TBufferImpressora = record
TamanhoBuffer: Word;
Buffer: array [0..255] of Char;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
       Buff: TBufferImpressora;
       TestePasstrough: Integer;
       strFoo: string;
begin
{ Primeiro devemos checar se o "escape" PASSTHROUGH é suportado. Para isso, executamos a função "Escape" passando o QUERYESCSUPPORT. Caso o driver suporte, ela irá retornar um valor maior que 0 }
       TestePasstrough := PASSTHROUGH;
       if Escape(Printer.Handle, QUERYESCSUPPORT, SizeOf(PASSTHROUGH), @TestePasstrough, nil) > 0 then
       begin
                   { Inicializamos o driver }
                   Printer.BeginDoc;
                   { Informação qualquer a enviar diretamente para a impressora }
                   strFoo := 'Passthrough string';
                   { Copia da string para a estrutura }
                   StrPCopy(Buff.Buffer, strFoo);
                   { Indicamos o tamanho da informação}
                   Buff.TamanhoBuffer := StrLen(Buff.Buffer);
                   { Enviamos o "escape" }
                   Escape(Printer.Canvas.Handle, PASSTHROUGH, 0, @Buff,nil);
                  { Descarregamos... }
                  Printer.EndDoc;
       end;
end;

end.

Nenhum comentário:

Postar um comentário