Программно установить параметр Страниц на листе (N-Up) при печати в Windows - PullRequest
3 голосов
/ 11 августа 2010

Мне нужен хороший способ программно установить параметр «Страниц на листе» при печати. ​​

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

В то время, как оно появляется, я могу спросить Windows, если принтерподдерживает это с помощью элемента dmNup структуры DEVMODE, и, похоже, нет никакого официального способа фактически установить его для текущего задания на печать.

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

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

Эта статья предлагает другое возможное решение: манипулирование соответствующимбайт в данных частного драйвера, который следует официальной структуре DEVMODE.Проблема в том, что нет никакой гарантии, что какой-либо конкретный драйвер принтера фактически использует один и тот же байт, и мне нужно поддерживать практически любой принтер, который может быть разумно использован в офисной среде.Казалось бы, моему программному обеспечению понадобилась бы конфигурация, в которой я мог бы указать различные смещения байтов для драйверов, которые не используют значение по умолчанию.Это может быть редким явлением или частой головной болью, в зависимости от того, сколько драйверов принтеров решили использовать разные байты для этой настройки.

Итак, вот мои вопросы:

  • Есть ли у кого-нибудь какие-либореальный опыт использования последней техники манипуляции с данными частного драйвера?Насколько хорошо он работает при работе с различными принтерами разных производителей?
  • Есть ли какие-то другие методы, которые я упустил из виду?
  • Если ничего другого, то есть какие-то простые способы получения кодакоторый рисует текст, линии, графику и т. д. в контексте устройства принтера и каким-то образом заставляет его масштабировать, перемещать и, возможно, вращать (по 2 страницы на листе) вывод в нужное место в контексте устройства без записи всего кода (и без потери линий шириной в 1 пиксель)?

Примечание. Для чего стоит программа, над которой я работаю, использует C ++ и MFC.Однако все это должно в равной степени применяться к любой программе, которая имеет дело с контекстами устройства и остальной частью самого Windows API.

Ответы [ 3 ]

0 голосов
/ 22 февраля 2011

При реализации XPS в Win XP и более поздних версиях, если у вас есть исходное приложение в качестве приложения WPF / .NET, вы можете использовать PrintTicket в качестве механизма для установки NUp.

http://msdn.microsoft.com/en-us/library/system.printing.printticket.pagespersheet.aspx указывает свойство для N-Up.

В идеале, если приложение для рисования устанавливает это и затем вызывает драйвер печати, Windows должна установить правильную настройку NUp и передать ее базовому драйверу (GDI или XPS). Но, возможно, это будет работать только для тех драйверов, для которых реализованы преобразования Print Ticket.

0 голосов
/ 24 апреля 2012

Я наткнулся на учебник по Как напечатать несколько страниц на одном листе .

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

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

У меня есть код, который вы можете посмотреть в моем SO-вопросе здесь: PrintPage PrintPageEventHandler печатает слишком много копий .Оказывается, я неправильно указывал количество копий в своем документе.

0 голосов
/ 14 октября 2010

Ну, прошло уже много времени с тех пор, как я использовал GDI и MFC, но в прошлом я довольно много работал с принтерами. Я бы сказал, что поскольку GDI должен абстрагировать вашу программу от знания контекста рисования, вам не повезло для конкретного вызова API. Тем не менее, могут быть некоторые способы сделать это, которые не так хакерские, как хлопать битами в приватной области структуры.

Первое, что я хотел бы сделать, это взглянуть на метод CDC :: Escape (или функцию Escape Win32 API). В лучшем случае есть стандартная escape-последовательность для установки принтера в режим n-up. В худшем случае вам нужно найти управляющую последовательность для вашего принтера и отправить ее в необработанном виде. (Когда-то это был единственный способ заставить принтер использовать свои необычные функции.) Некоторое время назад большинство принтеров начали внедрять языковой стандарт (PCL? HPGL? Я забыл, какой). Может случиться так, что многие принтеры поймут управляющую последовательность, если они все еще будут реализовывать стандартные языки.

Если это не удастся, вам, вероятно, придется вручную реализовать свой собственный рисунок n-up для контекста, но использовать что-то вроде SetMapMode, чтобы установить единицы измерения в Twips (или как там работает) и нарисовать их предварительно масштабированными.

В противном случае попробуйте посмотреть, что GDI делает с масштабированием, и посмотрите, работает ли это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...