我尝试在打印机上设置双面(双面)模式,但调用
SetPrinter()
不起作用:
bool SetDuplexMode(HANDLE hPrinter, short duplexMode) {
PRINTER_INFO_2* pInfo = NULL;
DWORD dwNeeded = 0;
GetPrinter(hPrinter, 2, NULL, 0, &dwNeeded);
pInfo = (PRINTER_INFO_2*)malloc(dwNeeded);
if (!GetPrinter(hPrinter, 2, (LPBYTE)pInfo, dwNeeded, &dwNeeded)) {
free(pInfo);
return false;
}
DEVMODE* pDevMode = pInfo->pDevMode;
if (!pDevMode) {
free(pInfo);
return false;
}
pDevMode->dmFields |= DM_DUPLEX;
pDevMode->dmDuplex = duplexMode;
if (!SetPrinter(hPrinter, 2, (LPBYTE)pInfo, 0)) {
std::wcout << L"SetPrinter not working" << L'\n';
free(pInfo);
return false;
}
free(pInfo);
return true;
}
我有这样的消息:
设置打印机不工作
根据Q140285:如何使用SetPrinter修改打印机设置:
另外,因为修改 DEVMODE 中设备无关部分的字段也可能会影响设备相关部分的更改,所以 您需要在调用 SetPrinter() 之前调用 DocumentProperties() 以便为 SetPrinter() 制作一致的 DEVMODE 结构).
您还必须考虑到
GetPrinter()
可能会返回 NULL DEVMODE*
指针,在这种情况下,您必须调用 DocumentProperties()
来获取 DEVMODE
才能进行任何更改。
您还应该在调用
pDevMode->dmFields |= DM_DUPLEX;
之前将 pDevMode->dmFields = DM_DUPLEX;
更改为 SetPrinter()
,以便它知道您只更改 1 个字段,而不是 GetPrinter()
为您提供的所有字段。
话虽如此,尝试更多类似这样的事情:
#include <vector>
bool SetDuplexMode(HANDLE hPrinter, LPTSTR pPrinterName, short duplexMode)
{
DWORD dwNeeded = 0;
if (!GetPrinter(hPrinter, 2, nullptr, 0, &dwNeeded))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
std::wcout << L"GetPrinter failed\n";
return false;
}
}
if (dwNeeded == 0)
return false;
std::vector<BYTE> infoBuffer(dwNeeded);
if (!GetPrinter(hPrinter, 2, infoBuffer.data(), dwNeeded, &dwNeeded))
{
std::wcout << L"GetPrinter failed\n";
return false;
}
PRINTER_INFO_2* pInfo = reinterpret_cast<PRINTER_INFO_2*>(infoBuffer.data());
DEVMODE* pDevMode = pInfo->pDevMode;
std::vector<BYTE> devModeBuffer;
if (!pDevMode)
{
LONG lNeeded = DocumentProperties(nullptr, hPrinter, pPrinterName, nullptr, nullptr, 0);
if (lNeeded <= 0)
{
std::wcout << L"DocumentProperties failed\n";
return false;
}
devModeBuffer.resize(lNeeded);
pDevMode = reinterpret_cast<DEVMODE*>(devModeBuffer.data());
if (DocumentProperties(nullptr, hPrinter, pPrinterName, pDevMode, nullptr, DM_OUT_BUFFER) != IDOK)
{
std::wcout << L"DocumentProperties failed\n";
return false;
}
pInfo->pDevMode = pDevMode;
}
if (!(pDevMode->dmFields & DM_DUPLEX))
{
std::wcout << L"Printer does not support duplex mode\n";
return false;
}
pDevMode->dmFields = DM_DUPLEX;
pDevMode->dmDuplex = duplexMode;
pInfo->pSecurityDescriptor = NULL;
if (DocumentProperties(nullptr, hPrinter, pPrinterName, pDevMode, pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER) != IDOK)
{
std::wcout << L"DocumentProperties failed\n";
return false;
}
if (!SetPrinter(hPrinter, 2, reinterpret_cast<LPBYTE>(pInfo), 0))
{
std::wcout << L"SetPrinter failed\n";
return false;
}
return true;
}