使用 SetPrinter() 设置双面模式不起作用

问题描述 投票:0回答:1

我尝试在打印机上设置双面(双面)模式,但调用

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;
}

我有这样的消息:

设置打印机不工作

c++ windows winapi printing
1个回答
0
投票

根据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;
}
© www.soinside.com 2019 - 2024. All rights reserved.