Нам нужно иметь возможность изменить лоток для печати, выбранный по умолчанию для данного принтера. У кого-нибудь есть код VC++ / win32 для этого?
В случае, если это имеет значение, я считаю, что нам нужно изменить настройки по умолчанию для принтера. Наши задания на печать выполняются приложением, отличным от нашего, поэтому мы не можем вносить такие изменения в контексте операции печати, исходящей из нашего приложения. Если нет способа изменить настройки печати по умолчанию в другом приложении, я думаю, что мы застряли в изменении пользовательских значений по умолчанию для принтера, инициируя наше задание печати, а затем возвращая значения по умолчанию к исходным значениям.
Мы действительно предпочли бы, чтобы значения по умолчанию менялись только для текущего пользователя, и не требовали какого-либо специального повышения прав UAC и т. д.
Я подозреваю, что он будет использовать что-то похожее на то, что показано в эта статья MSDN, и включать настройки полей в структуре DEVMODE (либо dmDefaultSource, либо dmFormName, либо оба).
Есть берущие? Или у кого-нибудь есть какие-то ошибки, которыми они хотели бы поделиться?
Обновлено: вот ссылка на документацию DEVMODE Документация DEVMODE
Обновлено: Я также должен указать, что мы ищем общее решение, а не что-то конкретное для конкретного принтера (мы развертываем во многих, многих средах)





Недавно мне пришлось сделать что-то очень похожее на конкретный драйвер принтера, и для этого требовался SDK конкретного производителя. Лоток, похоже, не отображается в DEVMODE или любой другой структуре PRINTINFO_ *, поэтому я думаю, что отправлю электронное письмо поставщику принтера.
В крайнем случае, я могу придумать два возможных взлома. Один из них - автоматизировать драйвер на уровне графического интерфейса пользователя с помощью скриптового инструмента, такого как AutoIT. Во-вторых, выгрузите реестр в файл, измените настройки драйвера, снова сделайте дамп реестра и сравните различия (может работать, а может и не работать).
Насколько мне известно, принтеры управляются драйвером принтера, отправляя им команды SNMP или PJL. Но не все принтеры полностью реализуют эти наборы команд.
Для принтеров HP я нашел по адресу: http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?lang=en&cc=us&objectID=bpl07282&jumpid=reg_R1002_USEN некоторые команды PJL (некоторые также относятся к лотку).
Я не уверен, что это поможет, но воспринимайте это как подсказку для будущих поисков ...
Настройка таких функций может быть сложной, особенно если драйвер не следует рекомендациям Microsoft по печати. При этом мы добились определенного успеха с System.Drawing.Printing.PrinterSettings. Вы можете установить PaperSource, но я не уверен, что вы можете установить значения по умолчанию.
Если вы не видели этот пример, возможно, вы захотите посмотреть на него дальше. В нем описывается метод сохранения и перезагрузки настроек принтера. Один из моих парней указал мне на это: Настройки принтера - изменение, сохранение и загрузка настроек принтера
Другой метод, который может сработать, но может не сработать для вас, - это определить несколько необходимых вам настроек. Установите принтер с каждой из этих настроек (например, лоток 1, лоток 2). Затем просто переключите принтер по умолчанию на печать. Не то, что вы ищете, но это может помочь.
Что мы обычно делаем в этих ситуациях, так это заставляем стороннее приложение записывать данные в папку, которую мы отслеживаем, затем мы забираем файл и сами разбираем Postscript или PCL, меняем лоток для бумаги и затем отправляем на целевое устройство. Намного проще, чем может показаться.
Это хороший справочник по настройкам, связанным с текущим приложением. Если бы мое приложение инициировало задания на печать, оно бы работало отлично. Но мы даем указание другому приложению инициировать задание печати, поэтому нам нужно либо изменить настройки в другом приложении, либо изменить настройки системы по умолчанию.
dmDefaultSource управляет лотком. К сожалению, значения, которые вы хотите установить, различаются в зависимости от вашего драйвера, поскольку это номер лотка, а не обязательно тот же номер, что и номер лотка, напечатанный на вашем принтере.
Следующая ссылка предоставляет некоторый код VB6 для сбора информации о назначениях лотков / лотков вашего принтера. Вы можете использовать эту информацию, чтобы программно назначить dmDefaultSource соответствующей ячейке № для лотка. В основном вам нужно использовать DeviceCapabilities, чтобы вернуть информацию о ваших принтерах, а затем выполнить поиск строки (например, «Лоток 1»), чтобы получить связанный номер ячейки.
http://support.microsoft.com/kb/194789
Это выглядит довольно многообещающе - я отправлю ответ, когда смогу подышать воздухом и покачать его - спасибо!
К вашему сведению - решение, которое мы использовали, заключалось в захвате структуры DEVMODE. У нас есть небольшое приложение win32, которое представляет диалог настроек принтера (через Свойства документа с fMode, установленным на DM_IN_PROMPT). Результирующий DEVMODE затем сохраняется на диск. Когда мы выполняем нашу печать, мы фиксируем текущий DEVMODE, устанавливаем сохраненный DEVMODE, запускаем печать, затем восстанавливаем исходный DEVMODE.
Это действительно хорошо работает. Иногда драйверы печати обновляются и вызывают сбой сохраненного режима DEVMODE, но это происходит не очень часто, и пользователям достаточно легко исправить это.
В качестве дополнительного бонуса этот подход позволяет нам фиксировать ВСЕ настройки принтера (а не только выходной лоток), поэтому мы смогли поддерживать расширенные настройки, такие как сшивание, подборка и т. д.
Совет: если вы попробуете это сделать, обязательно записывайте на диск как двоичный выходной поток. В моей первоначальной оценке этого подхода я случайно установил выходной поток как поток вывода текста. Во многих случаях все будет работать нормально, а затем внезапно сломаться для некоторых принтеров (которые использовали байты высокого порядка в своих личных данных DEVMODE). Глупая, но легкая ошибка, которая на время сняла с рассмотрения очень хорошее решение.
Я не думаю, что вам было бы интересно расширить свой ответ? Как захватить текущий DEVMODE? Как заменить его на сохраненный?
Конечно - вы используете DocumentProperties с другим значением для fMode
Эта ссылка содержит дополнительное описание и пример кода C#. nicholas.piasecki.name/blog/2008/11/…
DEVMODE имеет два параметра (dmDefaultSource и dmFormName), которые, кажется, управляют лотком. Неправильно ли я истолковываю то, что контролируют эти участники?