Windows: Как сказать принтеру выдавать FormFeed во время печати? - PullRequest
13 голосов
/ 30 декабря 2010

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

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

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

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

docInfo.pDatatype = "RAW";

на TEXT:

docInfo.pDataType = "TEXT";

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

Если вы хотите визуализировать текст в драйвере XPS, вам следует использовать GDI.Возможно, вы сможете отправить простой текст в драйвер, если вы укажете «TEXT» в качестве типа данных.Процессор печати, подключенный к драйверу, затем «преобразует» открытый текст для вас, отрисовывая задание через драйвер для 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, которое сохраняется правильно.И я подумал, что все исправлено.

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

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

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


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

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

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

Типы данных

Процесс печати 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 и добавьте характеристики печати, используя заводские настройки устройства печати. Использовать : Это полезно, когда задание на печать представляет собой простой текст и целевое устройство печати не может интерпретировать простой текст.

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

alt text

Смотри также

Ответы [ 3 ]

4 голосов
/ 30 декабря 2010

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

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

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

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

0 голосов
/ 31 декабря 2010

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

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

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

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

0 голосов
/ 30 декабря 2010

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

...