При работе с POS-принтерами, такими как Epson TM 30, часто возникает необходимость программно управлять настройками печати, особенно при использовании рулонной бумаги шириной 80 мм. В этой статье я расскажу, как правильно настроить принтер в Delphi, чтобы избежать проблем с автоматическим выбором формата A4 вместо нужного размера.
Проблема
Как отмечает пользователь в исходном вопросе, несмотря на правильные настройки в Windows, при открытии диалога печати из Delphi принтер по умолчанию выбирает формат A4 вместо "рулон 80 мм". Это происходит даже при корректных настройках в панели управления принтерами.
Решение
1. Проверка и установка драйверов
Перед программным решением убедитесь, что: - Установлены официальные драйверы Epson TM 30 (не универсальные драйверы Windows) - В настройках принтера в Windows выбран правильный размер бумаги - Отключено автоматическое управление принтерами в Windows
2. Получение списка доступных форматов бумаги
Для работы с настройками принтера в Delphi используем WinAPI-функции. Вот функция для получения списка доступных форматов бумаги:
type
TPrinterValueNamePair = record
Name: string;
Value: SmallInt;
end;
TPrinterValueNamePairs = array of TPrinterValueNamePair;
function GetAvailablePaperSizes: TPrinterValueNamePairs;
var
device, driver, port: array[0..255] of char;
hDMode: THandle;
hPrinter: THandle;
Len: Integer;
PaperNames: array of array[0..63] of char;
PaperNumbers: array of word;
I: Integer;
begin
SetLength(Result, 0);
// Получаем информацию о текущем принтере
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(device, driver, port, hDMode);
if OpenPrinter(device, hPrinter, nil) then
try
// Получаем названия форматов бумаги
Len := DeviceCapabilities(device, port, DC_PAPERNAMES, nil, nil);
if Len > 0 then
begin
SetLength(PaperNames, Len);
DeviceCapabilities(device, port, DC_PAPERNAMES, @PaperNames[0], nil);
end;
// Получаем номера форматов бумаги
Len := DeviceCapabilities(device, port, DC_PAPERS, nil, nil);
if Len > 0 then
begin
SetLength(PaperNumbers, Len);
DeviceCapabilities(device, port, DC_PAPERS, @PaperNumbers[0], nil);
end;
// Формируем результат
SetLength(Result, Length(PaperNumbers));
for I := 0 to High(PaperNumbers) do
begin
Result[I].Value := PaperNumbers[I];
if I < Length(PaperNames) then
Result[I].Name := PaperNames[I]
else
Result[I].Name := 'Формат #' + IntToStr(PaperNumbers[I]);
end;
finally
ClosePrinter(hPrinter);
end;
end;
3. Установка нужного формата бумаги
Для установки формата "рулон 80 мм" нужно найти его числовой идентификатор в списке доступных форматов и установить его:
procedure SetPrinterPaperSize(APaperSize: SmallInt);
var
device, driver, port: array[0..255] of char;
hDMode: THandle;
pDMode: PDEVMODE;
begin
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(device, driver, port, hDMode);
if hDMode <> 0 then
begin
pDMode := GlobalLock(hDMode);
if Assigned(pDMode) then
try
pDMode^.dmPaperSize := APaperSize;
pDMode^.dmFields := pDMode^.dmFields or DM_PAPERSIZE;
// Для рулонной бумаги также может потребоваться установка ориентации
pDMode^.dmOrientation := DMORIENT_PORTRAIT;
pDMode^.dmFields := pDMode^.dmFields or DM_ORIENTATION;
finally
GlobalUnlock(hDMode);
end;
end;
// Принудительное обновление настроек принтера
Printer.Copies := Printer.Copies;
end;
4. Определение текущего формата бумаги
Чтобы проверить текущий установленный формат бумаги:
function GetCurrentPaperSize: SmallInt;
var
device, driver, port: array[0..255] of char;
hDMode: THandle;
pDMode: PDEVMODE;
begin
Result := 0;
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(device, driver, port, hDMode);
if hDMode <> 0 then
begin
pDMode := GlobalLock(hDMode);
if Assigned(pDMode) then
try
Result := pDMode^.dmPaperSize;
finally
GlobalUnlock(hDMode);
end;
end;
end;
5. Пример использования
Вот как можно использовать эти функции в приложении:
procedure TForm1.Button1Click(Sender: TObject);
var
PaperSizes: TPrinterValueNamePairs;
I: Integer;
Roll80mmSize: SmallInt;
begin
// Получаем список доступных форматов
PaperSizes := GetAvailablePaperSizes;
// Ищем "рулон 80 мм" в списке
Roll80mmSize := 0;
for I := 0 to High(PaperSizes) do
begin
if Pos('80mm', PaperSizes[I].Name) > 0 then
begin
Roll80mmSize := PaperSizes[I].Value;
Break;
end;
end;
if Roll80mmSize = 0 then
raise Exception.Create('Формат "рулон 80 мм" не найден в списке доступных форматов');
// Устанавливаем нужный формат
SetPrinterPaperSize(Roll80mmSize);
// Проверяем текущий формат
if GetCurrentPaperSize <> Roll80mmSize then
ShowMessage('Не удалось установить формат бумаги')
else
ShowMessage('Формат бумаги успешно установлен на "рулон 80 мм"');
end;
Альтернативное решение: использование ESC/POS команд
Для POS-принтеров Epson можно использовать прямое управление через ESC/POS команды, минуя драйвер Windows:
procedure PrintToEpsonTM30Direct;
var
F: TextFile;
begin
AssignPrn(F);
try
Rewrite(F);
// Инициализация принтера
Writeln(F, #27'@');
// Установка режима печати
Writeln(F, #27'!'#0); // Стандартный режим
// Печать текста
Writeln(F, 'Пример печати на рулоне 80 мм');
Writeln(F, '----------------------------');
Writeln(F, 'Товар 1 100 руб.');
Writeln(F, 'Товар 2 200 руб.');
Writeln(F, '----------------------------');
Writeln(F, 'Итого: 300 руб.');
// Подача бумаги и отрезание (если есть авторезчик)
Writeln(F, #29'V'#65#0); // Полная отсечка
finally
CloseFile(F);
end;
end;
Заключение
Проблема с автоматическим выбором формата A4 вместо рулонной бумаги решается: 1. Установкой правильных драйверов 2. Программной установкой нужного формата перед печатью 3. Либо использованием прямого вывода ESC/POS команд
Представленные примеры кода на Delphi позволяют контролировать настройки печати и гарантировать правильный выбор формата бумаги для Epson TM 30.
Статья описывает методы программной настройки размера бумаги "рулон 80 мм" для принтера Epson TM 30 в Delphi, включая работу с WinAPI и ESC/POS командами.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.