网络打印机的DeviceCapabilities

时间:2016-08-19 18:32:09

标签: c++ winapi networking printing gdi+

我尝试使用DeviceCapabilities获取网络打印机支持的页面大小列表,并与sPort参数完全混淆。

DWORD nPapersCount = ::DeviceCapabilities(sPrinter, sPort, DC_PAPERS, nullptr, nullptr);

有人可以建议我,我应该在sPort中为网络打印机提供什么?我怎样才能可靠地获得该端口?

作为实验,我尝试了格式的电脑名称" \\ Share",其端口" \\ Share \ LPT1",只是" LPT1"并且没有运气。

另外,我发现了EnumPorts功能,所以我可以获得远程服务器上的打印机端口列表,但我不知道如何在服务器上有多台打印机的情况下处理端口列表

typedef struct _PORT_INFO_2 {
  LPTSTR pPortName;
  LPTSTR pMonitorName;
  LPTSTR pDescription;
  DWORD  fPortType;
  DWORD  Reserved;
} PORT_INFO_2, *PPORT_INFO_2;

2 个答案:

答案 0 :(得分:2)

您无法猜测端口名,特别是在网络打印机的情况下。使用PrintDlg从当前选定的打印机获取信息(这可以在不显示打印对话框的情况下完成)。

Portname可通过PRINTDLG结构的hDevNames成员获取。

DEVNAMES structure

typedef struct tagDEVNAMES {
  WORD wDriverOffset;
  WORD wDeviceOffset;
  WORD wOutputOffset; //<= port name
  WORD wDefault;
} DEVNAMES, *LPDEVNAMES;

Unicode示例:

PRINTDLG pdlg = { sizeof PRINTDLG };
pdlg.Flags = PD_RETURNDEFAULT;
PrintDlg(&pdlg);

LPDEVNAMES lpDev = (LPDEVNAMES)GlobalLock(pdlg.hDevNames);
std::wstring device = (LPCTSTR)lpDev + lpDev->wDeviceOffset;
std::wstring port = (LPCTSTR)lpDev + lpDev->wOutputOffset;
::GlobalUnlock(pdlg.hDevNames);

//clean up after PrintDlg, as pointed out by @RemyLebeau
GlobalFree(pdlg.hDevMode);
GlobalFree(pdlg.hDevNames);

int nPapersCount;
nPapersCount = ::DeviceCapabilities(device.c_str(), port.c_str(), DC_PAPERS, NULL, NULL);
if (nPapersCount > 0)
{
    WORD* sizeBuf = new WORD[nPapersCount];
    DeviceCapabilities(device.c_str(), port.c_str(), DC_PAPERS, (LPTSTR)sizeBuf, NULL);
    for (int i = 0; i < nPapersCount; i++)
        std::wcout << sizeBuf[i] << "\n";
    delete[] sizeBuf;
}

答案 1 :(得分:0)

使用 PrintDlg 有点笨拙,缺点是它只能让您查询默认打印机 (AFAIK)。更好的选择是使用 GetPrinter,请求的输出级别为 5:

HANDLE h = NULL;
OpenPrinter(printerName, &h, NULL);  // printerName is a LPWSTR
if (!h) 
    return;
DWORD cbBuf=0;
GetPrinter(h, 5, NULL, 0, &cbBuf);
    // First call to GetPrinter determines an output buffer size
BYTE *buf = new BYTE[cbBuf];
if (!GetPrinter(h, 5, buf, cbBuf, &cbBuf))
    { ClosePrinter(h);  return; }
PRINTER_INFO_5 *ppi = (PRINTER_INFO_5*) buf;
LPWSTR port = ppi->pPortName;
ClosePrinter(h);