Под Win16 Вы можете использовать функцию SpoolFile, или Passthrough escape, если принтер поддерживает последнее. Под Win32 Вы можете использовать WritePrinter. Ниже пример открытия принтера и записи чистого потока данных в принтер. Учтите, что Вы должны передать корректное имя принтера, такое, как "HP LaserJet 5MP", чтобы функция сработала успешно. Конечно, Вы можете включать в поток данных любые необходимые управляющие коды, которые могут потребоваться. uses WinSpool;
procedure WriteRawStringToPrinter(PrinterName:String; S:String); var Handle: THandle; N: DWORD; DocInfo1: TDocInfo1; begin if not OpenPrinter(PChar(PrinterName), Handle, nil) then begin ShowMessage('error ' + IntToStr(GetLastError)); Exit; end; with DocInfo1 do begin pDocName := PChar('test doc'); pOutputFile := nil; pDataType := 'RAW'; end; StartDocPrinter(Handle, 1, @DocInfo1); StartPagePrinter(Handle); WritePrinter(Handle, PChar(S), Length(S), N); EndPagePrinter(Handle); EndDocPrinter(Handle); ClosePrinter(Handle); end;
procedure TForm1.Button1Click(Sender: TObject); begin WriteRawStringToPrinter('HP', 'Test This'); end; Посмотри и доделай как тебе надо. unit TextPrinter;
interface
uses Windows, Controls, Forms, Dialogs;
type TTextPrinter = class(TObject) private FNumberOfBytesWritten: Integer; FHandle: THandle; FPrinterOpen: Boolean; FErrorString: PChar; procedure SetErrorString; public constructor Create; procedure Write(const Str: string); procedure WriteLn(const Str: string); destructor Destroy; override; published property NumberOfBytesWritten: Integer read FNumberOfBytesWritten; end;
implementation
{TTextPrinter}
constructor TTextPrinter.Create; begin FHandle := CreateFile('LPT1', GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); if FHandle = INVALID_HANDLE_VALUE then begin SetErrorString; raise Exception.Create(FErrorString); end else FPrinterOpen := True; end;
procedure TTextPrinter.SetErrorString; begin if FErrorString <> nil then LocalFree(Integer(FErrorString)); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM, nil, GetLastError(), LANG_USER_DEFAULT, @FErrorString, 0, nil ); end;
procedure TTextPrinter.Write(const Str: string); var OEMStr: PChar; NumberOfBytesToWrite: Integer; begin if not FPrinterOpen then Exit; NumberOfBytesToWrite := Length(Str); OEMStr := PChar(LocalAlloc(LMEM_FIXED, NumberOfBytesToWrite + 1)); try CharToOem(PChar(Str), OEMStr); if not WriteFile(FHandle, OEMStr^, NumberOfBytesToWrite, FNumberOfBytesWritten, nil) then begin SetErrorString; raise Exception.Create(FErrorString); end; finally LocalFree(Integer(OEMStr)); end; end;
procedure TTextPrinter.WriteLn(const Str: string); begin Self.Write(Str); Self.Write(#10); end;
destructor TTextPrinter.Destroy; begin CloseHandle(FHandle); if FErrorString <> nil then LocalFree(Integer(FErrorString)); end;
end. P.S. В принципе, вместо LPT1 может стоять что угодно, даже сетевой сервер печати (\\server\prn) - все равно печатает. Можно и параметр в конструктор вставить и т.д. |