我正在使用 MFC 并尝试使用OnPrint()
打印 DI 位图的内容。我知道如何获取我的位图,我知道如何到达::StretchDIBit
DC,但要做到这一点,我需要知道纸张尺寸,并想说是否适合正常位图尺寸,只需使用它,如果太大,制作它更小。但是我从哪里获得页面大小?如何将我的 DI 位图宽度/高度与打印机页面的输出相关联?
将 发送::StretchDIBit
到一些随机值进行测试:
pDC->SetMapMode(MM_ISOTROPIC);
pDC->SetWindowExt(500, 500);
pDC->SetViewportExt(4500, 6500);
打印出来的,但拉伸不成比例。如果我只是简单地将它发送到__super::OnPrint()
它打印但非常小。我宁愿让它只使用OnDraw()
which 输出到屏幕上,这就是__super::OnPrint()
它的作用,但是我如何设置它以打印正确的大小和比例?
蒂亚!!
编辑:
根据下面的答案,它没有用。什么都没有打印。如果我在(不打印)上显示时使用了 MM_ISOTROPIC,则CView
没有显示任何内容,所以我有条件地使用地图模式。这是完整的代码,包括CView
窗口中支持的缩放。有什么遗漏/错误?
蒂亚!!
void CMyImageView::OnDraw(CDC* pDCView)
{
if (m_DIBData != NULL) {
#define PALSIZE(x) ((x) > 8? 0: 1 << (x))
// move different versions of bitmap header to bitmap structure
BITMAP bm;
if (m_DIBData->biSize == sizeof(BITMAPCOREHEADER)) {
bm.bmWidth=((BITMAPCOREHEADER*)m_DIBData)->bcWidth;
bm.bmHeight=((BITMAPCOREHEADER*)m_DIBData)->bcHeight;
bm.bmBitsPixel=((BITMAPCOREHEADER*)m_DIBData)->bcBitCount;
bm.bmType=BI_RGB;
bm.bmBits=PBYTE(m_DIBData) + m_DIBData->biSize + PALSIZE(bm.bmBitsPixel) * 3;
}
else {
bm.bmWidth=m_DIBData->biWidth;
bm.bmHeight=m_DIBData->biHeight;
bm.bmBitsPixel=m_DIBData->biBitCount;
bm.bmType=m_DIBData->biCompression;
long color=m_DIBData->biClrUsed ? m_DIBData->biClrUsed : PALSIZE(bm.bmBitsPixel);
bm.bmBits=PBYTE(m_DIBData) + m_DIBData->biSize + color * 4;
}
CPoint point=GetScrollPosition();
CRect rcClient(0, 0, 0, 0);
if(pDCView->IsPrinting())
{
pDCView->SetMapMode(MM_ISOTROPIC);
pDCView->SetWindowExt(bm.bmWidth, bm.bmHeight);
rcClient.right=pDCView->GetDeviceCaps(HORZRES);
rcClient.bottom=pDCView->GetDeviceCaps(VERTRES);
// setup view
pDCView->SetViewportExt(rcClient.right, rcClient.bottom);
}
else {
ASSERT(MM_TEXT == pDCView->GetMapMode());
ASSERT(CPoint(0, 0) == pDCView->GetViewportOrg());
GetClientRect(rcClient);
}
const int cx=rcClient.right; // view client area width
const int cy=rcClient.bottom; // view client area height
const int bx=bm.bmWidth; // source bitmap width
const int by=bm.bmHeight; // source bitmap height
const int vx=(int)(bx * m_fZoom); // virtual document width
const int vy=(int)(by * m_fZoom); // virtual document height
const int xPos=point.x; // horizontal scroll position
const int yPos=point.y; // vertical scroll position
// source and destination coordinates and sizes
int xSrc, ySrc, nSrcWidth, nSrcHeight, xDst, yDst, nDstWidth, nDstHeight;
if (vx > cx) {
xSrc=(int)(xPos / m_fZoom);
nSrcWidth=bx - xSrc;
xDst=0;
nDstWidth=vx - xPos;
}
else {
xSrc=0;
nSrcWidth=bx;
xDst=cx / 2 - vx / 2;
nDstWidth=vx;
}
if (vy > cy) {
ySrc=0;
nSrcHeight=by;
yDst=-yPos;
nDstHeight=vy;
}
else {
ySrc=0;
nSrcHeight=by;
yDst=cy / 2 - vy / 2;
nDstHeight=vy;
}
::StretchDIBits(pDCView->m_hDC,
xDst, yDst, // xy-coordinates of upper-left corner of dest. rect.
nDstWidth, nDstHeight, // width & height of destination rectangle
xSrc, ySrc, // xy-coordinates of lower-left corner of source rect.
nSrcWidth, nSrcHeight, // width & height of source rectangle
bm.bmBits, // address of array with DIB bits
(BITMAPINFO*)m_DIBData, // address of structure with bitmap info
DIB_RGB_COLORS, // usage flags
SRCCOPY); // raster operation code
}
}
编辑:
所以我将IsPrinting
上面的部分修改为:
if(pDCView->IsPrinting())
{
pDCView->SetMapMode(MM_ISOTROPIC);
// setup base size of item
pDCView->SetWindowExt(bm.bmWidth, bm.bmHeight);
rcClient.right=bm.bmWidth;
rcClient.bottom=bm.bmHeight;
// setup view output to full page
int horzres=pDCView->GetDeviceCaps(HORZRES);
int vertres=pDCView->GetDeviceCaps(VERTRES);
pDCView->SetViewportExt(horzres, vertres);
}
有效!但是现在我不得不在另一个问题中询问位图和精度输出。