Windows: как указать принтеру выдавать FormFeed во время печати?

Мне нужно указать драйверу принтера, чтобы он запустил подачу страницы.

я печатаю прямо на принтер, используя:

набор вызовов API.

Во многом источником вдохновения послужил KB138594 - HOWTO: отправка необработанных данных на принтер с помощью Win32 API < / а>. В этой статье базы знаний важно отметить, что они (и мой скопированный код) запускают документ в режиме RAW:

// Fill in the structure with info about this "document."
docInfo.pDocName = "My Document";
docInfo.pOutputFile = NULL;
docInfo.pDatatype = "RAW";
StartDocPrinter(hPrinter, 1, docInfo);

Примечание. Режим RAW (в отличие от режима TEXT) означает, что мы отправляем необработанные байты в драйвер принтера. Мы обещаем говорить на том языке, который он понимает.

Затем мы можем использовать WritePrinter, чтобы написать все, что захотим:

WritePrinter(hPrinter, "Hello, world!"); //note, extra parameters removed for clarity
WritePrinter(hPrinter, 0x0c); //form-feed

Проблема здесь в символе подачи страницы 0x0c. Поскольку мы открыли принтер в RAW режиме, мы обещаем, что отправим байты драйвера принтера, которые он сможет обработать. Драйверы большинства принтеров принимают 0x0C, что означает, что вы хотите выполнить подачу страницы.

Проблема в том, что другие принтеры (принтер PDF, принтеры Microsoft XPS) ожидают, что задания на печать в формате RAW будут выполняться на их собственном языке принтера. Если вы используете вышеуказанное для печати на принтере XPS или PDF: ничего не происходит (т.е. нет диалогового окна сохранения, ничего не печатается).

я попросил решение на этот вопрос некоторое время назад, и был получен ответ, что вам необходимо изменить режим документа с RAW:

docInfo.pDatatype = "RAW";

to TEXT:

docInfo.pDataType = "TEXT";

Вероятно, это связано с тем, что вы отправляете данные в формате «RAW» непосредственно на принтер, а RAW может быть любым PDL. Но драйвер XPS, вероятно, понимает только XPS и, вероятно, просто проигнорирует ваш PDL "unknown: Hello, world! 0xFF". Драйвер XPS, вероятно, будет принимать данные XPS только тогда, когда вы пишете прямо в него.

Если вы хотите отобразить текст в драйвере XPS, вам следует использовать GDI. Если в качестве типа данных вы укажете «ТЕКСТ», вы можете отправить драйвер в виде обычного текста. Процессор печати, подключенный к драйверу, затем «преобразует» для вас открытый текст, передав задание драйверу через GDI.

Чтобы это сработало, я изменил свой код, чтобы объявить документ печати как TEXT:

// Fill in the structure with info about this "document."
docInfo.pDocName = "My Document";
docInfo.pOutputFile = NULL;
docInfo.pDatatype = "TEXT";
StartDocPrinter(hPrinter, 1, docInfo);
WritePrinter(hPrinter, "Hello, world!");
WritePrinter(hPrinter, 0x0c); //form-feed

Затем появляется диалоговое окно Сохранить как для принтеров XPS и PDF, и оно правильно сохраняется. И я думал, что все исправлено.

За исключением нескольких месяцев, когда я попытался напечатать на ‹quote> реальном ‹/quote> принтере: подачи формы не происходит - предположительно потому, что я больше не печатаю в режиме «сырые команды принтера».

Итак, что мне нужно, так это способ создания фида в стиле Windows. Мне нужен вызов API, который сообщит драйверу принтера, что я хочу, чтобы принтер выполнял подачу страницы.

Мой вопрос: как указать принтеру, что нужно подавать форму во время печати?


Справочная информация о типах данных

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

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

Типы данных

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

RAW - это тип данных по умолчанию для клиентов, отличных от программ для Windows. Тип данных RAW указывает диспетчеру очереди печати вообще не изменять задание печати перед печатью. При использовании этого типа данных весь процесс подготовки задания на печать выполняется на клиентском компьютере.

EMF, или расширенный метафайл, является типом данных по умолчанию для большинства программ на базе Windows. С помощью EMF напечатанный документ преобразуется в формат метафайла, который более портативен, чем файлы RAW, и обычно может быть распечатан на любом принтере. Файлы EMF обычно меньше файлов RAW, содержащих то же задание на печать. Что касается производительности, то только первая часть задания на печать изменяется или отображается на клиентском компьютере, но большая часть воздействия приходится на компьютер сервера печати, который также помогает приложению на клиентском компьютере быстрее возвращать управление пользователю.

В следующей таблице (взято из MSDN) показаны пять различных типов данных. поддерживается процессором печати Windows по умолчанию:

Тип данных: RAW
Указания к диспетчеру очереди печати: распечатать документ без изменений.
Использование: это тип данных для все клиенты не на винде.

Тип данных: RAW [FF appended]
Указания к диспетчеру очереди: добавьте символ подачи страницы (0x0C), но не вносите никаких других изменений. (Принтер PCL пропускает последнюю страницу документа, если нет завершающей подачи формы.)
Использование: требуется для некоторых приложений. Windows не назначает его, но его можно установить по умолчанию в диалоговом окне «Обработчик печати».

Тип данных: RAW [FF auto]
Указания к диспетчеру очереди: проверьте наличие завершающего канала формы и добавьте его, если его еще нет, но не вносите никаких других изменений.
Использование: требуется для некоторых приложений. Windows не назначает его, но его можно установить по умолчанию в диалоговом окне «Обработчик печати».

Тип данных: NT EMF 1.00x
Указания к диспетчеру очереди. Считайте документ расширенным метафайлом (EMF), а не данными RAW, которые выводит драйвер принтера.
Использование: документы EMF создаются Windows.

Тип данных: TEXT
Указания к диспетчеру очереди. Обработайте все задание как текст ANSI и добавьте спецификации печати, используя заводские настройки устройства печати. Использование: это полезно, когда задание печати представляет собой простой текст, а целевое печатающее устройство не может интерпретировать простой текст.

Вы можете увидеть процессоры печати, доступные для принтера, и типы данных, которые поддерживает каждый процессор, через свойства принтера на панели управления:

alt text

Смотрите также


person Ian Boyd    schedule 30.12.2010    source источник


Ответы (3)


Да, это не работает. Вы намеренно игнорируете драйвер принтера, фрагмент кода, который представляет собой универсальный интерфейс для любого принтера. Что оставляет вам разбираться с особенностями каждой конкретной модели принтера.

Есть несколько общих интерфейсов, тот, который вы использовали в своем коде, - это тот, который использовался в старых матричных принтерах. PCL широко используется в лазерных принтерах Hewlett Packard. Postscript широко используется в принтерах высокого класса. У последних двух есть свои заклинания для получения формы.

Еще есть океан дешевых лазерных и струйных принтеров. Часто у них вообще нет четко определенного интерфейса. Вместо процессора внутри принтера, который переводит команды принтера в точки на бумаге, они позволяют драйверу принтера делать всю тяжелую работу. Вы никогда не получите ни одного из них, интерфейс проприетарный и недокументированный.

Драйвер принтера здесь ваш друг. PrintDocument класс, который будет его использовать. Получить канал формы легко, просто установите _ 1_ и выйдите из PrintPage обработчик событий. Вы уже видели связанный мной класс StreamPrinter.

person Hans Passant    schedule 30.12.2010
comment
Я не использую управляемый код, но разрешает ли класс PrintDocument использовать шрифты принтера (т.е. быстро печатать точечную матрицу, а не печатать текст как графику)? - person Ian Boyd; 30.12.2010
comment
Об этом позаботится драйвер принтера, он знает, какие шрифты установлены на принтере. - person Hans Passant; 30.12.2010
comment
Да, но как бы вы использовали класс PrintDocument таким образом, чтобы я сказал ему, что хочу использовать шрифты принтера, а не, скажем, Arial. Пример на MSDN выполняет graphics.DrawString(...) с использованием .NET GDI +. Google говорит, что .NET не поддерживает шрифты принтера, а только TTF. - person Ian Boyd; 31.12.2010
comment
Замена, в основном, Arial карт на Helvetica. Полная информация находится здесь: support.microsoft.com/kb/201978 - person Hans Passant; 31.12.2010

Я не знаком с типом документа TEXT, но предполагаю, что это просто представление «глупого принтера» с наименьшим общим знаменателем. Если это так, он может распознать символ подачи формы, за исключением того, что вы использовали неправильный символ - это не 0x12 или 0xFF, это 0x0c. См. http://en.wikipedia.org/wiki/Ascii.

person Mark Ransom    schedule 30.12.2010
comment
Да, это была ошибка преобразования конкретного языка в общий язык, которую я сделал в своей голове, когда писал вопрос. Реальный синтаксис исходного языка - #12, который представляет собой десятичный символ 12, который является символом FF. На первом проходе при вводе вопроса я слепо преобразовал const FF = #12 в 0xFF, затем исправил его на 0x12, что тоже неверно. Конечно, должно быть 0x0c. Исправлена ​​исправленная опечатка. - person Ian Boyd; 30.12.2010

Поскольку мой последний ответ не помог, давайте попробуем очевидное. Вы пробовали делать EndPagePrinter, а затем StartPagePrinter всякий раз, когда вам нужен разрыв страницы?

Если это по-прежнему не сработает, возможно, вам придется сделать это сложным путем, используя GDI. Стек выглядит немного иначе, чем тот, который вы используете:

  • CreateDC
  • CreateFont
  • SelectObject
  • StartDoc
    • StartPage
      • TextOut
    • EndPage
  • EndDoc
  • DeleteDC

Вам потребуется управлять шрифтом и самостоятельно размещать текст на странице в каждой позиции строки.

person Mark Ransom    schedule 30.12.2010