GetDeviceCaps所有印表機物理參數均透過 GetDeviceCaps(Printer->Handle, nIndex) 取得,Printer 為 VCL TPrinter 實例。
int dpiX = GetDeviceCaps(Printer->Handle, LOGPIXELSX); // 水平 DPI
int dpiY = GetDeviceCaps(Printer->Handle, LOGPIXELSY); // 垂直 DPI
典型值:600, 1200, 2400 DPI。注意:部分印表機水平/垂直 DPI 不同。
| 屬性 | VCL 屬性 | API 常數 | 說明 |
|---|---|---|---|
| 可列印寬度 | Printer->PageWidth | HORZRES | 扣除邊界後可用像素 |
| 可列印高度 | Printer->PageHeight | VERTRES | 扣除邊界後可用像素 |
| 物理寬度 | — | PHYSICALWIDTH | 含不可列印邊界的完整像素 |
| 物理高度 | — | PHYSICALHEIGHT | 含不可列印邊界的完整像素 |
| 物理左邊距 | — | PHYSICALOFFSETX | 從物理左緣到可列印區左緣的像素 |
| 物理上邊距 | — | PHYSICALOFFSETY | 從物理上緣到可列印區上緣的像素 |
double paperWidthInch = (double)GetDeviceCaps(Printer->Handle, PHYSICALWIDTH) / dpiX;
double paperHeightInch = (double)GetDeviceCaps(Printer->Handle, PHYSICALHEIGHT) / dpiY;
double paperWidthCm = paperWidthInch * 2.54;
double paperHeightCm = paperHeightInch * 2.54;
物理寬度 (PHYSICALWIDTH)
│◄──────────────────────►│
├────────┬──────────────┬┤
│ 左邊距 │ 可列印區 │右邊距
│OFFSETX │ PageWidth │
└────────┴──────────────┘
void __fastcall TForm1::PrintLayout()
{
Printer()->BeginDoc();
try {
int dpiX = GetDeviceCaps(Printer()->Handle, LOGPIXELSX);
int dpiY = GetDeviceCaps(Printer()->Handle, LOGPIXELSY);
int physW = GetDeviceCaps(Printer()->Handle, PHYSICALWIDTH);
int physH = GetDeviceCaps(Printer()->Handle, PHYSICALHEIGHT);
int offsetX = GetDeviceCaps(Printer()->Handle, PHYSICALOFFSETX);
int offsetY = GetDeviceCaps(Printer()->Handle, PHYSICALOFFSETY);
// 1. 計算可列印區域(像素)
TRect printRect;
printRect.left = offsetX;
printRect.top = offsetY;
printRect.right = physW - (GetDeviceCaps(Printer()->Handle, PHYSICALWIDTH) - Printer()->PageWidth - offsetX);
printRect.bottom = physH - (GetDeviceCaps(Printer()->Handle, PHYSICALHEIGHT) - Printer()->PageHeight - offsetY);
// 2. 轉換為 mm 方便佈局
double mmPerPxX = 25.4 / dpiX;
double mmPerPxY = 25.4 / dpiY;
// 3. 繪製邊框測試
Printer()->Canvas->Rectangle(printRect);
// 4. 文字輸出(以 mm 定位)
Printer()->Canvas->TextOut(
(int)(20 / mmPerPxX), // 20mm from left
(int)(10 / mmPerPxY), // 10mm from top
"精準列印測試");
}
__finally { Printer()->EndDoc(); }
}
Printer()->BeginDoc() 後再讀取。Printer()->PrinterIndex 切換印表機時,參數會隨之變更,需重新查詢。
精通 GetDeviceCaps 各項指標,是實現「所見即所得」高品質列印的關鍵基礎。