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

Мне нужно сообщить драйверу принтера, чтобы он выдал форму.

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

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

Много вдохновения пришло из KB138594 - HOWTO: отправка исходных данных на принтер с помощью Win32 API. Важным моментом в этой статье KB является то, что они (и мой скопированный код) запускают документ в режиме 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 Printers) ожидают, что задания RAW будут находиться на собственном языке принтера. Если вы используете вышеприведенное для печати на XPS или PDF-принтер: ничего не происходит (т.е. Нет диалогового окна сохранения, ничего не печатается).

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

docInfo.pDatatype = "RAW";

to TEXT:

docInfo.pDataType = "TEXT";

Хорошо, это возможно потому, что вы отправляете "RAW" непосредственно на принтер, и RAW может быть любым PDL. Но XPS водитель, вероятно, только понимает XPS, и он, вероятно, просто проигнорирует ваш "неизвестный: привет, мир! 0xFF" PDL. Драйвер 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> real </quote> : форма-канал не существует - по-видимому, потому, что я больше не печатаю в режиме "сырые команды принтера".

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

Мой вопрос: Как сообщить принтеру о выпуске Form-Feed во время печати?


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

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

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

Типы данных

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

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

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

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

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

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

Тип данных: RAW [FF auto]
Направления для диспетчера очереди буферов. Проверяйте трейлинг-фид и добавьте его, если он еще не существует, но никаких других изменений не производится.
Использовать: требуется для некоторых приложений. Windows не назначает его, но его можно установить как значение по умолчанию в диалоговом окне "Процессор печати".

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

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

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

alt text

См. также

Ответ 1

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

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

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

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

Ответ 2

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

Ответ 3

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

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

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

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