Печать файлов произвольного типа
От: dimok@  
Дата: 18.12.02 11:50
Оценка:
Нужна возможность печати из приложения любых файлов, которые умеют печатать винды. При этом нужно получить JobId.
Вообще-то задача стоит глубже, надо получить SPL-файл с форматом данных EMF (я его умею разбирать), при этом реальная печать не должна происходить. Сейчас есть свой драйвер виртуального принтера, виртуальный порт, и т.п.
Или еще глубже — графическое изображение произвольного файла! Есть ли пути короче?
Re: Печать файлов произвольного типа
От: DreadDog Россия  
Дата: 18.12.02 13:57
Оценка:
Здравствуйте, dimok@, Вы писали:

D>Или еще глубже — графическое изображение произвольного файла! Есть ли пути короче?

У нас стояла аналогичная задача, но там формулировалось как печать на виртуальный принтер UDC (Universal Data Converter) файлов с определенными расширениями и складывание их в тот же каталог в свои подпапки. Печатали через ShellExecute(..,"print",..). Если отправить не удалось — переходим к следующему файлу, иначе — ждем пока у этого принтера есть работа — использовалась функция из MSDN:

   BOOL GetJobs(HANDLE hPrinter,        /* Handle to the printer. */ 
                JOB_INFO_2 **ppJobInfo, /* Pointer to be filled.  */ 
                int *pcJobs,            /* Count of jobs filled.  */ 
                DWORD *pStatus)         /* Print Queue status.    */ 

   {
      DWORD               cByteNeeded,
                          nReturned,
                          cByteUsed;
      JOB_INFO_2          *pJobStorage = NULL;
      PRINTER_INFO_2      *pPrinterInfo = NULL;

   /* Get the buffer size needed. */ 
       if (!GetPrinter(hPrinter, 2, NULL, 0, &cByteNeeded))
       {
           if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
               return FALSE;
       }

       pPrinterInfo = (PRINTER_INFO_2 *)malloc(cByteNeeded);
       if (!(pPrinterInfo))
           /* Failure to allocate memory. */ 
           return FALSE;

       /* Get the printer information. */ 
       if (!GetPrinter(hPrinter,
               2,
               (unsigned char *)pPrinterInfo,
               cByteNeeded,
               &cByteUsed))
       {
           /* Failure to access the printer. */ 
           free(pPrinterInfo);
           pPrinterInfo = NULL;
           return FALSE;
       }

       /* Get job storage space. */ 
       if (!EnumJobs(hPrinter,
               0,
               pPrinterInfo->cJobs,
               2,
               NULL,
               0,
               (LPDWORD)&cByteNeeded,
               (LPDWORD)&nReturned))
       {
           if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
           {
               free(pPrinterInfo);
               pPrinterInfo = NULL;
               return FALSE;
           }
       }

       pJobStorage = (JOB_INFO_2 *)malloc(cByteNeeded);
       if (!pJobStorage)
       {
           /* Failure to allocate Job storage space. */ 
           free(pPrinterInfo);
           pPrinterInfo = NULL;
           return FALSE;
       }

       ZeroMemory(pJobStorage, cByteNeeded);

       /* Get the list of jobs. */ 
       if (!EnumJobs(hPrinter,
               0,
               pPrinterInfo->cJobs,
               2,
               (LPBYTE)pJobStorage,
               cByteNeeded,
               (LPDWORD)&cByteUsed,
               (LPDWORD)&nReturned))
       {
           free(pPrinterInfo);
           free(pJobStorage);
           pJobStorage = NULL;
           pPrinterInfo = NULL;
           return FALSE;
       }

       /*
        *  Return the information.
        */ 
       *pcJobs = nReturned;
       *pStatus = pPrinterInfo->Status;
       *ppJobInfo = pJobStorage;
       free(pPrinterInfo);

       return TRUE;

   }


Код использования такой:


// ... Preparing Directories
        DWORD flags;
    if (!hSpy)
    {
        hSpy = FindFirstPrinterChangeNotification( pHandle, PRINTER_CHANGE_ADD_JOB, 0, NULL );
    } else 
        FindNextPrinterChangeNotification( hSpy, &flags, NULL, NULL );    
    if ( hSpy == INVALID_HANDLE_VALUE )
         DWORD error = GetLastError();

    HINSTANCE error = ShellExecute( NULL, "print", _T(fullpath), NULL, NULL, SW_SHOWNOACTIVATE );
    if (((int)error) <= 32)
    { // Error
       printf(" - ERROR\n");
           RemoveDirectory(str);
       return;
    }

    JOB_INFO_2 *    info;
    int        num;
    DWORD        status;

    GetJobs(pHandle, &info, &num, &status);
    WaitForSingleObject( hSpy, INFINITE );
    // Wait For End Job
    while (1)
    {
        GetJobs(pHandle, &info, &num, &status);
        if (num == 0)
            break;
        Sleep(1);
    }
    MoveDirectory(str);
    printf(" - SUCCESS\n");


Может это можно использовать ?
Re[2]: Печать файлов произвольного типа
От: dimok@  
Дата: 18.12.02 14:20
Оценка:
А каким образом мы печатаем на нужный принтер? Он должен быть принтером по умолчанию?
И как мы узнаем свое задание? Вдруг кто-то еще печатает?
Re[3]: Печать файлов произвольного типа
От: DreadDog Россия  
Дата: 18.12.02 14:57
Оценка:
Здравствуйте, dimok@, Вы писали:

D>А каким образом мы печатаем на нужный принтер? Он должен быть принтером по умолчанию?

Да нам этого хватало, но ты либо предоставляешь пользователю возможность выбрать либо:

bool Open ()
{
  // Get Default Printer Name 
  BOOL founded = FALSE;
  TCHAR  Name[512];

  DWORD cbNeeded = 0, dwReturned = 0;
  EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &cbNeeded, &dwReturned);
  if (cbNeeded)
  {
    PRINTER_INFO_2* pPI2 = (PRINTER_INFO_2*) GlobalAllocPtr(GHND, cbNeeded);
    if (pPI2)
    {
    if (EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 2, LPBYTE(pPI2), cbNeeded, &cbNeeded, &dwReturned))
    {
        for (DWORD i = 0; i < dwReturned; i++)
        {                            
        if (pPI2[i].Attributes & PRINTER_ATTRIBUTE_DEFAULT == 0)
           continue;
        strcpy(Name, pPI2[i].pPrinterName);
        founded = TRUE;
        break;
        }            
        }
    }
    DWORD error = GetLastError();
    GlobalFreePtr(pPI2);
   }
   if (!founded)
      return false;

   TCHAR  str[512];
   strcpy(str, Name);
   BOOL ret = OpenPrinter(str, (LPHANDLE) &pHandle, &pdef);
   if (!ret)
   {
      DWORD error = GetLastError();
   }
   return true;
}


делаешь как то так но сравниваешь название.

D>И как мы узнаем свое задание? Вдруг кто-то еще печатает?


Не знаю. Начал печатать пиши куда-нибудь а потом сравнивай.
Ты сам начинаешь печатать? Или нет?

Привет, Константин.
Re[4]: Печать файлов произвольного типа
От: dimok@  
Дата: 18.12.02 15:16
Оценка:
Получить имя дефолтного принтера можно проще: GetDefaultPrinter.
В моем случае печатают несколько потоков программы, которые не интерактивны, занимаются своим делом. Иногда им надо получить изображение отчетов, чтобы потом отослать по факсу. Ясно, что печатать они могут и одновременно. А принтер всегда нужен мой — виртуальный. Требовать сделать его принтером по умолчанию — не практично! Устанавливать его таким временно — криво, особенно в моем случае. Потоки передеруться, да и процедура эта не из простых, нашлась статейка в MSDNе.
Re: Печать файлов произвольного типа
От: ilnar Россия  
Дата: 20.12.02 14:48
Оценка:
Здравствуйте, dimok@, Вы писали:

D>Нужна возможность печати из приложения любых файлов, которые умеют печатать винды. При этом нужно получить JobId.

D>Вообще-то задача стоит глубже, надо получить SPL-файл с форматом данных EMF (я его умею разбирать), при этом реальная печать не должна происходить. Сейчас есть свой драйвер виртуального принтера, виртуальный порт, и т.п.
D>Или еще глубже — графическое изображение произвольного файла! Есть ли пути короче?

возьми PostScript
Re[2]: Печать файлов произвольного типа
От: dimok@  
Дата: 20.12.02 15:02
Оценка:
Здравствуйте, ilnar, Вы писали:

I>Здравствуйте, dimok@, Вы писали:


I>возьми PostScript


Можно поподробнее?!!
Re[5]: Печать файлов произвольного типа
От: dimok@  
Дата: 20.12.02 15:07
Оценка:
Ладно, отвечу сам себе! Вдруг кому пригодиться!
После некоторых экспериментов выяснилось!!!
ShellExecute(NULL,"printto",FileName,PrinterName,NULL,SW_SHOWMINNOACTIVE);

Это то, что касается печати на нужном принтере!!!
Re[3]: Печать файлов произвольного типа
От: ilnar Россия  
Дата: 20.12.02 15:12
Оценка:
Здравствуйте, dimok@, Вы писали:

D>Здравствуйте, ilnar, Вы писали:


I>>Здравствуйте, dimok@, Вы писали:


I>>возьми PostScript


D>Можно поподробнее?!!


я правильно понял, что нужно любые документы печатать? и держать как-то в общем виде?
если да, переводишь в постскрипт формат и все готово, принтера его понимают (правда не все).
Re[4]: Печать файлов произвольного типа
От: dimok@  
Дата: 20.12.02 15:26
Оценка:
Здравствуйте, ilnar, Вы писали:

I>я правильно понял, что нужно любые документы печатать? и держать как-то в общем виде?

I>если да, переводишь в постскрипт формат и все готово, принтера его понимают (правда не все).

Проблема немного другая, нужно переводить готовые уже документы (txt, htm, doc, xls, ...) в растровый формат для отправки по факсу.
О постскрипте (пока ничего не знаю! Может он мне помочь? Сейчас использую EMF в качестве переходного формата, т.к. именно он создается при печати!
Re[5]: Печать файлов произвольного типа
От: ilnar Россия  
Дата: 20.12.02 17:34
Оценка:
Здравствуйте, dimok@, Вы писали:

D>Здравствуйте, ilnar, Вы писали:


I>>я правильно понял, что нужно любые документы печатать? и держать как-то в общем виде?

I>>если да, переводишь в постскрипт формат и все готово, принтера его понимают (правда не все).

D>Проблема немного другая, нужно переводить готовые уже документы (txt, htm, doc, xls, ...) в растровый формат для отправки по факсу.

D>О постскрипте (пока ничего не знаю! Может он мне помочь? Сейчас использую EMF в качестве переходного формата, т.к. именно он создается при печати!

www.adobe.com — разработчик постскрипт, документ в этом формате содержит и шрифты при необходимости, и векторную графику, и текст. также является языком программирования.
в виндах перевод документов в постскрипт не пробовал, а в линухе очень много различных прог, которые качественно переводят разные доки (текст, изображение, html, ....) в постскрипт формат. в виндах с этим хуже.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.