Отправка выходных данных 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 драйвер принтера преобразует данные в метафайле в формат, необходимый для конкретного используемого принтера.
Примечание
Если для используемого принтера не включена функция spooling, выходные данные графики не направляются в метафайл. Вместо этого отдельные графические команды обрабатываются драйвером принтера, а затем отправляются на принтер.
Как правило, вам не нужно жестко кодировать имя принтера, как это было сделано в предыдущем консольном приложении. Одной из альтернатив жесткому кодированию имени является вызов GetDefaultPrinter для получения имени принтера по умолчанию. Перед вызовом GetDefaultPrinter необходимо выделить буфер, достаточный для хранения имени принтера. Вы можете определить размер требуемого буфера, вызвав Метод GetDefaultPrinter, передав null в качестве первого аргумента.
Примечание
Функция GetDefaultPrinter поддерживается только в Windows 2000 и более поздних версиях.
Следующее консольное приложение получает имя принтера по умолчанию, а затем рисует на этом принтере прямоугольник и эллипс. Вызов Graphics::D rawRectangle находится между вызовами 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;
}