Поделиться через


Отправка выходных данных GDI+ на принтер

Использование Windows GDI+ для рисования на принтере аналогично использованию GDI+ для рисования на экране компьютера. Чтобы нарисовать на принтере, получите дескриптор контекста устройства для принтера, а затем передайте этот дескриптор в конструктор графики.

Следующее консольное приложение рисует линию, прямоугольник и многоточие на принтере с именем MyPrinter:

#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
using namespace Gdiplus;

INT main()
{
   // Initialize GDI+.
   GdiplusStartupInput gdiplusStartupInput;
   ULONG_PTR gdiplusToken;
   GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

   // Get a device context for the printer.
   HDC hdcPrint = CreateDC(NULL, TEXT("\\\\printserver\\print1"), NULL, NULL);

   DOCINFO docInfo;
   ZeroMemory(&docInfo, sizeof(docInfo));
   docInfo.cbSize = sizeof(docInfo);
   docInfo.lpszDocName = "GdiplusPrint";

   StartDoc(hdcPrint, &docInfo);
   StartPage(hdcPrint);
      Graphics* graphics = new Graphics(hdcPrint);
      Pen* pen = new Pen(Color(255, 0, 0, 0));
      graphics->DrawLine(pen, 50, 50, 350, 550);
      graphics->DrawRectangle(pen, 50, 50, 300, 500);
      graphics->DrawEllipse(pen, 50, 50, 300, 500);
      delete pen;
      delete graphics;
   EndPage(hdcPrint);
   EndDoc(hdcPrint);
   
   DeleteDC(hdcPrint);
   GdiplusShutdown(gdiplusToken);
   return 0;
}

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

Заметка

Если буферизация (спулинг) не включена для используемого принтера, то вывод графики не направляется в метафайл. Вместо этого отдельные графические команды обрабатываются драйвером принтера, а затем отправляются на принтер.

 

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

Заметка

Функция getDefaultPrinter поддерживается только в Windows 2000 и более поздних версиях.

 

Следующее консольное приложение получает имя принтера по умолчанию, а затем рисует прямоугольник и многоточие на этом принтере. Вызов Graphics::DrawRectangle находится между вызовами StartPage и EndPage, поэтому прямоугольник находится на отдельной странице. Аналогичным образом эллипс находится на отдельной странице.

#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
using namespace Gdiplus;

INT main()
{
   // Initialize GDI+.
   GdiplusStartupInput gdiplusStartupInput;
   ULONG_PTR gdiplusToken;
   GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

   DWORD size;
   HDC hdcPrint;

   DOCINFO docInfo;
   ZeroMemory(&docInfo, sizeof(docInfo));
   docInfo.cbSize = sizeof(docInfo);
   docInfo.lpszDocName = "GdiplusPrint";

   // Get the size of the default printer name.
   GetDefaultPrinter(NULL, &size);

   // Allocate a buffer large enough to hold the printer name.
   TCHAR* buffer = new TCHAR[size];

   // Get the printer name.
   if(!GetDefaultPrinter(buffer, &size))
   {
      printf("Failure");
   }
   else
   {
      // Get a device context for the printer.
      hdcPrint = CreateDC(NULL, buffer, NULL, NULL);

      StartDoc(hdcPrint, &docInfo);
         Graphics* graphics;
         Pen* pen = new Pen(Color(255, 0, 0, 0));

         StartPage(hdcPrint);
            graphics = new Graphics(hdcPrint);
            graphics->DrawRectangle(pen, 50, 50, 200, 300);
            delete graphics;
         EndPage(hdcPrint);

         StartPage(hdcPrint);
            graphics = new Graphics(hdcPrint);
            graphics->DrawEllipse(pen, 50, 50, 200, 300);
            delete graphics;
         EndPage(hdcPrint);

         delete pen;
      EndDoc(hdcPrint);

      DeleteDC(hdcPrint);
   }

   delete buffer;

   GdiplusShutdown(gdiplusToken);
   return 0;
}