背景:
“遍歷當前用戶的每一臺虛擬打印機,將其默認紙張設置為 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;
}