C++ 网络打印机的设备容量

C++ 网络打印机的设备容量,c++,winapi,networking,printing,gdi+,C++,Winapi,Networking,Printing,Gdi+,我试图使用DeviceCapabilities获取网络打印机支持的页面大小列表,但完全与sPort参数混淆 DWORD nPapersCount = ::DeviceCapabilities(sPrinter, sPort, DC_PAPERS, nullptr, nullptr); 有谁能告诉我,我应该在sPort中为网络打印机提供什么,以及如何可靠地获得该端口 作为实验,我尝试了PC名称的格式“\\Share”,其端口“\\Share\LPT1”,只是“LPT1”,但没有运气 此外,我还发

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

DWORD nPapersCount = ::DeviceCapabilities(sPrinter, sPort, DC_PAPERS, nullptr, nullptr);
有谁能告诉我,我应该在sPort中为网络打印机提供什么,以及如何可靠地获得该端口

作为实验,我尝试了PC名称的格式“\\Share”,其端口“\\Share\LPT1”,只是“LPT1”,但没有运气

此外,我还发现了
EnumPorts
函数,因此我可以获得远程服务器上的打印机端口列表,但我不知道如何处理服务器上多台打印机的端口列表


您无法猜测端口名,尤其是在网络打印机的情况下。用于从当前选定的打印机获取信息(无需显示打印对话框即可完成此操作)

Portname可通过结构的成员
hDevNames
获得

:

typedef结构标记devnames{
字偏移量;
单词wDeviceOffset;
WORD wOutputOffset;//wDeviceOffset;
std::wstring端口=(LPCTSTR)lpDev+lpDev->wOutputOffset;
::GlobalUnlock(pdlg.hDevNames);
//如@RemyLebeau所指出的,打印后进行清理
GlobalFree(pdlg.hDevMode);
GlobalFree(pdlg.hDevNames);
国际人口统计;
nPapersCount=::设备容量(device.c_str(),port.c_str(),DC_PAPERS,NULL,NULL);
如果(nPapersCount>0)
{
WORD*sizeBuf=新词[nPapersCount];
设备容量(device.c_str(),port.c_str(),DC_PAPERS,(LPTSTR)sizeBuf,NULL);
对于(int i=0;istd::wcout使用完后,不要忘记释放
PRINTDLG
结构中的
hDevMode
hDevNames
hDC
句柄。使用
GlobalFree()
DeleteDC()
。你确定你需要
PD_RETURNDC
,但是?你没有使用
hDC
做任何事情。@RemyLebeau没有分配,所以不需要
GlobalFree
。也没有DC。
PD_RETURNDC
是不必要的,我删除了它。文档清楚地说明
hDevMode
如果输入时为空,
hDevNames
将被分配。它没有说明
PD_RETURNDEFAULT
是否会改变这种行为。它只说明它们被设置为系统默认打印机的句柄。它们是被分配的吗?还是静态的,由操作系统所有?文档没有说明这两种方式。但大多数
PD_RETURNDEFAULT
我可以在它们上面找到call
GlobalFree()
。@RemyLebeau你是对的。我必须调用
GlobalFree
,否则内存会泄漏。文档不是很清楚。
typedef struct _PORT_INFO_2 {
  LPTSTR pPortName;
  LPTSTR pMonitorName;
  LPTSTR pDescription;
  DWORD  fPortType;
  DWORD  Reserved;
} PORT_INFO_2, *PPORT_INFO_2;
typedef struct tagDEVNAMES {
  WORD wDriverOffset;
  WORD wDeviceOffset;
  WORD wOutputOffset; //<= port name
  WORD wDefault;
} DEVNAMES, *LPDEVNAMES;
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;
}