MFC:获取所有打印机的名称(打印机模块-2)

背景:

"遍历当前用户的每一台虚拟打印机,将其默认纸张设置为 A4 并设置为纵向。"

实现原理:

1.从当前用户的注册表读取所有已配置的打印机;

2.遍历每台打印机;

3.输出其逻辑与实际纸张大小;

4.尝试设置为 A4 纸,纵向;

5.输出设置是否成功。

cpp 复制代码
#include <Windows.h>
#include <stdio.h>

void SetPrinterPaperSizeAndOrientation(HANDLE hPrinter, int nPaperIndex, int nOrientation)
{
    DEVMODE devMode;
    memset(&devMode, 0, sizeof(DEVMODE));
    devMode.dmSize = sizeof(DEVMODE);
    
    // 获取当前打印机的设备模式
    if (DocumentProperties(NULL, hPrinter, NULL, &devMode, NULL, DM_OUT_BUFFER) != IDOK)
    {
        // 获取设备模式失败
        return;
    }
    
    // 修改纸张大小和方向
    devMode.dmPaperSize = nPaperIndex; // 设置纸张大小
    devMode.dmOrientation = nOrientation; // 设置纸张方向

    // 更新打印机的设备模式
    if (DocumentProperties(NULL, hPrinter, NULL, &devMode, &devMode, DM_IN_BUFFER | DM_OUT_BUFFER) != IDOK)
    {
        // 更新设备模式失败
        return;
    }

    // 获取逻辑高度和实际高度
    int nLogicHeight = devMode.dmPelsHeight; // 逻辑高度
    int nActualHeight = devMode.dmYResolution; // 实际高度
}

// 获取打印机纸张信息
void GetPrinterPaperInfo(const TCHAR* pszPrinterName, int& nLogicalWidth, int& nLogicalHeight, int& nPhysicalWidth, int& nPhysicalHeight)
{
    HKEY hKey;
    LONG lResult;

    // 构造打印机注册表项路径
    TCHAR szKeyPath[MAX_PATH];
    _stprintf_s(szKeyPath, _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers\\%s\\PrinterDriverData"), pszPrinterName);

    // 打开打印机注册表项
    lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyPath, 0, KEY_READ, &hKey);
    if (lResult == ERROR_SUCCESS)
    {
        TCHAR szData[MAX_PATH];
        DWORD dwDataSize = sizeof(szData);

        // 获取逻辑纸张宽度
        lResult = RegQueryValueEx(hKey, _T("PaperWidth"), NULL, NULL, (LPBYTE)szData, &dwDataSize);
if (lResult == ERROR_SUCCESS)
{
    // 正确处理数据
    printf("Value data: %s\n", szData);
}
else if (lResult == ERROR_MORE_DATA)
{
    printf("Buffer size too small\n");
}
else if (lResult == ERROR_INVALID_PARAMETER)
{
    printf("Invalid parameter\n");
}
else
{
    printf("Error querying default registry value: %d\n", lResult);
}
        if (lResult == ERROR_SUCCESS)
        {
            sscanf_s(szData, "%d", &nLogicalWidth);
        }

        // 获取逻辑纸张高度
        lResult = RegQueryValueEx(hKey, _T("PaperHeight"), NULL, NULL, (LPBYTE)szData, &dwDataSize);
        if (lResult == ERROR_SUCCESS)
        {
            sscanf_s(szData, "%d", &nLogicalHeight);
        }

        // 获取实际纸张宽度
        lResult = RegQueryValueEx(hKey, _T("PaperWidthActual"), NULL, NULL, (LPBYTE)szData, &dwDataSize);
        if (lResult == ERROR_SUCCESS)
        {
            sscanf_s(szData, "%d", &nPhysicalWidth);
        }

        // 获取实际纸张高度
        lResult = RegQueryValueEx(hKey, _T("PaperHeightActual"), NULL, NULL, (LPBYTE)szData, &dwDataSize);
        if (lResult == ERROR_SUCCESS)
        {
            sscanf_s(szData, "%d", &nPhysicalHeight);
        }

        RegCloseKey(hKey);
    }
}

int main()
{
    HKEY hKey;
    LONG lResult;
    DWORD dwIndex = 0;
    TCHAR szPrinterName[MAX_PATH];
    DWORD dwSize = sizeof(szPrinterName);

    // 打开打印机列表注册表项
    lResult = RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\Devices"), 0, KEY_READ, &hKey);
    if (lResult == ERROR_SUCCESS)
    {
        // 遍历打印机列表
        while (RegEnumKeyEx(hKey, dwIndex, szPrinterName, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
        {
            int nLogicalWidth = 0; // 逻辑纸张宽度
            int nLogicalHeight = 0; // 逻辑纸张高度
            int nPhysicalWidth = 0; // 实际纸张宽度
            int nPhysicalHeight = 0; // 实际纸张高度

            // 获取打印机纸张信息
            GetPrinterPaperInfo(szPrinterName, nLogicalWidth, nLogicalHeight, nPhysicalWidth, nPhysicalHeight);

            // 输出获取的纸张信息
            printf("Printer Name: %s\n", szPrinterName);
            printf("Logical Paper Size: %d x %d\n", nLogicalWidth, nLogicalHeight);
            printf("Physical Paper Size: %d x %d\n", nPhysicalWidth, nPhysicalHeight);

            // 重置打印机名称缓冲区大小
            dwSize = sizeof(szPrinterName);
            dwIndex++;
        }

        RegCloseKey(hKey);
    }

    return 0;
}
相关推荐
学习路上_write几秒前
FREERTOS_互斥量_创建和使用
c语言·开发语言·c++·stm32·单片机·嵌入式硬件
闻缺陷则喜何志丹1 小时前
【SOSDP模板 容斥原理 逆向思考】3757. 有效子序列的数量|分数未知
c++·算法·力扣·容斥原理·sosdp·逆向思考
BestOrNothing_20152 小时前
一篇搞懂 C++ 重载:函数重载 + 运算符重载,从入门到会用(含 ++、<<、== 实战)
c++·函数重载·运算符重载·operator·前置后置++·重载与重写
2501_941144422 小时前
Python + C++ 异构微服务设计与优化
c++·python·微服务
程序猿编码2 小时前
PRINCE算法的密码生成器:原理与设计思路(C/C++代码实现)
c语言·网络·c++·算法·安全·prince
charlie1145141913 小时前
深入理解C/C++的编译链接技术6——A2:动态库设计基础之ABI设计接口
c语言·开发语言·c++·学习·动态库·函数
Cx330❀3 小时前
C++ STL set 完全指南:从基础用法到实战技巧
开发语言·数据结构·c++·算法·leetcode·面试
zmzb01033 小时前
C++课后习题训练记录Day33
开发语言·c++
Want5953 小时前
C/C++贪吃蛇小游戏
c语言·开发语言·c++
草莓熊Lotso4 小时前
《算法闯关指南:动态规划算法--斐波拉契数列模型》--01.第N个泰波拉契数,02.三步问题
开发语言·c++·经验分享·笔记·其他·算法·动态规划