背景:
“遍历当前用户的每一台虚拟打印机,将其默认纸张设置为 A4 并设置为纵向。”
实现原理:
1.从当前用户的注册表读取所有已配置的打印机;
2.遍历每台打印机;
3.输出其逻辑与实际纸张大小;
4.尝试设置为 A4 纸,纵向;
5.输出设置是否成功。
#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;
}