Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Как программно установить размер бумаги для принтера Epson TM 30 в Delphi?

Delphi , ОС и Железо , Принтеры и Печать

 

Проблема с выбором размера бумаги

При работе с принтерами Epson TM 30 (и другими POS-принтерами) на рулонной бумаге 80 мм разработчики часто сталкиваются с проблемой: несмотря на правильные настройки в системе Windows, при открытии диалога печати из Delphi по умолчанию выбирается формат A4 вместо нужного "бесконечного рулона 80 мм".

Как отмечает пользователь в вопросе, даже после установки правильного размера бумаги в настройках принтера Windows, при каждом запуске процедуры печати размер снова сбрасывается на A4.

Решение проблемы

1. Проверка и установка драйверов

Перед программным решением убедитесь, что: - Установлены официальные драйверы Epson TM 30 (не универсальные драйверы Windows) - В настройках принтера в Windows выбран правильный размер бумаги - Отключено автоматическое управление принтерами в Windows

2. Получение списка доступных размеров бумаги

Для работы с размерами бумаги в Delphi можно использовать WinAPI функцию DeviceCapabilities. Вот пример функции, которая возвращает список доступных форматов бумаги:

type
  TPrinterValueNamePair = record
    Name: string;
    Value: SmallInt;
  end;

  TPrinterValueNamePairs = array of TPrinterValueNamePair;

function GetPaperSizes: 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. Установка нужного размера бумаги

Для установки конкретного размера бумаги можно использовать следующую процедуру:

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;
    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. Поиск нужного формата бумаги

Для POS-принтеров Epson TM 30 обычно используются следующие константы: - DMPAP_ROLL_80 (80 мм рулонная бумага) - DMPAP_ROLL_58 (58 мм рулонная бумага)

Однако эти константы могут отличаться в зависимости от драйвера. Лучший способ - перечислить все доступные форматы и найти нужный по имени:

function FindPaperSizeByName(const AName: string): SmallInt;
var
  PaperSizes: TPrinterValueNamePairs;
  I: Integer;
begin
  Result := 0; // По умолчанию
  PaperSizes := GetPaperSizes;

  for I := 0 to High(PaperSizes) do
  begin
    if Pos(AName, PaperSizes[I].Name) > 0 then
    begin
      Result := PaperSizes[I].Value;
      Break;
    end;
  end;
end;

Пример использования:

procedure TForm1.ButtonPrintClick(Sender: TObject);
var
  PaperSize: SmallInt;
begin
  // Находим и устанавливаем 80 мм рулонную бумагу
  PaperSize := FindPaperSizeByName('80mm');
  if PaperSize > 0 then
    SetPrinterPaperSize(PaperSize)
  else
    ShowMessage('Не удалось найти размер бумаги 80mm');

  // Далее ваша логика печати
  Printer.BeginDoc;
  try
    Printer.Canvas.TextOut(10, 10, 'Тест печати на Epson TM-30');
  finally
    Printer.EndDoc;
  end;
end;

Альтернативное решение: прямой вывод на принтер

Для POS-принтеров часто более надежным решением является прямой вывод команд ESC/POS, минуя драйвер Windows:

procedure DirectPrintToEpsonTM30;
var
  hPrinter: THandle;
  DocInfo: TDocInfo1;
  BytesWritten: DWORD;
  Data: AnsiString;
begin
  // Открываем принтер по имени
  if OpenPrinter('Epson TM-T30', hPrinter, nil) then
  try
    // Начинаем документ
    FillChar(DocInfo, SizeOf(DocInfo), 0);
    DocInfo.pDocName := 'POS Print';
    DocInfo.pOutputFile := nil;
    DocInfo.pDatatype := 'RAW';

    StartDocPrinter(hPrinter, 1, @DocInfo);
    StartPagePrinter(hPrinter);

    try
      // ESC/POS команды для инициализации, выбора режима и печати текста
      Data := #27'@' +         // Инициализация принтера
              'Test print on Epson TM-T30'#10#13 +
              #29'V'#66#0;     // Частичный отрез

      WritePrinter(hPrinter, @Data[1], Length(Data), BytesWritten);
    finally
      EndPagePrinter(hPrinter);
      EndDocPrinter(hPrinter);
    end;
  finally
    ClosePrinter(hPrinter);
  end
  else
    RaiseLastOSError;
end;

Заключение

Проблема с автоматическим сбросом размера бумаги в Epson TM-30 при печати из Delphi решается: 1. Установкой правильных драйверов 2. Программной установкой размера бумаги перед печатью 3. Либо использованием прямого вывода ESC/POS команд

Представленные примеры кода позволяют: - Получить список доступных размеров бумаги - Установить нужный размер программно - Определить текущий размер бумаги - Осуществить прямой вывод на принтер

Для POS-систем рекомендуется использовать прямое управление принтером через ESC/POS команды, так как это обеспечивает более предсказуемое поведение и не зависит от настроек драйвера Windows.

Создано по материалам из источника по ссылке.

Решение проблемы программной установки размера бумаги для принтера Epson TM 30 в Delphi с примерами кода.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Принтеры и Печать ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-06-04 07:17:24/0.0059549808502197/0