GDI и даже абстрактная модель печати Windows, вероятно, здесь вам не помогут. Вам нужно будет отправить команду подачи и обрезки на принтер на том языке, на котором он обычно ожидает получение данных.
Например, термопринтер Epson TM-T88III говорит на родном языке ESC / POS, а не является последовательностью команд GDI или PCL. Тем не менее, большинство из этих принтеров поставляются с драйверами принтеров, благодаря которым Windows видит их как обычные принтеры GDI. Обычно эти драйверы работают так, что они растеризуют все команды GDI в одну большую битовую карту в программном обеспечении, а затем выдают битовую карту на принтер для печати через команду «print the bit-image» на своем родном языке. Обычно это имеет нежелательный эффект:
- Гораздо менее эффективно (с точки зрения требуемого времени и передаваемых данных) отправлять на принтер много растровых данных, чем последовательность двоичных команд, которые он знает, как интерпретировать. (Вы бы предпочли отправить изображение текста для печати или просто текст и спецификацию размера шрифта? Аналогии с HTML / CSS и изображением текста.)
- Эти принтеры обычно имеют низкое разрешение и являются монохромными (то есть все черное или белое, без оттенков серого или цветного). Их предварительно загруженные шрифты спроектированы так, чтобы хорошо работать при этих ограничениях для четкого и четкого рендеринга. Растеризация до растрового изображения приводит к потере этого тщательного дизайна, поскольку пиксели защелкиваются и округляются по сетке, что приводит к рваному текстовому рендерингу на фактической распечатке. Если вы пытаетесь нарисовать что-то, что действительно чувствительно к такому виду округления, например штрих-код, вы SOL, если вы не заботитесь о DPI контекста устройства принтера при работе с GDI.
Например, вот фрагмент кода из обширного примера в моем обычно нерелевантном блоге . В конце вы можете увидеть, как я заполняю BinaryWriter
необходимой последовательностью байтов, равной команде «подать бумагу и вырезать» на нашем термопринтере Epson (AsciiControlChars
- это просто статический класс с константами):
using (var ms = new MemoryStream())
using (var bw = new BinaryWriter(ms))
{
// Reset the printer bws (NV images are not cleared)
bw.Write(AsciiControlChars.Escape);
bw.Write('@');
// Render the logo
RenderLogo(bw);
// Feed 3 vertical motion units and cut the paper with a 1 point cut
bw.Write(AsciiControlChars.GroupSeparator);
bw.Write('V');
bw.Write((byte)66);
bw.Write((byte)3);
bw.Flush();
return ms.ToArray();
}
Затем вы можете просто отправить байты непосредственно на принтер в виде документа RAW, используя код в конце этой статьи, который работает с различными функциями принтера Win32, или класс Microsoft RawPrinterHelper от Microsoft .
Вам нужно будет найти команды, специфичные для вашего принтера. Скорее всего, он не слишком отличается от того, который вы видите здесь: языки POS начинают стандартизироваться, но это также означает, что SQL является стандартом - взаимно понятным для людей, но не способным к взаимодействию без каких-либо настроек.
Если вы по-прежнему хотите использовать GDI, вы можете распечатать документ GDI обычным способом на принтере (опять же, при условии, что драйвер принтера GDI существует, что, вероятно, и так), а затем выпустить второй, маленький, RAW документ на принтер, который содержит собственную команду подачи и обрезки. (В качестве альтернативы, некоторые драйверы принтера GDI позволяют указывать «всегда вырезать после печати документа» прямо на панели управления «Принтеры», но удачи вам в том, что программный доступ к этой функции драйвера задокументирован!)
Надеюсь, это поможет нарисовать картину отношений GDI с POS-принтерами.