我必须使用GDI一般用打印机打印文档。我可以使设备没问题。我还传达了所需的页面大小,如:
HANDLE hPrinter;
OpenPrinterW( printerName, &hPrinter, 0 );
DocumentPropertiesW( 0, hPrinter, printerName,
pDevMode, NULL, DM_OUT_BUFFER);
if( settings.paperLength > 0 && settings.paperWidth > 0 )
{
if( pDevMode->dmFields & DM_PAPERSIZE )
{
pDevMode->dmPaperSize = 0;
}
if( pDevMode->dmFields & DM_PAPERLENGTH )
{
pDevMode->dmPaperLength = settings.paperLength;
}
if( pDevMode->dmFields & DM_PAPERWIDTH )
{
pDevMode->dmPaperWidth = settings.paperWidth;
}
}
DocumentPropertiesW( 0, hPrinter, printerName, 0, pDevMode,
DM_IN_BUFFER | DM_OUT_BUFFER );
ClosePrinter( hPrinter );
然后我StretchBlt我的文件并打印出来。
DOCINFOW di;
memset ((void *) &di, 0, sizeof (di));
di.cbSize = sizeof (DOCINFOW);
di.lpszDocName = utf_to_widechar("Document").data();
HDC hdc = this->deviceContext;
auto cxpage = GetDeviceCaps( hdc, HORZRES );
auto cypage = GetDeviceCaps( hdc, VERTRES );
auto hdcMem = CreateCompatibleDC( hdc );
BITMAPINFO bi;
bi.bmiHeader = {sizeof(bi.bmiHeader), settings.width, settings.height,
1, 24, BI_RGB, 0, 0x0ec4, 0x0ec4, 0, 0};
LPVOID ppvBits;
auto hBitmap = CreateDIBSection( 0, &bi, DIB_RGB_COLORS, &ppvBits, 0, 0 );
auto hbmOld = SelectObject( hdcMem, hBitmap );
StartDocW( hdc, &di);
for(int i = 0; i < this->colorTables.size(); ++i)
{
int size = settings.width * settings.height * 3;
StartPage( hdc );
SetDIBits( 0, hBitmap, 0, settings.height,
(PVOID)&(colorTables[i][0]), &bi, DIB_RGB_COLORS );
SetMapMode( hdc, MM_ISOTROPIC )
SetWindowExtEx( hdc, cxpage, cypage, 0 );
SetViewportExtEx( hdc, cxpage, cypage, 0 );
SetViewportOrgEx( hdc, 0, 0, 0 );
StretchBlt( hdc, 0, 0, cxpage, cypage, hdcMem, 0, 0,
settings.width, settings.height, SRCCOPY );
EndPage( hdc );
}
EndDoc( hdc );
SelectObject( hdcMem, hbmOld );
DeleteDC( hdcMem );
现在,我的文件是210mmx99mm。大多数打印机或多或少地正确处理此问题:打印尺寸合适,如果打印机支持较小的纸张尺寸,则位于左上角或中间顶部。问题是,我现在正在使用惠普打印机,它不会以这种方式工作。打印件被拉伸到整个A4 [这意味着它被调整大小以覆盖整个A4页面,这是错误的大小和错误的比例]。我知道打印机实际上可以做到这一点。我可以使用其他软件正确打印此类文档。惠普似乎并不完全支持某些GDI功能。有什么方法可以解决它吗?