Чтение онлайн

ЖАНРЫ

Советы по Delphi. Версия 1.4.3 от 1.1.2001

Озеров Валентин

Шрифт:

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) – все равно печатает. Можно и параметр в конструктор вставить и т.д.

Как правильно печатать любую информацию (растровые и векторные изображения), а также как сделать режим предварительного просмотра?

Nomadic советует:

Маленькое предисловие.

Т.к. основная моя работа связана с написанием софта для института, обрабатывающего геоданные, то и в отделе, где pаботаю, так же мучаются проблемами печати (в одном случае — надо печатать карты, с изолиниями, заливкой, подписями и пр.; в другом случае — свои таблицы и сложные отрисовки по внешнему виду).

В итоге, моим коллегой был написан кусок, в котором ему удалось добиться качественной печати в двух режимах : MetaFile, Bitmap.

Работа с MetaFile у нас сложилась уже исторически — достаточно удобно описать ф-цию, которая что-то отрисовывает (хоть на экране, хоть где), которая принимает TCanvas, и подсовывать ей то канвас дисплея, то канвас метафайла, а потом этот Metafile выбрасывать на печать. Достаточно решить лишь проблемы масштабирования, после чего — вперед.

Главная головная боль при таком методе — при отрисовке больших кусков, которые занимают весь лист или его большую часть, надо этот метафайл по размерам делать сразу же в пикселах на этот самый лист. Тогда при изменении размеров (просмотр перед печатью) — искажения при уменьшении не кpритичны, а вот при увеличении линии и шрифты не "поползут".

Итак:

Hабор идей, котоpые были написаны (с) Андреем Аристовым, программистом отдела матобеспечения СибНИИНП, г. Тюмень. Моего здесь только — приделывание сверху надстроек для личного использования.

Вся работа сводится к следующим шагам :

1. Получить необходимые коэф-ты;

2. Построить метафайл или bmp для последующего вывода на печать;

3. Hапечатать.

Hиже приведенный кусок (прошу меня не пинать, но писал я и писал для достаточно кривой реализации с передачей параметров через глобальные переменные) я использую для того, чтобы получить коэф-ты пересчета.

Поделиться с друзьями: