Отправить документ Postscript на принтер с помощью VC++

У меня есть файл постскриптума. Как я могу отправить его на принтер с помощью Visual C++? Кажется, это должно быть просто.


person chowey    schedule 13.06.2013    source источник
comment
Я просматривал GDI API и любую другую документацию по принтерам, которую я мог видеть от Microsoft. Я могу отправлять команды GDI напрямую. Я могу получить принтер HDC. Но я не вижу, как просто отправлять команды postscript напрямую. Для принтера, совместимого с PostScript, это должно быть возможно, не так ли?   -  person chowey    schedule 13.06.2013


Ответы (3)


Если принтер напрямую поддерживает PostScript, вы можете буферизовать необработанные задания на печать следующим образом:

HANDLE ph;

OpenPrinter(&ph, "Printer Name", NULL);

di1.pDatatype = IsV4Driver("Printer Name") ? "XPS_PASS" : "RAW"; 
di1.pDocName = "Raw print document";
di1.pOutputFile = NULL;

StartDocPrinter(ph, 1, (LPBYTE)&di1);

StartPagePrinter(ph);

WritePrinter(ph, buffer, dwRead, &dwWritten);

EndPagePrinter(ph);

EndDocPrinter(ph)

Повторяйте WritePrinter, пока не подкачаете весь файл.

IsV4Driver() Проверяет наличие драйверов версии 4, это необходимо в Windows 8 и Server 2012:

bool IsV4Driver(wchar_t* printerName)
{
    HANDLE handle;
    PRINTER_DEFAULTS defaults;

    defaults.DesiredAccess = PRINTER_ACCESS_USE;
    defaults.pDatatype = L"RAW";
    defaults.pDevMode = NULL;

    if (::OpenPrinter(printerName, &handle, &defaults) == 0)
    {
        return false;
    }

    DWORD version = GetVersion(handle);

    ClosePrinter(handle);

    return version == 4;
}

DWORD GetVersion(HANDLE handle)
{
    DWORD needed;

    GetPrinterDriver(handle, NULL, 2, NULL, 0, &needed);

    std::vector<char> buffer(needed);

    return ((DRIVER_INFO_2*) &buffer[0])->cVersion;
}
person Tony Edgecombe    schedule 20.06.2013
comment
Отлично, это сработало для меня. Одно исправление - вы делаете EndDocPrinter дважды, но я почти уверен, что первого там быть не должно. - person chowey; 02.07.2013

Это сложнее, чем вы подозреваете. Если это принтер postscript, подключенный через последовательный или usb-порт, вы можете просто открыть устройство и записать файл. Точно так же, если это принтер PostScript, подключенный к сети Ethernet, вы можете подключиться к порту 9100 (telnet my.network.printer 9100 < pic.ps) (возможно, я не правильно помню номер порта, возможно, потребуется понюхать или провести некоторые исследования) и записать файл.

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

Если это комбинированный принтер PCL/PS, вам может потребоваться добавить заголовок PCL для входа в режим PS в зависимости от настроек принтера (если все настроено на «автоматическое определение», не беспокойтесь об этой части). Вы узнаете, как это сделать, если распечатаете фрагменты кода постскриптума, возможно, с помощью другой чепухи, вместо желаемого вывода.

Мне стыдно признаться, что я на самом деле не знаю, как открыть USB-устройство в Windows C++, но если это поможет, способ DOS состоял в том, чтобы использовать lpt1: в качестве имени файла (как в copy pic.ps lpt1:), которое будет использовать устройство.

Если это общий принтер, вам действительно следует пройти через сетевую очередь печати, а не напрямую на принтер.

person luser droog    schedule 13.06.2013

Это не так сложно. Вы можете использовать протокол LPD (Line Printer Daemon) для связи с сервером. Протокол прост, вы можете прочитать спецификацию и написать ее самостоятельно.

Другой способ — вызвать команду lpr напрямую. Однако эта команда отключена в Windows 7 по умолчанию. Поиск «lpr command windows 7» подскажет, как его включить.

person xeranic    schedule 13.06.2013