为什么我得不到虚拟打印机的上下文?
Why I don't get the context of the virtual printer?
Windows 8.1 x64
我已经安装了PdfCreater虚拟打印机。它是我电脑上的默认打印机(而且是单台打印机)。
现在我想获取它的上下文:
HDC GetPrinterDC(void)
{
PRINTER_INFO_5 pinfo5[3];
ZeroMemory(pinfo5, sizeof(pinfo5));
DWORD dwNeeded, dwReturned;
if (EnumPrinters(PRINTER_ENUM_DEFAULT, NULL, 5,
(LPBYTE)pinfo5, sizeof(pinfo5),
&dwNeeded, /* I get 0 */
&dwReturned /* I get 0 */)) {
// And I am here...
return CreateDC(NULL, pinfo5[0].pPrinterName, NULL, NULL); // NULL
}
return 0;
}
但我得到 NULL
。为什么会这样?
不要对第一个 EnumPrinters
的结果进行错误检查(Petzold 也不这样做)
另请注意,一台打印机所需的内存量可能为数百字节。但是 PRINTER_INFO_5 pinfo5[1];
分配的可能比那个少。所以你必须分配第一个 EnumPrinters
调用告诉你的内容。
HDC printerDC = NULL;
DWORD flags = PRINTER_ENUM_LOCAL;// | PRINTER_ENUM_CONNECTIONS;
DWORD memsize, printer_count;
//figure out how much memory we need
EnumPrinters(flags, NULL, 5, NULL, 0, &memsize, &printer_count);
if (memsize < 1) return;
//allocate memory
BYTE* bytes = new BYTE[memsize];
if (EnumPrinters(flags, NULL, 5, bytes, memsize, &memsize, &printer_count))
{
if (printer_count > 0)
{
PRINTER_INFO_5* printerInfo = (PRINTER_INFO_5*)bytes;
printerDC = CreateDC(NULL, printerInfo->pPrinterName, NULL, NULL);
//optional, list printer names
for (UINT i = 0; i < printer_count; i++)
{
OutputDebugString(printerInfo->pPrinterName);
OutputDebugString(L"\n");
printerInfo++;
}
}
}
delete[] bytes;
如果您想访问默认打印机,另一种选择是使用 PRINTDLG
(实际上不显示任何打印对话框)
PRINTDLG pdlg;
memset(&pdlg, 0, sizeof(PRINTDLG));
pdlg.lStructSize = sizeof(PRINTDLG);
// Set the flag to return printer DC, but don't show dialog
pdlg.Flags = PD_RETURNDEFAULT | PD_RETURNDC;
PrintDlg(&pdlg);
printerDC = pdlg.hDC;
另见
How To Print a Document
How To: Retrieve a Printer Device Context
Windows 8.1 x64
我已经安装了PdfCreater虚拟打印机。它是我电脑上的默认打印机(而且是单台打印机)。
现在我想获取它的上下文:
HDC GetPrinterDC(void)
{
PRINTER_INFO_5 pinfo5[3];
ZeroMemory(pinfo5, sizeof(pinfo5));
DWORD dwNeeded, dwReturned;
if (EnumPrinters(PRINTER_ENUM_DEFAULT, NULL, 5,
(LPBYTE)pinfo5, sizeof(pinfo5),
&dwNeeded, /* I get 0 */
&dwReturned /* I get 0 */)) {
// And I am here...
return CreateDC(NULL, pinfo5[0].pPrinterName, NULL, NULL); // NULL
}
return 0;
}
但我得到 NULL
。为什么会这样?
不要对第一个 EnumPrinters
的结果进行错误检查(Petzold 也不这样做)
另请注意,一台打印机所需的内存量可能为数百字节。但是 PRINTER_INFO_5 pinfo5[1];
分配的可能比那个少。所以你必须分配第一个 EnumPrinters
调用告诉你的内容。
HDC printerDC = NULL;
DWORD flags = PRINTER_ENUM_LOCAL;// | PRINTER_ENUM_CONNECTIONS;
DWORD memsize, printer_count;
//figure out how much memory we need
EnumPrinters(flags, NULL, 5, NULL, 0, &memsize, &printer_count);
if (memsize < 1) return;
//allocate memory
BYTE* bytes = new BYTE[memsize];
if (EnumPrinters(flags, NULL, 5, bytes, memsize, &memsize, &printer_count))
{
if (printer_count > 0)
{
PRINTER_INFO_5* printerInfo = (PRINTER_INFO_5*)bytes;
printerDC = CreateDC(NULL, printerInfo->pPrinterName, NULL, NULL);
//optional, list printer names
for (UINT i = 0; i < printer_count; i++)
{
OutputDebugString(printerInfo->pPrinterName);
OutputDebugString(L"\n");
printerInfo++;
}
}
}
delete[] bytes;
如果您想访问默认打印机,另一种选择是使用 PRINTDLG
(实际上不显示任何打印对话框)
PRINTDLG pdlg;
memset(&pdlg, 0, sizeof(PRINTDLG));
pdlg.lStructSize = sizeof(PRINTDLG);
// Set the flag to return printer DC, but don't show dialog
pdlg.Flags = PD_RETURNDEFAULT | PD_RETURNDC;
PrintDlg(&pdlg);
printerDC = pdlg.hDC;
另见
How To Print a Document
How To: Retrieve a Printer Device Context