Нужна возможность печати из приложения любых файлов, которые умеют печатать винды. При этом нужно получить JobId.
Вообще-то задача стоит глубже, надо получить SPL-файл с форматом данных EMF (я его умею разбирать), при этом реальная печать не должна происходить. Сейчас есть свой драйвер виртуального принтера, виртуальный порт, и т.п.
Или еще глубже — графическое изображение произвольного файла! Есть ли пути короче?
Здравствуйте, 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;
}
Здравствуйте, 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>И как мы узнаем свое задание? Вдруг кто-то еще печатает?
Не знаю. Начал печатать пиши куда-нибудь а потом сравнивай.
Ты сам начинаешь печатать? Или нет?
Получить имя дефолтного принтера можно проще: GetDefaultPrinter.
В моем случае печатают несколько потоков программы, которые не интерактивны, занимаются своим делом. Иногда им надо получить изображение отчетов, чтобы потом отослать по факсу. Ясно, что печатать они могут и одновременно. А принтер всегда нужен мой — виртуальный. Требовать сделать его принтером по умолчанию — не практично! Устанавливать его таким временно — криво, особенно в моем случае. Потоки передеруться, да и процедура эта не из простых, нашлась статейка в MSDNе.
Здравствуйте, dimok@, Вы писали:
D>Нужна возможность печати из приложения любых файлов, которые умеют печатать винды. При этом нужно получить JobId. D>Вообще-то задача стоит глубже, надо получить SPL-файл с форматом данных EMF (я его умею разбирать), при этом реальная печать не должна происходить. Сейчас есть свой драйвер виртуального принтера, виртуальный порт, и т.п. D>Или еще глубже — графическое изображение произвольного файла! Есть ли пути короче?
Здравствуйте, dimok@, Вы писали:
D>Здравствуйте, ilnar, Вы писали:
I>>Здравствуйте, dimok@, Вы писали:
I>>возьми PostScript
D>Можно поподробнее?!!
я правильно понял, что нужно любые документы печатать? и держать как-то в общем виде?
если да, переводишь в постскрипт формат и все готово, принтера его понимают (правда не все).
Здравствуйте, ilnar, Вы писали:
I>я правильно понял, что нужно любые документы печатать? и держать как-то в общем виде? I>если да, переводишь в постскрипт формат и все готово, принтера его понимают (правда не все).
Проблема немного другая, нужно переводить готовые уже документы (txt, htm, doc, xls, ...) в растровый формат для отправки по факсу.
О постскрипте (пока ничего не знаю! Может он мне помочь? Сейчас использую EMF в качестве переходного формата, т.к. именно он создается при печати!
Здравствуйте, dimok@, Вы писали:
D>Здравствуйте, ilnar, Вы писали:
I>>я правильно понял, что нужно любые документы печатать? и держать как-то в общем виде? I>>если да, переводишь в постскрипт формат и все готово, принтера его понимают (правда не все).
D>Проблема немного другая, нужно переводить готовые уже документы (txt, htm, doc, xls, ...) в растровый формат для отправки по факсу. D>О постскрипте (пока ничего не знаю! Может он мне помочь? Сейчас использую EMF в качестве переходного формата, т.к. именно он создается при печати!
www.adobe.com — разработчик постскрипт, документ в этом формате содержит и шрифты при необходимости, и векторную графику, и текст. также является языком программирования.
в виндах перевод документов в постскрипт не пробовал, а в линухе очень много различных прог, которые качественно переводят разные доки (текст, изображение, html, ....) в постскрипт формат. в виндах с этим хуже.