Virtual Printer for Developers
© 2000-2010, Two Pilots

На английском: Virtual Printer
Другие проекты: PDF Library
В начало История версий Документация Скачать Поддержка Купить

Как работает виртуальный принтер

 

 

Как виртуальный принтер передает информацию клиенскому приложению

Клиентское приложение получает информацию от виртуального принтера через INI файл:
Виртуальный принтер   -> EMF файлы + INI файл ->   Клиентское приложение

В INI файле сохраняется вся информация о работе виртуального принтера.

Пример INI файла:

[Device]
DeviceName=Your Virtual Printer Example
[Document]
Name=Lorem Ipsum - All the facts - Lipsum generator
JobID=2
MachineName=\\T23
UserName=Stas
SessionID=0
HorizontalResolution=300
VerticalResolution=300
Orientation=1
PaperSize=9
PaperSizeName=A4
PaperWidth=2100
PaperLength=2970
Pages=2
Copies=1
Collate=0
Bin=15
BinName=Automatically Select
[EMF]
Count=2
File0=C:\DOCUME~1\Stas\LOCALS~1\Temp\00020001.emf
File1=C:\DOCUME~1\Stas\LOCALS~1\Temp\00020002.emf

Режимы передачи пути к INI файлу от виртуального принтера к заданной клиентской программе:

  1. Командная строка
    При передаче с помощью командной строки виртуальный принтер запускает указанную ему клиентскоую программу с путем INI файла в виде параметра командной строки.
    Самый простой и предпочтительный способ.

  2. WM_COPYDATA
    Виртуальный принтер запускает указанную программу или ищет уже запущенный экземпляр, и посылает ей путь INI файла посредством сообщения WM_COPYDATA.

  3. Буфер обмена
    Виртуальный принтер запускает указанную программу или ищет уже запущенный экземпляр, размещает путь INI файла в буфере обмена и отправляет программе нотификацию.
    Устаревший метод, предназначен для старых программ.

 

Как изменить текущую форму страницы

int _iPaperCount = 0;
WORD* _pPapers = NULL;
char* _pPaperNames = NULL;
POINT* _pPaperSizes = NULL;

// функция для просмотра всех доступных форм страницы:

void FillPapers()
{
  HANDLE hPrinter = NULL;

  if (_pPapers)
  {
    delete [] _pPapers;
    _pPapers = NULL;
  }

  if (_pPaperNames)
  {
    delete [] _pPaperNames;
    _pPaperNames = NULL;
  }

  if (_pPaperSizes)
  {
    delete [] _pPaperSizes;
    _pPaperSizes = NULL;
  }

  if (OpenPrinter(PRINTER_NAME, &hPrinter, NULL))
  {
    DWORD dwNeeded = 0;
   
    // доступ к формам принтера

    _iPaperCount = DeviceCapabilities(PRINTER_NAME, NULL, DC_PAPERS, NULL, NULL);
    if (_iPaperCount)
    {
      _pPapers = new WORD[_iPaperCount];
      ZeroMemory(_pPapers, sizeof(WORD)*_iPaperCount);
      DeviceCapabilities(PRINTER_NAME, NULL, DC_PAPERS, (LPSTR) _pPapers, NULL);

      _pPaperNames = new char[_iPaperCount*64];
      ZeroMemory(_pPaperNames, sizeof(char)*64*_iPaperCount);
      DeviceCapabilities(PRINTER_NAME, NULL, DC_PAPERNAMES, _pPaperNames, NULL);

      _pPaperSizes = new POINT[_iPaperCount];
      ZeroMemory(_pPaperSizes, sizeof(POINT)*_iPaperCount);
      DeviceCapabilities(PRINTER_NAME, NULL, DC_PAPERSIZE, (LPSTR) _pPaperSizes, NULL);
    }
 
    ClosePrinter(hPrinter);
  }
  else
  {
    // отчет об ошибке
  }
}

// функция выбора текущей формы страницы:

BOOL SetPrinterPaper(short dmPaperSize, const char* pszFormName)
{
  BOOL bResult = FALSE;
  HANDLE hPrinter = NULL;

  if (OpenPrinter(PRINTER_NAME, &hPrinter, NULL))
  {
    DWORD dwNeeded = 0;
    GetPrinter(hPrinter, 2, NULL, 0, &dwNeeded);

    if (dwNeeded > 0)
    {
      BYTE* pPrinterInfo = new BYTE[dwNeeded];

      if (GetPrinter(hPrinter, 2, pPrinterInfo, dwNeeded, &dwNeeded))
      {
        DEVMODE* pDevMode = ((PRINTER_INFO_2*) pPrinterInfo)->pDevMode;
        pDevMode->dmPaperSize = dmPaperSize;
        lstrcpy((char*) &pDevMode->dmFormName, pszFormName);
        SetPrinter(hPrinter, 2, pPrinterInfo, 0);
        bResult = TRUE;
      }
      else
      {
        // отчет об ошибке
      }

      delete [] pPrinterInfo;
   }

   ClosePrinter(hPrinter);
  }
  else
  {
    // отчет об ошибке
  }

  return bResult;
}

 

Как добавить новую форму страницы нестандартного размера

if (OpenPrinter(PRINTER_NAME, &hPrinter, NULL))
{
  FORM_INFO_1 FormInfo = {0};
  FormInfo.pName = (char*) &_szNewFormName;
  FormInfo.Size.cx = FormInfo.ImageableArea.right = _iNewFormWidth*1000;
  FormInfo.Size.cy = FormInfo.ImageableArea.bottom = _iNewFormLength*1000;

  if (AddForm(hPrinter, 1, (BYTE*) &FormInfo))
  {
    FillPapers();

    // установка нового типа страниц

    for (int i=0; i<_iPaperCount; i++)
    {
      if (lstrcmp(_szNewFormName, &_pPaperNames[i*64]) == 0)
      {
        SetPrinterPaper(_pPapers[i], _szNewFormName);
        FillPapers();
        break;
      }
    }
  }
  else
  {
    // отчет об ошибке
  }

  ClosePrinter(hPrinter);
}

 

Как изменить ориентацию страницы и качество печати (разрешение)

HANDLE hPrinter = NULL;
PRINTER_DEFAULTS prnDef = { NULL, NULL, PRINTER_ALL_ACCESS };

if (OpenPrinter(PRINTER_NAME, &hPrinter, &prnDef))
{
  DWORD dwNeeded = 0;

  GetPrinter(hPrinter, 2, NULL, 0, &dwNeeded);
  if (dwNeeded > 0)
  {
    BYTE* pPrinterInfo = new BYTE[dwNeeded];

    // получение текущих параметров принтера
    if (GetPrinter(hPrinter, 2, pPrinterInfo, dwNeeded, &dwNeeded))
    {
      DEVMODE* pDevMode = ((PRINTER_INFO_2*) pPrinterInfo)->pDevMode;
      pDevMode->dmFields = pDevMode->dmFields|DM_ORIENTATION|DM_PRINTQUALITY|DM_YRESOLUTION;

      // изменение параметров
      pDevMode->dmOrientation = 1;  // ориентация страницы: 1-портретная, 2-пейзажная
      pDevMode->dmPrintQuality = 300;  // значение разрешения по горизонтали
      pDevMode->dmYResoultion = 300;  // значение разрешения по вертикали 

      // сохранение измененных установок
      if (!SetPrinter(hPrinter, 2, pPrinterInfo, 0))
      {
        // отчет об ошибке
      }
    }
    else
    {
      // отчет об ошибке
    }

    delete [] pPrinterInfo;
  }

  ClosePrinter(hPrinter);
}
else
{
  // отчет об ошибке
}

О компании | Контакты | Карта сайта

Copyright © 2000-2010 Two Pilots. Все права защищены.